GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
xdiv.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <cassert>
31 
32 #include "Array-util.h"
33 #include "CMatrix.h"
34 #include "dMatrix.h"
35 #include "CNDArray.h"
36 #include "dNDArray.h"
37 #include "fCMatrix.h"
38 #include "fMatrix.h"
39 #include "fCNDArray.h"
40 #include "fNDArray.h"
41 #include "oct-cmplx.h"
42 #include "dDiagMatrix.h"
43 #include "fDiagMatrix.h"
44 #include "CDiagMatrix.h"
45 #include "fCDiagMatrix.h"
46 #include "lo-array-errwarn.h"
47 #include "quit.h"
48 
49 #include "error.h"
50 #include "xdiv.h"
51 
53 
54 static void
55 solve_singularity_warning (double rcond)
56 {
58 }
59 
60 template <typename T1, typename T2>
61 bool
62 mx_leftdiv_conform (const T1& a, const T2& b, blas_trans_type blas_trans)
63 {
64  octave_idx_type a_nr = (blas_trans == blas_no_trans ? a.rows () : a.cols ());
65  octave_idx_type b_nr = b.rows ();
66 
67  if (a_nr != b_nr)
68  {
69  octave_idx_type a_nc = (blas_trans == blas_no_trans ? a.cols ()
70  : a.rows ());
71  octave_idx_type b_nc = b.cols ();
72 
73  octave::err_nonconformant (R"(operator \)", a_nr, a_nc, b_nr, b_nc);
74  }
75 
76  return true;
77 }
78 
79 #define INSTANTIATE_MX_LEFTDIV_CONFORM(T1, T2) \
80  template bool mx_leftdiv_conform (const T1&, const T2&, blas_trans_type)
81 
86 
87 template <typename T1, typename T2>
88 bool
89 mx_div_conform (const T1& a, const T2& b)
90 {
91  octave_idx_type a_nc = a.cols ();
92  octave_idx_type b_nc = b.cols ();
93 
94  if (a_nc != b_nc)
95  {
96  octave_idx_type a_nr = a.rows ();
97  octave_idx_type b_nr = b.rows ();
98 
99  octave::err_nonconformant ("operator /", a_nr, a_nc, b_nr, b_nc);
100  }
101 
102  return true;
103 }
104 
105 #define INSTANTIATE_MX_DIV_CONFORM(T1, T2) \
106  template bool mx_div_conform (const T1&, const T2&)
107 
112 
113 // Right division functions.
114 //
115 // op2 / op1: m cm
116 // +-- +---+----+
117 // matrix | 1 | 3 |
118 // +---+----+
119 // complex_matrix | 2 | 4 |
120 // +---+----+
121 
122 // -*- 1 -*-
123 Matrix
124 xdiv (const Matrix& a, const Matrix& b, MatrixType& typ)
125 {
126  if (! mx_div_conform (a, b))
127  return Matrix ();
128 
129  octave_idx_type info;
130  double rcond = 0.0;
131 
132  Matrix result
133  = b.solve (typ, a.transpose (), info, rcond,
134  solve_singularity_warning, true, blas_trans);
135 
136  return result.transpose ();
137 }
138 
139 // -*- 2 -*-
141 xdiv (const Matrix& a, const ComplexMatrix& b, MatrixType& typ)
142 {
143  if (! mx_div_conform (a, b))
144  return ComplexMatrix ();
145 
146  octave_idx_type info;
147  double rcond = 0.0;
148 
149  ComplexMatrix result
150  = b.solve (typ, a.transpose (), info, rcond,
151  solve_singularity_warning, true, blas_trans);
152 
153  return result.transpose ();
154 }
155 
156 // -*- 3 -*-
158 xdiv (const ComplexMatrix& a, const Matrix& b, MatrixType& typ)
159 {
160  if (! mx_div_conform (a, b))
161  return ComplexMatrix ();
162 
163  octave_idx_type info;
164  double rcond = 0.0;
165 
166  ComplexMatrix result
167  = b.solve (typ, a.transpose (), info, rcond,
168  solve_singularity_warning, true, blas_trans);
169 
170  return result.transpose ();
171 }
172 
173 // -*- 4 -*-
175 xdiv (const ComplexMatrix& a, const ComplexMatrix& b, MatrixType& typ)
176 {
177  if (! mx_div_conform (a, b))
178  return ComplexMatrix ();
179 
180  octave_idx_type info;
181  double rcond = 0.0;
182 
183  ComplexMatrix result
184  = b.solve (typ, a.transpose (), info, rcond,
185  solve_singularity_warning, true, blas_trans);
186 
187  return result.transpose ();
188 }
189 
190 // Funny element by element division operations.
191 //
192 // op2 \ op1: s cs
193 // +-- +---+----+
194 // matrix | 1 | 3 |
195 // +---+----+
196 // complex_matrix | 2 | 4 |
197 // +---+----+
198 
199 Matrix
200 elem_xdiv (double a, const Matrix& b)
201 {
202  octave_idx_type nr = b.rows ();
203  octave_idx_type nc = b.columns ();
204 
205  Matrix result (nr, nc);
206 
207  for (octave_idx_type j = 0; j < nc; j++)
208  for (octave_idx_type i = 0; i < nr; i++)
209  {
210  octave_quit ();
211  result (i, j) = a / b (i, j);
212  }
213 
214  return result;
215 }
216 
218 elem_xdiv (double a, const ComplexMatrix& b)
219 {
220  octave_idx_type nr = b.rows ();
221  octave_idx_type nc = b.columns ();
222 
223  ComplexMatrix result (nr, nc);
224 
225  for (octave_idx_type j = 0; j < nc; j++)
226  for (octave_idx_type i = 0; i < nr; i++)
227  {
228  octave_quit ();
229  result (i, j) = a / b (i, j);
230  }
231 
232  return result;
233 }
234 
236 elem_xdiv (const Complex a, const Matrix& b)
237 {
238  octave_idx_type nr = b.rows ();
239  octave_idx_type nc = b.columns ();
240 
241  ComplexMatrix result (nr, nc);
242 
243  for (octave_idx_type j = 0; j < nc; j++)
244  for (octave_idx_type i = 0; i < nr; i++)
245  {
246  octave_quit ();
247  result (i, j) = a / b (i, j);
248  }
249 
250  return result;
251 }
252 
254 elem_xdiv (const Complex a, const ComplexMatrix& b)
255 {
256  octave_idx_type nr = b.rows ();
257  octave_idx_type nc = b.columns ();
258 
259  ComplexMatrix result (nr, nc);
260 
261  for (octave_idx_type j = 0; j < nc; j++)
262  for (octave_idx_type i = 0; i < nr; i++)
263  {
264  octave_quit ();
265  result (i, j) = a / b (i, j);
266  }
267 
268  return result;
269 }
270 
271 // Funny element by element division operations.
272 //
273 // op2 \ op1: s cs
274 // +-- +---+----+
275 // N-D array | 1 | 3 |
276 // +---+----+
277 // complex N-D array | 2 | 4 |
278 // +---+----+
279 
280 NDArray
281 elem_xdiv (double a, const NDArray& b)
282 {
283  NDArray result (b.dims ());
284 
285  for (octave_idx_type i = 0; i < b.numel (); i++)
286  {
287  octave_quit ();
288  result (i) = a / b (i);
289  }
290 
291  return result;
292 }
293 
295 elem_xdiv (double a, const ComplexNDArray& b)
296 {
297  ComplexNDArray result (b.dims ());
298 
299  for (octave_idx_type i = 0; i < b.numel (); i++)
300  {
301  octave_quit ();
302  result (i) = a / b (i);
303  }
304 
305  return result;
306 }
307 
309 elem_xdiv (const Complex a, const NDArray& b)
310 {
311  ComplexNDArray result (b.dims ());
312 
313  for (octave_idx_type i = 0; i < b.numel (); i++)
314  {
315  octave_quit ();
316  result (i) = a / b (i);
317  }
318 
319  return result;
320 }
321 
323 elem_xdiv (const Complex a, const ComplexNDArray& b)
324 {
325  ComplexNDArray result (b.dims ());
326 
327  for (octave_idx_type i = 0; i < b.numel (); i++)
328  {
329  octave_quit ();
330  result (i) = a / b (i);
331  }
332 
333  return result;
334 }
335 
336 // Left division functions.
337 //
338 // op2 \ op1: m cm
339 // +-- +---+----+
340 // matrix | 1 | 3 |
341 // +---+----+
342 // complex_matrix | 2 | 4 |
343 // +---+----+
344 
345 // -*- 1 -*-
346 Matrix
347 xleftdiv (const Matrix& a, const Matrix& b, MatrixType& typ,
348  blas_trans_type transt)
349 {
350  if (! mx_leftdiv_conform (a, b, transt))
351  return Matrix ();
352 
353  octave_idx_type info;
354  double rcond = 0.0;
355  return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
356 }
357 
358 // -*- 2 -*-
360 xleftdiv (const Matrix& a, const ComplexMatrix& b, MatrixType& typ,
361  blas_trans_type transt)
362 {
363  if (! mx_leftdiv_conform (a, b, transt))
364  return ComplexMatrix ();
365 
366  octave_idx_type info;
367  double rcond = 0.0;
368 
369  return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
370 }
371 
372 // -*- 3 -*-
374 xleftdiv (const ComplexMatrix& a, const Matrix& b, MatrixType& typ,
375  blas_trans_type transt)
376 {
377  if (! mx_leftdiv_conform (a, b, transt))
378  return ComplexMatrix ();
379 
380  octave_idx_type info;
381  double rcond = 0.0;
382  return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
383 }
384 
385 // -*- 4 -*-
387 xleftdiv (const ComplexMatrix& a, const ComplexMatrix& b, MatrixType& typ,
388  blas_trans_type transt)
389 {
390  if (! mx_leftdiv_conform (a, b, transt))
391  return ComplexMatrix ();
392 
393  octave_idx_type info;
394  double rcond = 0.0;
395  return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
396 }
397 
398 static void
399 solve_singularity_warning (float rcond)
400 {
402 }
403 
408 
413 
414 // Right division functions.
415 //
416 // op2 / op1: m cm
417 // +-- +---+----+
418 // matrix | 1 | 3 |
419 // +---+----+
420 // complex_matrix | 2 | 4 |
421 // +---+----+
422 
423 // -*- 1 -*-
425 xdiv (const FloatMatrix& a, const FloatMatrix& b, MatrixType& typ)
426 {
427  if (! mx_div_conform (a, b))
428  return FloatMatrix ();
429 
430  octave_idx_type info;
431  float rcond = 0.0;
432 
433  FloatMatrix result
434  = b.solve (typ, a.transpose (), info, rcond,
435  solve_singularity_warning, true, blas_trans);
436 
437  return result.transpose ();
438 }
439 
440 // -*- 2 -*-
442 xdiv (const FloatMatrix& a, const FloatComplexMatrix& b, MatrixType& typ)
443 {
444  if (! mx_div_conform (a, b))
445  return FloatComplexMatrix ();
446 
447  octave_idx_type info;
448  float rcond = 0.0;
449 
450  FloatComplexMatrix result
451  = b.solve (typ, a.transpose (), info, rcond,
452  solve_singularity_warning, true, blas_trans);
453 
454  return result.transpose ();
455 }
456 
457 // -*- 3 -*-
459 xdiv (const FloatComplexMatrix& a, const FloatMatrix& b, MatrixType& typ)
460 {
461  if (! mx_div_conform (a, b))
462  return FloatComplexMatrix ();
463 
464  octave_idx_type info;
465  float rcond = 0.0;
466 
467  FloatComplexMatrix result
468  = b.solve (typ, a.transpose (), info, rcond,
469  solve_singularity_warning, true, blas_trans);
470 
471  return result.transpose ();
472 }
473 
474 // -*- 4 -*-
477 {
478  if (! mx_div_conform (a, b))
479  return FloatComplexMatrix ();
480 
481  octave_idx_type info;
482  float rcond = 0.0;
483 
484  FloatComplexMatrix result
485  = b.solve (typ, a.transpose (), info, rcond,
486  solve_singularity_warning, true, blas_trans);
487 
488  return result.transpose ();
489 }
490 
491 // Funny element by element division operations.
492 //
493 // op2 \ op1: s cs
494 // +-- +---+----+
495 // matrix | 1 | 3 |
496 // +---+----+
497 // complex_matrix | 2 | 4 |
498 // +---+----+
499 
501 elem_xdiv (float a, const FloatMatrix& b)
502 {
503  octave_idx_type nr = b.rows ();
504  octave_idx_type nc = b.columns ();
505 
506  FloatMatrix result (nr, nc);
507 
508  for (octave_idx_type j = 0; j < nc; j++)
509  for (octave_idx_type i = 0; i < nr; i++)
510  {
511  octave_quit ();
512  result (i, j) = a / b (i, j);
513  }
514 
515  return result;
516 }
517 
519 elem_xdiv (float a, const FloatComplexMatrix& b)
520 {
521  octave_idx_type nr = b.rows ();
522  octave_idx_type nc = b.columns ();
523 
524  FloatComplexMatrix result (nr, nc);
525 
526  for (octave_idx_type j = 0; j < nc; j++)
527  for (octave_idx_type i = 0; i < nr; i++)
528  {
529  octave_quit ();
530  result (i, j) = a / b (i, j);
531  }
532 
533  return result;
534 }
535 
537 elem_xdiv (const FloatComplex a, const FloatMatrix& b)
538 {
539  octave_idx_type nr = b.rows ();
540  octave_idx_type nc = b.columns ();
541 
542  FloatComplexMatrix result (nr, nc);
543 
544  for (octave_idx_type j = 0; j < nc; j++)
545  for (octave_idx_type i = 0; i < nr; i++)
546  {
547  octave_quit ();
548  result (i, j) = a / b (i, j);
549  }
550 
551  return result;
552 }
553 
556 {
557  octave_idx_type nr = b.rows ();
558  octave_idx_type nc = b.columns ();
559 
560  FloatComplexMatrix result (nr, nc);
561 
562  for (octave_idx_type j = 0; j < nc; j++)
563  for (octave_idx_type i = 0; i < nr; i++)
564  {
565  octave_quit ();
566  result (i, j) = a / b (i, j);
567  }
568 
569  return result;
570 }
571 
572 // Funny element by element division operations.
573 //
574 // op2 \ op1: s cs
575 // +-- +---+----+
576 // N-D array | 1 | 3 |
577 // +---+----+
578 // complex N-D array | 2 | 4 |
579 // +---+----+
580 
582 elem_xdiv (float a, const FloatNDArray& b)
583 {
584  FloatNDArray result (b.dims ());
585 
586  for (octave_idx_type i = 0; i < b.numel (); i++)
587  {
588  octave_quit ();
589  result (i) = a / b (i);
590  }
591 
592  return result;
593 }
594 
596 elem_xdiv (float a, const FloatComplexNDArray& b)
597 {
598  FloatComplexNDArray result (b.dims ());
599 
600  for (octave_idx_type i = 0; i < b.numel (); i++)
601  {
602  octave_quit ();
603  result (i) = a / b (i);
604  }
605 
606  return result;
607 }
608 
611 {
612  FloatComplexNDArray result (b.dims ());
613 
614  for (octave_idx_type i = 0; i < b.numel (); i++)
615  {
616  octave_quit ();
617  result (i) = a / b (i);
618  }
619 
620  return result;
621 }
622 
625 {
626  FloatComplexNDArray result (b.dims ());
627 
628  for (octave_idx_type i = 0; i < b.numel (); i++)
629  {
630  octave_quit ();
631  result (i) = a / b (i);
632  }
633 
634  return result;
635 }
636 
637 // Left division functions.
638 //
639 // op2 \ op1: m cm
640 // +-- +---+----+
641 // matrix | 1 | 3 |
642 // +---+----+
643 // complex_matrix | 2 | 4 |
644 // +---+----+
645 
646 // -*- 1 -*-
648 xleftdiv (const FloatMatrix& a, const FloatMatrix& b, MatrixType& typ,
649  blas_trans_type transt)
650 {
651  if (! mx_leftdiv_conform (a, b, transt))
652  return FloatMatrix ();
653 
654  octave_idx_type info;
655  float rcond = 0.0;
656  return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
657 }
658 
659 // -*- 2 -*-
662  blas_trans_type transt)
663 {
664  if (! mx_leftdiv_conform (a, b, transt))
665  return FloatComplexMatrix ();
666 
667  octave_idx_type info;
668  float rcond = 0.0;
669 
670  return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
671 }
672 
673 // -*- 3 -*-
676  blas_trans_type transt)
677 {
678  if (! mx_leftdiv_conform (a, b, transt))
679  return FloatComplexMatrix ();
680 
681  octave_idx_type info;
682  float rcond = 0.0;
683  return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
684 }
685 
686 // -*- 4 -*-
689  MatrixType& typ, blas_trans_type transt)
690 {
691  if (! mx_leftdiv_conform (a, b, transt))
692  return FloatComplexMatrix ();
693 
694  octave_idx_type info;
695  float rcond = 0.0;
696  return a.solve (typ, b, info, rcond, solve_singularity_warning, true, transt);
697 }
698 
699 // Diagonal matrix division.
700 
701 template <typename MT, typename DMT>
702 MT
703 mdm_div_impl (const MT& a, const DMT& d)
704 {
705  if (! mx_div_conform (a, d))
706  return MT ();
707 
708  octave_idx_type m = a.rows ();
709  octave_idx_type n = d.rows ();
710  octave_idx_type l = d.length ();
711  MT x (m, n);
712  typedef typename DMT::element_type S;
713  typedef typename MT::element_type T;
714  const T *aa = a.data ();
715  const S *dd = d.data ();
716  T *xx = x.fortran_vec ();
717 
718  for (octave_idx_type j = 0; j < l; j++)
719  {
720  const S del = dd[j];
721  if (del != S ())
722  for (octave_idx_type i = 0; i < m; i++)
723  xx[i] = aa[i] / del;
724  else
725  for (octave_idx_type i = 0; i < m; i++)
726  xx[i] = T ();
727  aa += m; xx += m;
728  }
729 
730  for (octave_idx_type i = l*m; i < n*m; i++)
731  xx[i] = T ();
732 
733  return x;
734 }
735 
736 // Right division functions.
737 //
738 // op2 / op1: dm cdm
739 // +-- +---+----+
740 // matrix | 1 | |
741 // +---+----+
742 // complex_matrix | 2 | 3 |
743 // +---+----+
744 
745 // -*- 1 -*-
746 Matrix
747 xdiv (const Matrix& a, const DiagMatrix& b)
748 { return mdm_div_impl (a, b); }
749 
750 // -*- 2 -*-
752 xdiv (const ComplexMatrix& a, const DiagMatrix& b)
753 { return mdm_div_impl (a, b); }
754 
755 // -*- 3 -*-
758 { return mdm_div_impl (a, b); }
759 
760 // Right division functions, float type.
761 //
762 // op2 / op1: dm cdm
763 // +-- +---+----+
764 // matrix | 1 | |
765 // +---+----+
766 // complex_matrix | 2 | 3 |
767 // +---+----+
768 
769 // -*- 1 -*-
771 xdiv (const FloatMatrix& a, const FloatDiagMatrix& b)
772 { return mdm_div_impl (a, b); }
773 
774 // -*- 2 -*-
777 { return mdm_div_impl (a, b); }
778 
779 // -*- 3 -*-
782 { return mdm_div_impl (a, b); }
783 
784 template <typename MT, typename DMT>
785 MT
786 dmm_leftdiv_impl (const DMT& d, const MT& a)
787 {
788  if (! mx_leftdiv_conform (d, a, blas_no_trans))
789  return MT ();
790 
791  octave_idx_type m = d.cols ();
792  octave_idx_type n = a.cols ();
793  octave_idx_type k = a.rows ();
794  octave_idx_type l = d.length ();
795  MT x (m, n);
796  typedef typename DMT::element_type S;
797  typedef typename MT::element_type T;
798  const T *aa = a.data ();
799  const S *dd = d.data ();
800  T *xx = x.fortran_vec ();
801 
802  for (octave_idx_type j = 0; j < n; j++)
803  {
804  for (octave_idx_type i = 0; i < l; i++)
805  xx[i] = (dd[i] != S () ? aa[i] / dd[i] : T ());
806  for (octave_idx_type i = l; i < m; i++)
807  xx[i] = T ();
808  aa += k; xx += m;
809  }
810 
811  return x;
812 }
813 
814 // Left division functions.
815 //
816 // op2 \ op1: m cm
817 // +---+----+
818 // diag_matrix | 1 | 2 |
819 // +---+----+
820 // complex_diag_matrix | | 3 |
821 // +---+----+
822 
823 // -*- 1 -*-
824 Matrix
825 xleftdiv (const DiagMatrix& a, const Matrix& b)
826 { return dmm_leftdiv_impl (a, b); }
827 
828 // -*- 2 -*-
830 xleftdiv (const DiagMatrix& a, const ComplexMatrix& b)
831 { return dmm_leftdiv_impl (a, b); }
832 
833 // -*- 3 -*-
836 { return dmm_leftdiv_impl (a, b); }
837 
838 // Left division functions, float type.
839 //
840 // op2 \ op1: m cm
841 // +---+----+
842 // diag_matrix | 1 | 2 |
843 // +---+----+
844 // complex_diag_matrix | | 3 |
845 // +---+----+
846 
847 // -*- 1 -*-
850 { return dmm_leftdiv_impl (a, b); }
851 
852 // -*- 2 -*-
855 { return dmm_leftdiv_impl (a, b); }
856 
857 // -*- 3 -*-
860 { return dmm_leftdiv_impl (a, b); }
861 
862 // Diagonal by diagonal matrix division.
863 
864 template <typename MT, typename DMT>
865 MT
866 dmdm_div_impl (const MT& a, const DMT& d)
867 {
868  if (! mx_div_conform (a, d))
869  return MT ();
870 
871  octave_idx_type m = a.rows ();
872  octave_idx_type n = d.rows ();
873  octave_idx_type k = d.cols ();
874  octave_idx_type l = std::min (m, n);
875  octave_idx_type lk = std::min (l, k);
876  MT x (m, n);
877  typedef typename DMT::element_type S;
878  typedef typename MT::element_type T;
879  const T *aa = a.data ();
880  const S *dd = d.data ();
881  T *xx = x.fortran_vec ();
882 
883  for (octave_idx_type i = 0; i < lk; i++)
884  xx[i] = (dd[i] != S () ? aa[i] / dd[i] : T ());
885  for (octave_idx_type i = lk; i < l; i++)
886  xx[i] = T ();
887 
888  return x;
889 }
890 
891 // Right division functions.
892 //
893 // op2 / op1: dm cdm
894 // +-- +---+----+
895 // diag_matrix | 1 | |
896 // +---+----+
897 // complex_diag_matrix | 2 | 3 |
898 // +---+----+
899 
900 // -*- 1 -*-
902 xdiv (const DiagMatrix& a, const DiagMatrix& b)
903 { return dmdm_div_impl (a, b); }
904 
905 // -*- 2 -*-
907 xdiv (const ComplexDiagMatrix& a, const DiagMatrix& b)
908 { return dmdm_div_impl (a, b); }
909 
910 // -*- 3 -*-
913 { return dmdm_div_impl (a, b); }
914 
915 // Right division functions, float type.
916 //
917 // op2 / op1: dm cdm
918 // +-- +---+----+
919 // diag_matrix | 1 | |
920 // +---+----+
921 // complex_diag_matrix | 2 | 3 |
922 // +---+----+
923 
924 // -*- 1 -*-
927 { return dmdm_div_impl (a, b); }
928 
929 // -*- 2 -*-
932 { return dmdm_div_impl (a, b); }
933 
934 // -*- 3 -*-
937 { return dmdm_div_impl (a, b); }
938 
939 template <typename MT, typename DMT>
940 MT
941 dmdm_leftdiv_impl (const DMT& d, const MT& a)
942 {
943  if (! mx_leftdiv_conform (d, a, blas_no_trans))
944  return MT ();
945 
946  octave_idx_type m = d.cols ();
947  octave_idx_type n = a.cols ();
948  octave_idx_type k = d.rows ();
949  octave_idx_type l = std::min (m, n);
950  octave_idx_type lk = std::min (l, k);
951  MT x (m, n);
952  typedef typename DMT::element_type S;
953  typedef typename MT::element_type T;
954  const T *aa = a.data ();
955  const S *dd = d.data ();
956  T *xx = x.fortran_vec ();
957 
958  for (octave_idx_type i = 0; i < lk; i++)
959  xx[i] = (dd[i] != S () ? aa[i] / dd[i] : T ());
960  for (octave_idx_type i = lk; i < l; i++)
961  xx[i] = T ();
962 
963  return x;
964 }
965 
966 // Left division functions.
967 //
968 // op2 \ op1: dm cdm
969 // +---+----+
970 // diag_matrix | 1 | 2 |
971 // +---+----+
972 // complex_diag_matrix | | 3 |
973 // +---+----+
974 
975 // -*- 1 -*-
977 xleftdiv (const DiagMatrix& a, const DiagMatrix& b)
978 { return dmdm_leftdiv_impl (a, b); }
979 
980 // -*- 2 -*-
983 { return dmdm_leftdiv_impl (a, b); }
984 
985 // -*- 3 -*-
988 { return dmdm_leftdiv_impl (a, b); }
989 
990 // Left division functions, float type.
991 //
992 // op2 \ op1: dm cdm
993 // +---+----+
994 // diag_matrix | 1 | 2 |
995 // +---+----+
996 // complex_diag_matrix | | 3 |
997 // +---+----+
998 
999 // -*- 1 -*-
1002 { return dmdm_leftdiv_impl (a, b); }
1003 
1004 // -*- 2 -*-
1007 { return dmdm_leftdiv_impl (a, b); }
1008 
1009 // -*- 3 -*-
1012 { return dmdm_leftdiv_impl (a, b); }
1013 
1014 OCTAVE_END_NAMESPACE(octave)
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
octave_idx_type rows() const
Definition: Array.h:459
octave_idx_type columns() const
Definition: Array.h:471
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:503
octave_idx_type numel() const
Number of elements in the array.
Definition: Array.h:414
ComplexMatrix solve(MatrixType &mattype, const Matrix &b) const
Definition: CMatrix.cc:1931
ComplexMatrix transpose() const
Definition: CMatrix.h:172
FloatComplexMatrix transpose() const
Definition: fCMatrix.h:180
FloatComplexMatrix solve(MatrixType &mattype, const FloatMatrix &b) const
Definition: fCMatrix.cc:1942
FloatMatrix solve(MatrixType &mattype, const FloatMatrix &b) const
Definition: fMatrix.cc:1608
FloatMatrix transpose() const
Definition: fMatrix.h:140
Definition: dMatrix.h:42
Matrix transpose() const
Definition: dMatrix.h:140
Matrix solve(MatrixType &mattype, const Matrix &b) const
Definition: dMatrix.cc:1591
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
void warn_singular_matrix(double rcond)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
blas_trans_type
Definition: mx-defs.h:80
@ blas_no_trans
Definition: mx-defs.h:81
@ blas_trans
Definition: mx-defs.h:82
T octave_idx_type m
Definition: mx-inlines.cc:781
octave_idx_type n
Definition: mx-inlines.cc:761
std::complex< double > Complex
Definition: oct-cmplx.h:33
std::complex< float > FloatComplex
Definition: oct-cmplx.h:34
Matrix elem_xdiv(double a, const Matrix &b)
Definition: xdiv.cc:200
Matrix xleftdiv(const Matrix &a, const Matrix &b, MatrixType &typ, blas_trans_type transt)
Definition: xdiv.cc:347
MT dmm_leftdiv_impl(const DMT &d, const MT &a)
Definition: xdiv.cc:786
bool mx_leftdiv_conform(const T1 &a, const T2 &b, blas_trans_type blas_trans)
Definition: xdiv.cc:62
bool mx_div_conform(const T1 &a, const T2 &b)
Definition: xdiv.cc:89
#define INSTANTIATE_MX_LEFTDIV_CONFORM(T1, T2)
Definition: xdiv.cc:79
#define INSTANTIATE_MX_DIV_CONFORM(T1, T2)
Definition: xdiv.cc:105
MT dmdm_leftdiv_impl(const DMT &d, const MT &a)
Definition: xdiv.cc:941
MT mdm_div_impl(const MT &a, const DMT &d)
Definition: xdiv.cc:703
Matrix xdiv(const Matrix &a, const Matrix &b, MatrixType &typ)
Definition: xdiv.cc:124
MT dmdm_div_impl(const MT &a, const DMT &d)
Definition: xdiv.cc:866