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