GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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