GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
xpow.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2018 John W. Eaton
4 Copyright (C) 2009-2010 VZLU Prague
5 
6 This file is part of Octave.
7 
8 Octave is free software: you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <https://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if defined (HAVE_CONFIG_H)
25 # include "config.h"
26 #endif
27 
28 #include <cassert>
29 
30 #include <limits>
31 
32 #include "Array-util.h"
33 #include "CColVector.h"
34 #include "CDiagMatrix.h"
35 #include "fCDiagMatrix.h"
36 #include "fCMatrix.h"
37 #include "CMatrix.h"
38 #include "EIG.h"
39 #include "fEIG.h"
40 #include "dDiagMatrix.h"
41 #include "fDiagMatrix.h"
42 #include "dMatrix.h"
43 #include "PermMatrix.h"
44 #include "mx-cm-cdm.h"
45 #include "mx-fcm-fcdm.h"
46 #include "oct-cmplx.h"
47 #include "Range.h"
48 #include "quit.h"
49 
50 #include "error.h"
51 #include "ovl.h"
52 #include "utils.h"
53 #include "xpow.h"
54 
55 #include "bsxfun.h"
56 
57 
58 static void
60 {
61  error ("Failed to diagonalize matrix while calculating matrix exponential");
62 }
63 
64 static void
66 {
67  error ("for x^y, only square matrix arguments are permitted and one " \
68  "argument must be scalar. Use .^ for elementwise power.");
69 }
70 
71 template <typename T>
72 static inline bool
73 xisint (T x)
74 {
75  return (octave::math::x_nint (x) == x
76  && ((x >= 0 && x < std::numeric_limits<int>::max ())
77  || (x <= 0 && x > std::numeric_limits<int>::min ())));
78 }
79 
80 // Safer pow functions.
81 //
82 // op2 \ op1: s m cs cm
83 // +-- +---+---+----+----+
84 // scalar | | 1 | 5 | 7 | 11 |
85 // +---+---+----+----+
86 // matrix | 2 | * | 8 | * |
87 // +---+---+----+----+
88 // complex_scalar | 3 | 6 | 9 | 12 |
89 // +---+---+----+----+
90 // complex_matrix | 4 | * | 10 | * |
91 // +---+---+----+----+
92 
93 // -*- 1 -*-
95 xpow (double a, double b)
96 {
97  double retval;
98 
99  if (a < 0.0 && ! xisint (b))
100  {
101  Complex atmp (a);
102 
103  return std::pow (atmp, b);
104  }
105  else
106  retval = std::pow (a, b);
107 
108  return retval;
109 }
110 
111 // -*- 2 -*-
113 xpow (double a, const Matrix& b)
114 {
116 
117  octave_idx_type nr = b.rows ();
118  octave_idx_type nc = b.cols ();
119 
120  if (nr == 0 || nc == 0 || nr != nc)
122 
123  try
124  {
125  EIG b_eig (b);
126 
127  ComplexColumnVector lambda (b_eig.eigenvalues ());
129 
130  for (octave_idx_type i = 0; i < nr; i++)
131  {
132  Complex elt = lambda(i);
133  if (std::imag (elt) == 0.0)
134  lambda(i) = std::pow (a, std::real (elt));
135  else
136  lambda(i) = std::pow (a, elt);
137  }
138  ComplexDiagMatrix D (lambda);
139 
140  ComplexMatrix C = Q * D * Q.inverse ();
141  if (a > 0)
142  retval = real (C);
143  else
144  retval = C;
145  }
146  catch (const octave::execution_exception&)
147  {
149  }
150 
151  return retval;
152 }
153 
154 // -*- 3 -*-
156 xpow (double a, const Complex& b)
157 {
158  Complex result = std::pow (a, b);
159  return result;
160 }
161 
162 // -*- 4 -*-
164 xpow (double a, const ComplexMatrix& b)
165 {
167 
168  octave_idx_type nr = b.rows ();
169  octave_idx_type nc = b.cols ();
170 
171  if (nr == 0 || nc == 0 || nr != nc)
173 
174  EIG b_eig (b);
175 
176  try
177  {
178  ComplexColumnVector lambda (b_eig.eigenvalues ());
180 
181  for (octave_idx_type i = 0; i < nr; i++)
182  {
183  Complex elt = lambda(i);
184  if (std::imag (elt) == 0.0)
185  lambda(i) = std::pow (a, std::real (elt));
186  else
187  lambda(i) = std::pow (a, elt);
188  }
189  ComplexDiagMatrix D (lambda);
190 
191  retval = ComplexMatrix (Q * D * Q.inverse ());
192  }
193  catch (const octave::execution_exception&)
194  {
196  }
197 
198  return retval;
199 }
200 
201 // -*- 5 -*-
203 xpow (const Matrix& a, double b)
204 {
206 
207  octave_idx_type nr = a.rows ();
208  octave_idx_type nc = a.cols ();
209 
210  if (nr == 0 || nc == 0 || nr != nc)
212 
213  if (xisint (b))
214  {
215  int bint = static_cast<int> (b);
216  if (bint == 0)
217  {
218  retval = DiagMatrix (nr, nr, 1.0);
219  }
220  else
221  {
222  // Too much copying?
223  // FIXME: we shouldn't do this if the exponent is large...
224 
225  Matrix atmp;
226  if (bint < 0)
227  {
228  bint = -bint;
229 
230  octave_idx_type info;
231  double rcond = 0.0;
232  MatrixType mattype (a);
233 
234  atmp = a.inverse (mattype, info, rcond, 1);
235 
236  if (info == -1)
237  warning ("inverse: matrix singular to machine precision, rcond = %g", rcond);
238  }
239  else
240  atmp = a;
241 
242  Matrix result (atmp);
243 
244  bint--;
245 
246  while (bint > 0)
247  {
248  if (bint & 1)
249  // Use atmp * result instead of result * atmp
250  // for ML compatibility (bug #52706).
251  result = atmp * result;
252 
253  bint >>= 1;
254 
255  if (bint > 0)
256  atmp = atmp * atmp;
257  }
258 
259  retval = result;
260  }
261  }
262  else
263  {
264  EIG a_eig (a);
265 
266  try
267  {
268  ComplexColumnVector lambda (a_eig.eigenvalues ());
270 
271  for (octave_idx_type i = 0; i < nr; i++)
272  lambda(i) = std::pow (lambda(i), b);
273 
274  ComplexDiagMatrix D (lambda);
275 
276  retval = ComplexMatrix (Q * D * Q.inverse ());
277  }
278  catch (const octave::execution_exception&)
279  {
281  }
282  }
283 
284  return retval;
285 }
286 
287 // -*- 5d -*-
289 xpow (const DiagMatrix& a, double b)
290 {
292 
293  octave_idx_type nr = a.rows ();
294  octave_idx_type nc = a.cols ();
295 
296  if (nr == 0 || nc == 0 || nr != nc)
298 
299  if (xisint (b))
300  {
301  DiagMatrix r (nr, nc);
302  for (octave_idx_type i = 0; i < nc; i++)
303  r.dgelem (i) = std::pow (a.dgelem (i), b);
304  retval = r;
305  }
306  else
307  {
308  ComplexDiagMatrix r (nr, nc);
309  for (octave_idx_type i = 0; i < nc; i++)
310  r.dgelem (i) = std::pow (static_cast<Complex> (a.dgelem (i)), b);
311  retval = r;
312  }
313 
314  return retval;
315 }
316 
317 // -*- 5p -*-
319 xpow (const PermMatrix& a, double b)
320 {
321  if (xisint (b))
322  return a.power (static_cast<int> (b));
323  else
324  return xpow (Matrix (a), b);
325 }
326 
327 // -*- 6 -*-
329 xpow (const Matrix& a, const Complex& b)
330 {
332 
333  octave_idx_type nr = a.rows ();
334  octave_idx_type nc = a.cols ();
335 
336  if (nr == 0 || nc == 0 || nr != nc)
338 
339  EIG a_eig (a);
340 
341  try
342  {
343  ComplexColumnVector lambda (a_eig.eigenvalues ());
345 
346  for (octave_idx_type i = 0; i < nr; i++)
347  lambda(i) = std::pow (lambda(i), b);
348 
349  ComplexDiagMatrix D (lambda);
350 
351  retval = ComplexMatrix (Q * D * Q.inverse ());
352  }
353  catch (const octave::execution_exception&)
354  {
356  }
357 
358  return retval;
359 }
360 
361 // -*- 7 -*-
363 xpow (const Complex& a, double b)
364 {
365  Complex result;
366 
367  if (xisint (b))
368  result = std::pow (a, static_cast<int> (b));
369  else
370  result = std::pow (a, b);
371 
372  return result;
373 }
374 
375 // -*- 8 -*-
377 xpow (const Complex& a, const Matrix& b)
378 {
380 
381  octave_idx_type nr = b.rows ();
382  octave_idx_type nc = b.cols ();
383 
384  if (nr == 0 || nc == 0 || nr != nc)
386 
387  EIG b_eig (b);
388 
389  try
390  {
391  ComplexColumnVector lambda (b_eig.eigenvalues ());
393 
394  for (octave_idx_type i = 0; i < nr; i++)
395  {
396  Complex elt = lambda(i);
397  if (std::imag (elt) == 0.0)
398  lambda(i) = std::pow (a, std::real (elt));
399  else
400  lambda(i) = std::pow (a, elt);
401  }
402  ComplexDiagMatrix D (lambda);
403 
404  retval = ComplexMatrix (Q * D * Q.inverse ());
405  }
406  catch (const octave::execution_exception&)
407  {
409  }
410 
411  return retval;
412 }
413 
414 // -*- 9 -*-
416 xpow (const Complex& a, const Complex& b)
417 {
418  Complex result;
419  result = std::pow (a, b);
420  return result;
421 }
422 
423 // -*- 10 -*-
425 xpow (const Complex& a, const ComplexMatrix& b)
426 {
428 
429  octave_idx_type nr = b.rows ();
430  octave_idx_type nc = b.cols ();
431 
432  if (nr == 0 || nc == 0 || nr != nc)
434 
435  EIG b_eig (b);
436 
437  try
438  {
439  ComplexColumnVector lambda (b_eig.eigenvalues ());
441 
442  for (octave_idx_type i = 0; i < nr; i++)
443  {
444  Complex elt = lambda(i);
445  if (std::imag (elt) == 0.0)
446  lambda(i) = std::pow (a, std::real (elt));
447  else
448  lambda(i) = std::pow (a, elt);
449  }
450  ComplexDiagMatrix D (lambda);
451 
452  retval = ComplexMatrix (Q * D * Q.inverse ());
453  }
454  catch (const octave::execution_exception&)
455  {
457  }
458 
459  return retval;
460 }
461 
462 // -*- 11 -*-
464 xpow (const ComplexMatrix& a, double b)
465 {
467 
468  octave_idx_type nr = a.rows ();
469  octave_idx_type nc = a.cols ();
470 
471  if (nr == 0 || nc == 0 || nr != nc)
473 
474  if (xisint (b))
475  {
476  int bint = static_cast<int> (b);
477  if (bint == 0)
478  {
479  retval = DiagMatrix (nr, nr, 1.0);
480  }
481  else
482  {
483  // Too much copying?
484  // FIXME: we shouldn't do this if the exponent is large...
485 
486  ComplexMatrix atmp;
487  if (bint < 0)
488  {
489  bint = -bint;
490 
491  octave_idx_type info;
492  double rcond = 0.0;
493  MatrixType mattype (a);
494 
495  atmp = a.inverse (mattype, info, rcond, 1);
496 
497  if (info == -1)
498  warning ("inverse: matrix singular to machine precision, rcond = %g", rcond);
499  }
500  else
501  atmp = a;
502 
503  ComplexMatrix result (atmp);
504 
505  bint--;
506 
507  while (bint > 0)
508  {
509  if (bint & 1)
510  // Use atmp * result instead of result * atmp
511  // for ML compatibility (bug #52706).
512  result = atmp * result;
513 
514  bint >>= 1;
515 
516  if (bint > 0)
517  atmp = atmp * atmp;
518  }
519 
520  retval = result;
521  }
522  }
523  else
524  {
525  EIG a_eig (a);
526 
527  try
528  {
529  ComplexColumnVector lambda (a_eig.eigenvalues ());
531 
532  for (octave_idx_type i = 0; i < nr; i++)
533  lambda(i) = std::pow (lambda(i), b);
534 
535  ComplexDiagMatrix D (lambda);
536 
537  retval = ComplexMatrix (Q * D * Q.inverse ());
538  }
539  catch (const octave::execution_exception&)
540  {
542  }
543  }
544 
545  return retval;
546 }
547 
548 // -*- 12 -*-
550 xpow (const ComplexMatrix& a, const Complex& b)
551 {
553 
554  octave_idx_type nr = a.rows ();
555  octave_idx_type nc = a.cols ();
556 
557  if (nr == 0 || nc == 0 || nr != nc)
559 
560  EIG a_eig (a);
561 
562  try
563  {
564  ComplexColumnVector lambda (a_eig.eigenvalues ());
566 
567  for (octave_idx_type i = 0; i < nr; i++)
568  lambda(i) = std::pow (lambda(i), b);
569 
570  ComplexDiagMatrix D (lambda);
571 
572  retval = ComplexMatrix (Q * D * Q.inverse ());
573  }
574  catch (const octave::execution_exception&)
575  {
577  }
578 
579  return retval;
580 }
581 
582 // -*- 12d -*-
584 xpow (const ComplexDiagMatrix& a, const Complex& b)
585 {
587 
588  octave_idx_type nr = a.rows ();
589  octave_idx_type nc = a.cols ();
590 
591  if (nr == 0 || nc == 0 || nr != nc)
593 
594  ComplexDiagMatrix r (nr, nc);
595  for (octave_idx_type i = 0; i < nc; i++)
596  r(i, i) = std::pow (a(i, i), b);
597  retval = r;
598 
599  return retval;
600 }
601 
602 // mixed
604 xpow (const ComplexDiagMatrix& a, double b)
605 {
606  return xpow (a, static_cast<Complex> (b));
607 }
608 
610 xpow (const DiagMatrix& a, const Complex& b)
611 {
612  return xpow (ComplexDiagMatrix (a), b);
613 }
614 
615 // Safer pow functions that work elementwise for matrices.
616 //
617 // op2 \ op1: s m cs cm
618 // +-- +---+---+----+----+
619 // scalar | | * | 3 | * | 9 |
620 // +---+---+----+----+
621 // matrix | 1 | 4 | 7 | 10 |
622 // +---+---+----+----+
623 // complex_scalar | * | 5 | * | 11 |
624 // +---+---+----+----+
625 // complex_matrix | 2 | 6 | 8 | 12 |
626 // +---+---+----+----+
627 //
628 // * -> not needed.
629 
630 // FIXME: these functions need to be fixed so that things like
631 //
632 // a = -1; b = [ 0, 0.5, 1 ]; r = a .^ b
633 //
634 // and
635 //
636 // a = -1; b = [ 0, 0.5, 1 ]; for i = 1:3, r(i) = a .^ b(i), end
637 //
638 // produce identical results. Also, it would be nice if -1^0.5
639 // produced a pure imaginary result instead of a complex number with a
640 // small real part. But perhaps that's really a problem with the math
641 // library...
642 
643 // -*- 1 -*-
645 elem_xpow (double a, const Matrix& b)
646 {
648 
649  octave_idx_type nr = b.rows ();
650  octave_idx_type nc = b.cols ();
651 
652  double d1, d2;
653 
654  if (a < 0.0 && ! b.all_integers (d1, d2))
655  {
656  Complex atmp (a);
657  ComplexMatrix result (nr, nc);
658 
659  for (octave_idx_type j = 0; j < nc; j++)
660  for (octave_idx_type i = 0; i < nr; i++)
661  {
662  octave_quit ();
663  result(i, j) = std::pow (atmp, b(i, j));
664  }
665 
666  retval = result;
667  }
668  else
669  {
670  Matrix result (nr, nc);
671 
672  for (octave_idx_type j = 0; j < nc; j++)
673  for (octave_idx_type i = 0; i < nr; i++)
674  {
675  octave_quit ();
676  result(i, j) = std::pow (a, b(i, j));
677  }
678 
679  retval = result;
680  }
681 
682  return retval;
683 }
684 
685 // -*- 2 -*-
687 elem_xpow (double a, const ComplexMatrix& b)
688 {
689  octave_idx_type nr = b.rows ();
690  octave_idx_type nc = b.cols ();
691 
692  ComplexMatrix result (nr, nc);
693  Complex atmp (a);
694 
695  for (octave_idx_type j = 0; j < nc; j++)
696  for (octave_idx_type i = 0; i < nr; i++)
697  {
698  octave_quit ();
699  result(i, j) = std::pow (atmp, b(i, j));
700  }
701 
702  return result;
703 }
704 
705 static inline bool
706 same_sign (double a, double b)
707 {
708  return (a >= 0 && b >= 0) || (a <= 0 && b <= 0);
709 }
710 
712 elem_xpow (double a, const Range& r)
713 {
715 
716  // Only optimize powers with ranges that are integer and monotonic in
717  // magnitude.
718  if (r.numel () > 1 && r.all_elements_are_ints ()
719  && same_sign (r.base (), r.limit ()))
720  {
721  octave_idx_type n = r.numel ();
722  Matrix result (1, n);
723  if (same_sign (r.base (), r.inc ()))
724  {
725  double base = std::pow (a, r.base ());
726  double inc = std::pow (a, r.inc ());
727  result(0) = base;
728  for (octave_idx_type i = 1; i < n; i++)
729  result(i) = (base *= inc);
730  }
731  else
732  {
733  // Don't use Range::limit () here.
734  double limit = std::pow (a, r.base () + (n-1) * r.inc ());
735  double inc = std::pow (a, -r.inc ());
736  result(n-1) = limit;
737  for (octave_idx_type i = n-2; i >= 0; i--)
738  result(i) = (limit *= inc);
739  }
740 
741  retval = result;
742  }
743  else
744  retval = elem_xpow (a, r.matrix_value ());
745 
746  return retval;
747 }
748 
749 // -*- 3 -*-
751 elem_xpow (const Matrix& a, double b)
752 {
754 
755  octave_idx_type nr = a.rows ();
756  octave_idx_type nc = a.cols ();
757 
758  if (! xisint (b) && a.any_element_is_negative ())
759  {
760  ComplexMatrix result (nr, nc);
761 
762  for (octave_idx_type j = 0; j < nc; j++)
763  for (octave_idx_type i = 0; i < nr; i++)
764  {
765  octave_quit ();
766 
767  Complex atmp (a(i, j));
768 
769  result(i, j) = std::pow (atmp, b);
770  }
771 
772  retval = result;
773  }
774  else
775  {
776  Matrix result (nr, nc);
777 
778  for (octave_idx_type j = 0; j < nc; j++)
779  for (octave_idx_type i = 0; i < nr; i++)
780  {
781  octave_quit ();
782  result(i, j) = std::pow (a(i, j), b);
783  }
784 
785  retval = result;
786  }
787 
788  return retval;
789 }
790 
791 // -*- 4 -*-
793 elem_xpow (const Matrix& a, const Matrix& b)
794 {
796 
797  octave_idx_type nr = a.rows ();
798  octave_idx_type nc = a.cols ();
799 
800  octave_idx_type b_nr = b.rows ();
801  octave_idx_type b_nc = b.cols ();
802 
803  if (nr != b_nr || nc != b_nc)
804  octave::err_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
805 
806  bool convert_to_complex = false;
807  for (octave_idx_type j = 0; j < nc; j++)
808  for (octave_idx_type i = 0; i < nr; i++)
809  {
810  octave_quit ();
811  double atmp = a(i, j);
812  double btmp = b(i, j);
813  if (atmp < 0.0 && ! xisint (btmp))
814  {
815  convert_to_complex = true;
816  goto done;
817  }
818  }
819 
820 done:
821 
822  if (convert_to_complex)
823  {
824  ComplexMatrix complex_result (nr, nc);
825 
826  for (octave_idx_type j = 0; j < nc; j++)
827  for (octave_idx_type i = 0; i < nr; i++)
828  {
829  octave_quit ();
830  Complex atmp (a(i, j));
831  Complex btmp (b(i, j));
832  complex_result(i, j) = std::pow (atmp, btmp);
833  }
834 
835  retval = complex_result;
836  }
837  else
838  {
839  Matrix result (nr, nc);
840 
841  for (octave_idx_type j = 0; j < nc; j++)
842  for (octave_idx_type i = 0; i < nr; i++)
843  {
844  octave_quit ();
845  result(i, j) = std::pow (a(i, j), b(i, j));
846  }
847 
848  retval = result;
849  }
850 
851  return retval;
852 }
853 
854 // -*- 5 -*-
856 elem_xpow (const Matrix& a, const Complex& b)
857 {
858  octave_idx_type nr = a.rows ();
859  octave_idx_type nc = a.cols ();
860 
861  ComplexMatrix result (nr, nc);
862 
863  for (octave_idx_type j = 0; j < nc; j++)
864  for (octave_idx_type i = 0; i < nr; i++)
865  {
866  octave_quit ();
867  result(i, j) = std::pow (Complex (a(i, j)), b);
868  }
869 
870  return result;
871 }
872 
873 // -*- 6 -*-
875 elem_xpow (const Matrix& a, const ComplexMatrix& b)
876 {
877  octave_idx_type nr = a.rows ();
878  octave_idx_type nc = a.cols ();
879 
880  octave_idx_type b_nr = b.rows ();
881  octave_idx_type b_nc = b.cols ();
882 
883  if (nr != b_nr || nc != b_nc)
884  octave::err_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
885 
886  ComplexMatrix result (nr, nc);
887 
888  for (octave_idx_type j = 0; j < nc; j++)
889  for (octave_idx_type i = 0; i < nr; i++)
890  {
891  octave_quit ();
892  result(i, j) = std::pow (Complex (a(i, j)), b(i, j));
893  }
894 
895  return result;
896 }
897 
898 // -*- 7 -*-
900 elem_xpow (const Complex& a, const Matrix& b)
901 {
902  octave_idx_type nr = b.rows ();
903  octave_idx_type nc = b.cols ();
904 
905  ComplexMatrix result (nr, nc);
906 
907  for (octave_idx_type j = 0; j < nc; j++)
908  for (octave_idx_type i = 0; i < nr; i++)
909  {
910  octave_quit ();
911  double btmp = b(i, j);
912  if (xisint (btmp))
913  result(i, j) = std::pow (a, static_cast<int> (btmp));
914  else
915  result(i, j) = std::pow (a, btmp);
916  }
917 
918  return result;
919 }
920 
921 // -*- 8 -*-
924 {
925  octave_idx_type nr = b.rows ();
926  octave_idx_type nc = b.cols ();
927 
928  ComplexMatrix result (nr, nc);
929 
930  for (octave_idx_type j = 0; j < nc; j++)
931  for (octave_idx_type i = 0; i < nr; i++)
932  {
933  octave_quit ();
934  result(i, j) = std::pow (a, b(i, j));
935  }
936 
937  return result;
938 }
939 
941 elem_xpow (const Complex& a, const Range& r)
942 {
944 
945  // Only optimize powers with ranges that are integer and monotonic in
946  // magnitude.
947  if (r.numel () > 1 && r.all_elements_are_ints ()
948  && same_sign (r.base (), r.limit ()))
949  {
950  octave_idx_type n = r.numel ();
951  ComplexMatrix result (1, n);
952 
953  if (same_sign (r.base (), r.inc ()))
954  {
955  Complex base = std::pow (a, r.base ());
956  Complex inc = std::pow (a, r.inc ());
957  result(0) = base;
958  for (octave_idx_type i = 1; i < n; i++)
959  result(i) = (base *= inc);
960  }
961  else
962  {
963  // Don't use Range::limit () here.
964  Complex limit = std::pow (a, r.base () + (n-1) * r.inc ());
965  Complex inc = std::pow (a, -r.inc ());
966  result(n-1) = limit;
967  for (octave_idx_type i = n-2; i >= 0; i--)
968  result(i) = (limit *= inc);
969  }
970 
971  retval = result;
972  }
973  else
974  retval = elem_xpow (a, r.matrix_value ());
975 
976  return retval;
977 }
978 
979 // -*- 9 -*-
981 elem_xpow (const ComplexMatrix& a, double b)
982 {
983  octave_idx_type nr = a.rows ();
984  octave_idx_type nc = a.cols ();
985 
986  ComplexMatrix result (nr, nc);
987 
988  if (xisint (b))
989  {
990  int bint = static_cast<int> (b);
991  for (octave_idx_type j = 0; j < nc; j++)
992  for (octave_idx_type i = 0; i < nr; i++)
993  {
994  octave_quit ();
995  result(i, j) = std::pow (a(i, j), bint);
996  }
997  }
998  else
999  {
1000  for (octave_idx_type j = 0; j < nc; j++)
1001  for (octave_idx_type i = 0; i < nr; i++)
1002  {
1003  octave_quit ();
1004  result(i, j) = std::pow (a(i, j), b);
1005  }
1006  }
1007 
1008  return result;
1009 }
1010 
1011 // -*- 10 -*-
1014 {
1015  octave_idx_type nr = a.rows ();
1016  octave_idx_type nc = a.cols ();
1017 
1018  octave_idx_type b_nr = b.rows ();
1019  octave_idx_type b_nc = b.cols ();
1020 
1021  if (nr != b_nr || nc != b_nc)
1022  octave::err_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
1023 
1024  ComplexMatrix result (nr, nc);
1025 
1026  for (octave_idx_type j = 0; j < nc; j++)
1027  for (octave_idx_type i = 0; i < nr; i++)
1028  {
1029  octave_quit ();
1030  double btmp = b(i, j);
1031  if (xisint (btmp))
1032  result(i, j) = std::pow (a(i, j), static_cast<int> (btmp));
1033  else
1034  result(i, j) = std::pow (a(i, j), btmp);
1035  }
1036 
1037  return result;
1038 }
1039 
1040 // -*- 11 -*-
1043 {
1044  octave_idx_type nr = a.rows ();
1045  octave_idx_type nc = a.cols ();
1046 
1047  ComplexMatrix result (nr, nc);
1048 
1049  for (octave_idx_type j = 0; j < nc; j++)
1050  for (octave_idx_type i = 0; i < nr; i++)
1051  {
1052  octave_quit ();
1053  result(i, j) = std::pow (a(i, j), b);
1054  }
1055 
1056  return result;
1057 }
1058 
1059 // -*- 12 -*-
1062 {
1063  octave_idx_type nr = a.rows ();
1064  octave_idx_type nc = a.cols ();
1065 
1066  octave_idx_type b_nr = b.rows ();
1067  octave_idx_type b_nc = b.cols ();
1068 
1069  if (nr != b_nr || nc != b_nc)
1070  octave::err_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
1071 
1072  ComplexMatrix result (nr, nc);
1073 
1074  for (octave_idx_type j = 0; j < nc; j++)
1075  for (octave_idx_type i = 0; i < nr; i++)
1076  {
1077  octave_quit ();
1078  result(i, j) = std::pow (a(i, j), b(i, j));
1079  }
1080 
1081  return result;
1082 }
1083 
1084 // Safer pow functions that work elementwise for N-D arrays.
1085 //
1086 // op2 \ op1: s nd cs cnd
1087 // +-- +---+---+----+----+
1088 // scalar | | * | 3 | * | 9 |
1089 // +---+---+----+----+
1090 // N_d | 1 | 4 | 7 | 10 |
1091 // +---+---+----+----+
1092 // complex_scalar | * | 5 | * | 11 |
1093 // +---+---+----+----+
1094 // complex_N_d | 2 | 6 | 8 | 12 |
1095 // +---+---+----+----+
1096 //
1097 // * -> not needed.
1098 
1099 // FIXME: these functions need to be fixed so that things like
1100 //
1101 // a = -1; b = [ 0, 0.5, 1 ]; r = a .^ b
1102 //
1103 // and
1104 //
1105 // a = -1; b = [ 0, 0.5, 1 ]; for i = 1:3, r(i) = a .^ b(i), end
1106 //
1107 // produce identical results. Also, it would be nice if -1^0.5
1108 // produced a pure imaginary result instead of a complex number with a
1109 // small real part. But perhaps that's really a problem with the math
1110 // library...
1111 
1112 // -*- 1 -*-
1114 elem_xpow (double a, const NDArray& b)
1115 {
1117 
1118  if (a < 0.0 && ! b.all_integers ())
1119  {
1120  Complex atmp (a);
1121  ComplexNDArray result (b.dims ());
1122  for (octave_idx_type i = 0; i < b.numel (); i++)
1123  {
1124  octave_quit ();
1125  result(i) = std::pow (atmp, b(i));
1126  }
1127 
1128  retval = result;
1129  }
1130  else
1131  {
1132  NDArray result (b.dims ());
1133  for (octave_idx_type i = 0; i < b.numel (); i++)
1134  {
1135  octave_quit ();
1136  result(i) = std::pow (a, b(i));
1137  }
1138 
1139  retval = result;
1140  }
1141 
1142  return retval;
1143 }
1144 
1145 // -*- 2 -*-
1147 elem_xpow (double a, const ComplexNDArray& b)
1148 {
1149  ComplexNDArray result (b.dims ());
1150 
1151  for (octave_idx_type i = 0; i < b.numel (); i++)
1152  {
1153  octave_quit ();
1154  result(i) = std::pow (a, b(i));
1155  }
1156 
1157  return result;
1158 }
1159 
1160 // -*- 3 -*-
1162 elem_xpow (const NDArray& a, double b)
1163 {
1165 
1166  if (! xisint (b))
1167  {
1168  if (a.any_element_is_negative ())
1169  {
1170  ComplexNDArray result (a.dims ());
1171 
1172  for (octave_idx_type i = 0; i < a.numel (); i++)
1173  {
1174  octave_quit ();
1175  Complex atmp (a(i));
1176  result(i) = std::pow (atmp, b);
1177  }
1178 
1179  retval = result;
1180  }
1181  else
1182  {
1183  NDArray result (a.dims ());
1184  for (octave_idx_type i = 0; i < a.numel (); i++)
1185  {
1186  octave_quit ();
1187  result(i) = std::pow (a(i), b);
1188  }
1189 
1190  retval = result;
1191  }
1192  }
1193  else
1194  {
1195  NoAlias<NDArray> result (a.dims ());
1196 
1197  int ib = static_cast<int> (b);
1198  if (ib == 2)
1199  {
1200  for (octave_idx_type i = 0; i < a.numel (); i++)
1201  result(i) = a(i) * a(i);
1202  }
1203  else if (ib == 3)
1204  {
1205  for (octave_idx_type i = 0; i < a.numel (); i++)
1206  result(i) = a(i) * a(i) * a(i);
1207  }
1208  else if (ib == -1)
1209  {
1210  for (octave_idx_type i = 0; i < a.numel (); i++)
1211  result(i) = 1.0 / a(i);
1212  }
1213  else
1214  {
1215  for (octave_idx_type i = 0; i < a.numel (); i++)
1216  {
1217  octave_quit ();
1218  result(i) = std::pow (a(i), ib);
1219  }
1220  }
1221 
1222  retval = result;
1223  }
1224 
1225  return retval;
1226 }
1227 
1228 // -*- 4 -*-
1230 elem_xpow (const NDArray& a, const NDArray& b)
1231 {
1233 
1234  dim_vector a_dims = a.dims ();
1235  dim_vector b_dims = b.dims ();
1236 
1237  if (a_dims != b_dims)
1238  {
1239  if (! is_valid_bsxfun ("operator .^", a_dims, b_dims))
1240  octave::err_nonconformant ("operator .^", a_dims, b_dims);
1241 
1242  // Potentially complex results
1245  if (! xb.all_integers () && xa.any_element_is_negative ())
1246  return octave_value (bsxfun_pow (ComplexNDArray (xa), xb));
1247  else
1248  return octave_value (bsxfun_pow (xa, xb));
1249  }
1250 
1251  int len = a.numel ();
1252 
1253  bool convert_to_complex = false;
1254 
1255  for (octave_idx_type i = 0; i < len; i++)
1256  {
1257  octave_quit ();
1258  double atmp = a(i);
1259  double btmp = b(i);
1260  if (atmp < 0.0 && ! xisint (btmp))
1261  {
1262  convert_to_complex = true;
1263  goto done;
1264  }
1265  }
1266 
1267 done:
1268 
1269  if (convert_to_complex)
1270  {
1271  ComplexNDArray complex_result (a_dims);
1272 
1273  for (octave_idx_type i = 0; i < len; i++)
1274  {
1275  octave_quit ();
1276  Complex atmp (a(i));
1277  complex_result(i) = std::pow (atmp, b(i));
1278  }
1279 
1280  retval = complex_result;
1281  }
1282  else
1283  {
1284  NDArray result (a_dims);
1285 
1286  for (octave_idx_type i = 0; i < len; i++)
1287  {
1288  octave_quit ();
1289  result(i) = std::pow (a(i), b(i));
1290  }
1291 
1292  retval = result;
1293  }
1294 
1295  return retval;
1296 }
1297 
1298 // -*- 5 -*-
1300 elem_xpow (const NDArray& a, const Complex& b)
1301 {
1302  ComplexNDArray result (a.dims ());
1303 
1304  for (octave_idx_type i = 0; i < a.numel (); i++)
1305  {
1306  octave_quit ();
1307  result(i) = std::pow (a(i), b);
1308  }
1309 
1310  return result;
1311 }
1312 
1313 // -*- 6 -*-
1316 {
1317  dim_vector a_dims = a.dims ();
1318  dim_vector b_dims = b.dims ();
1319 
1320  if (a_dims != b_dims)
1321  {
1322  if (! is_valid_bsxfun ("operator .^", a_dims, b_dims))
1323  octave::err_nonconformant ("operator .^", a_dims, b_dims);
1324 
1325  return bsxfun_pow (a, b);
1326  }
1327 
1328  ComplexNDArray result (a_dims);
1329 
1330  for (octave_idx_type i = 0; i < a.numel (); i++)
1331  {
1332  octave_quit ();
1333  result(i) = std::pow (a(i), b(i));
1334  }
1335 
1336  return result;
1337 }
1338 
1339 // -*- 7 -*-
1341 elem_xpow (const Complex& a, const NDArray& b)
1342 {
1343  ComplexNDArray result (b.dims ());
1344 
1345  for (octave_idx_type i = 0; i < b.numel (); i++)
1346  {
1347  octave_quit ();
1348  double btmp = b(i);
1349  if (xisint (btmp))
1350  result(i) = std::pow (a, static_cast<int> (btmp));
1351  else
1352  result(i) = std::pow (a, btmp);
1353  }
1354 
1355  return result;
1356 }
1357 
1358 // -*- 8 -*-
1361 {
1362  ComplexNDArray result (b.dims ());
1363 
1364  for (octave_idx_type i = 0; i < b.numel (); i++)
1365  {
1366  octave_quit ();
1367  result(i) = std::pow (a, b(i));
1368  }
1369 
1370  return result;
1371 }
1372 
1373 // -*- 9 -*-
1375 elem_xpow (const ComplexNDArray& a, double b)
1376 {
1377  ComplexNDArray result (a.dims ());
1378 
1379  if (xisint (b))
1380  {
1381  int bint = static_cast<int> (b);
1382  if (bint == -1)
1383  {
1384  for (octave_idx_type i = 0; i < a.numel (); i++)
1385  result.xelem (i) = 1.0 / a(i);
1386  }
1387  else
1388  {
1389  for (octave_idx_type i = 0; i < a.numel (); i++)
1390  {
1391  octave_quit ();
1392  result(i) = std::pow (a(i), bint);
1393  }
1394  }
1395  }
1396  else
1397  {
1398  for (octave_idx_type i = 0; i < a.numel (); i++)
1399  {
1400  octave_quit ();
1401  result(i) = std::pow (a(i), b);
1402  }
1403  }
1404 
1405  return result;
1406 }
1407 
1408 // -*- 10 -*-
1411 {
1412  dim_vector a_dims = a.dims ();
1413  dim_vector b_dims = b.dims ();
1414 
1415  if (a_dims != b_dims)
1416  {
1417  if (! is_valid_bsxfun ("operator .^", a_dims, b_dims))
1418  octave::err_nonconformant ("operator .^", a_dims, b_dims);
1419 
1420  return bsxfun_pow (a, b);
1421  }
1422 
1423  ComplexNDArray result (a_dims);
1424 
1425  for (octave_idx_type i = 0; i < a.numel (); i++)
1426  {
1427  octave_quit ();
1428  double btmp = b(i);
1429  if (xisint (btmp))
1430  result(i) = std::pow (a(i), static_cast<int> (btmp));
1431  else
1432  result(i) = std::pow (a(i), btmp);
1433  }
1434 
1435  return result;
1436 }
1437 
1438 // -*- 11 -*-
1441 {
1442  ComplexNDArray result (a.dims ());
1443 
1444  for (octave_idx_type i = 0; i < a.numel (); i++)
1445  {
1446  octave_quit ();
1447  result(i) = std::pow (a(i), b);
1448  }
1449 
1450  return result;
1451 }
1452 
1453 // -*- 12 -*-
1456 {
1457  dim_vector a_dims = a.dims ();
1458  dim_vector b_dims = b.dims ();
1459 
1460  if (a_dims != b_dims)
1461  {
1462  if (! is_valid_bsxfun ("operator .^", a_dims, b_dims))
1463  octave::err_nonconformant ("operator .^", a_dims, b_dims);
1464 
1465  return bsxfun_pow (a, b);
1466  }
1467 
1468  ComplexNDArray result (a_dims);
1469 
1470  for (octave_idx_type i = 0; i < a.numel (); i++)
1471  {
1472  octave_quit ();
1473  result(i) = std::pow (a(i), b(i));
1474  }
1475 
1476  return result;
1477 }
1478 
1479 // Safer pow functions.
1480 //
1481 // op2 \ op1: s m cs cm
1482 // +-- +---+---+----+----+
1483 // scalar | | 1 | 5 | 7 | 11 |
1484 // +---+---+----+----+
1485 // matrix | 2 | * | 8 | * |
1486 // +---+---+----+----+
1487 // complex_scalar | 3 | 6 | 9 | 12 |
1488 // +---+---+----+----+
1489 // complex_matrix | 4 | * | 10 | * |
1490 // +---+---+----+----+
1491 
1492 // -*- 1 -*-
1494 xpow (float a, float b)
1495 {
1496  float retval;
1497 
1498  if (a < 0.0 && ! xisint (b))
1499  {
1500  FloatComplex atmp (a);
1501 
1502  return std::pow (atmp, b);
1503  }
1504  else
1505  retval = std::pow (a, b);
1506 
1507  return retval;
1508 }
1509 
1510 // -*- 2 -*-
1512 xpow (float a, const FloatMatrix& b)
1513 {
1515 
1516  octave_idx_type nr = b.rows ();
1517  octave_idx_type nc = b.cols ();
1518 
1519  if (nr == 0 || nc == 0 || nr != nc)
1521 
1522  FloatEIG b_eig (b);
1523 
1524  try
1525  {
1526  FloatComplexColumnVector lambda (b_eig.eigenvalues ());
1528 
1529  for (octave_idx_type i = 0; i < nr; i++)
1530  {
1531  FloatComplex elt = lambda(i);
1532  if (std::imag (elt) == 0.0)
1533  lambda(i) = std::pow (a, std::real (elt));
1534  else
1535  lambda(i) = std::pow (a, elt);
1536  }
1537  FloatComplexDiagMatrix D (lambda);
1538 
1539  FloatComplexMatrix C = Q * D * Q.inverse ();
1540 
1541  if (a > 0)
1542  retval = real (C);
1543  else
1544  retval = C;
1545  }
1546  catch (const octave::execution_exception&)
1547  {
1549  }
1550 
1551  return retval;
1552 }
1553 
1554 // -*- 3 -*-
1556 xpow (float a, const FloatComplex& b)
1557 {
1559  return result;
1560 }
1561 
1562 // -*- 4 -*-
1564 xpow (float a, const FloatComplexMatrix& b)
1565 {
1567 
1568  octave_idx_type nr = b.rows ();
1569  octave_idx_type nc = b.cols ();
1570 
1571  if (nr == 0 || nc == 0 || nr != nc)
1573 
1574  FloatEIG b_eig (b);
1575 
1576  try
1577  {
1578  FloatComplexColumnVector lambda (b_eig.eigenvalues ());
1580 
1581  for (octave_idx_type i = 0; i < nr; i++)
1582  {
1583  FloatComplex elt = lambda(i);
1584  if (std::imag (elt) == 0.0)
1585  lambda(i) = std::pow (a, std::real (elt));
1586  else
1587  lambda(i) = std::pow (a, elt);
1588  }
1589  FloatComplexDiagMatrix D (lambda);
1590 
1591  retval = FloatComplexMatrix (Q * D * Q.inverse ());
1592  }
1593  catch (const octave::execution_exception&)
1594  {
1596  }
1597 
1598  return retval;
1599 }
1600 
1601 // -*- 5 -*-
1603 xpow (const FloatMatrix& a, float b)
1604 {
1606 
1607  octave_idx_type nr = a.rows ();
1608  octave_idx_type nc = a.cols ();
1609 
1610  if (nr == 0 || nc == 0 || nr != nc)
1612 
1613  if (xisint (b))
1614  {
1615  int bint = static_cast<int> (b);
1616  if (bint == 0)
1617  {
1618  retval = FloatDiagMatrix (nr, nr, 1.0f);
1619  }
1620  else
1621  {
1622  // Too much copying?
1623  // FIXME: we shouldn't do this if the exponent is large...
1624 
1625  FloatMatrix atmp;
1626  if (bint < 0)
1627  {
1628  bint = -bint;
1629 
1630  octave_idx_type info;
1631  float rcond = 0.0;
1632  MatrixType mattype (a);
1633 
1634  atmp = a.inverse (mattype, info, rcond, 1);
1635 
1636  if (info == -1)
1637  warning ("inverse: matrix singular to machine precision, rcond = %g", rcond);
1638  }
1639  else
1640  atmp = a;
1641 
1642  FloatMatrix result (atmp);
1643 
1644  bint--;
1645 
1646  while (bint > 0)
1647  {
1648  if (bint & 1)
1649  // Use atmp * result instead of result * atmp
1650  // for ML compatibility (bug #52706).
1651  result = atmp * result;
1652 
1653  bint >>= 1;
1654 
1655  if (bint > 0)
1656  atmp = atmp * atmp;
1657  }
1658 
1659  retval = result;
1660  }
1661  }
1662  else
1663  {
1664  FloatEIG a_eig (a);
1665 
1666  try
1667  {
1668  FloatComplexColumnVector lambda (a_eig.eigenvalues ());
1670 
1671  for (octave_idx_type i = 0; i < nr; i++)
1672  lambda(i) = std::pow (lambda(i), b);
1673 
1674  FloatComplexDiagMatrix D (lambda);
1675 
1676  retval = FloatComplexMatrix (Q * D * Q.inverse ());
1677  }
1678  catch (const octave::execution_exception&)
1679  {
1681  }
1682  }
1683 
1684  return retval;
1685 }
1686 
1687 // -*- 5d -*-
1689 xpow (const FloatDiagMatrix& a, float b)
1690 {
1692 
1693  octave_idx_type nr = a.rows ();
1694  octave_idx_type nc = a.cols ();
1695 
1696  if (nr == 0 || nc == 0 || nr != nc)
1698 
1699  if (xisint (b))
1700  {
1701  FloatDiagMatrix r (nr, nc);
1702  for (octave_idx_type i = 0; i < nc; i++)
1703  r.dgelem (i) = std::pow (a.dgelem (i), b);
1704  retval = r;
1705  }
1706  else
1707  {
1708  FloatComplexDiagMatrix r (nr, nc);
1709  for (octave_idx_type i = 0; i < nc; i++)
1710  r.dgelem (i) = std::pow (static_cast<FloatComplex> (a.dgelem (i)), b);
1711  retval = r;
1712  }
1713 
1714  return retval;
1715 }
1716 
1717 // -*- 6 -*-
1719 xpow (const FloatMatrix& a, const FloatComplex& b)
1720 {
1722 
1723  octave_idx_type nr = a.rows ();
1724  octave_idx_type nc = a.cols ();
1725 
1726  if (nr == 0 || nc == 0 || nr != nc)
1728 
1729  FloatEIG a_eig (a);
1730 
1731  try
1732  {
1733  FloatComplexColumnVector lambda (a_eig.eigenvalues ());
1735 
1736  for (octave_idx_type i = 0; i < nr; i++)
1737  lambda(i) = std::pow (lambda(i), b);
1738 
1739  FloatComplexDiagMatrix D (lambda);
1740 
1741  retval = FloatComplexMatrix (Q * D * Q.inverse ());
1742  }
1743  catch (const octave::execution_exception&)
1744  {
1746  }
1747 
1748  return retval;
1749 }
1750 
1751 // -*- 7 -*-
1753 xpow (const FloatComplex& a, float b)
1754 {
1756 
1757  if (xisint (b))
1758  result = std::pow (a, static_cast<int> (b));
1759  else
1760  result = std::pow (a, b);
1761 
1762  return result;
1763 }
1764 
1765 // -*- 8 -*-
1767 xpow (const FloatComplex& a, const FloatMatrix& b)
1768 {
1770 
1771  octave_idx_type nr = b.rows ();
1772  octave_idx_type nc = b.cols ();
1773 
1774  if (nr == 0 || nc == 0 || nr != nc)
1776 
1777  FloatEIG b_eig (b);
1778 
1779  try
1780  {
1781  FloatComplexColumnVector lambda (b_eig.eigenvalues ());
1783 
1784  for (octave_idx_type i = 0; i < nr; i++)
1785  {
1786  FloatComplex elt = lambda(i);
1787  if (std::imag (elt) == 0.0)
1788  lambda(i) = std::pow (a, std::real (elt));
1789  else
1790  lambda(i) = std::pow (a, elt);
1791  }
1792  FloatComplexDiagMatrix D (lambda);
1793 
1794  retval = FloatComplexMatrix (Q * D * Q.inverse ());
1795  }
1796  catch (const octave::execution_exception&)
1797  {
1799  }
1800 
1801  return retval;
1802 }
1803 
1804 // -*- 9 -*-
1807 {
1809  result = std::pow (a, b);
1810  return result;
1811 }
1812 
1813 // -*- 10 -*-
1816 {
1818 
1819  octave_idx_type nr = b.rows ();
1820  octave_idx_type nc = b.cols ();
1821 
1822  if (nr == 0 || nc == 0 || nr != nc)
1824 
1825  FloatEIG b_eig (b);
1826 
1827  try
1828  {
1829  FloatComplexColumnVector lambda (b_eig.eigenvalues ());
1831 
1832  for (octave_idx_type i = 0; i < nr; i++)
1833  {
1834  FloatComplex elt = lambda(i);
1835  if (std::imag (elt) == 0.0)
1836  lambda(i) = std::pow (a, std::real (elt));
1837  else
1838  lambda(i) = std::pow (a, elt);
1839  }
1840  FloatComplexDiagMatrix D (lambda);
1841 
1842  retval = FloatComplexMatrix (Q * D * Q.inverse ());
1843  }
1844  catch (const octave::execution_exception&)
1845  {
1847  }
1848 
1849  return retval;
1850 }
1851 
1852 // -*- 11 -*-
1854 xpow (const FloatComplexMatrix& a, float b)
1855 {
1857 
1858  octave_idx_type nr = a.rows ();
1859  octave_idx_type nc = a.cols ();
1860 
1861  if (nr == 0 || nc == 0 || nr != nc)
1863 
1864  if (xisint (b))
1865  {
1866  int bint = static_cast<int> (b);
1867  if (bint == 0)
1868  {
1869  retval = FloatDiagMatrix (nr, nr, 1.0);
1870  }
1871  else
1872  {
1873  // Too much copying?
1874  // FIXME: we shouldn't do this if the exponent is large...
1875 
1876  FloatComplexMatrix atmp;
1877  if (bint < 0)
1878  {
1879  bint = -bint;
1880 
1881  octave_idx_type info;
1882  float rcond = 0.0;
1883  MatrixType mattype (a);
1884 
1885  atmp = a.inverse (mattype, info, rcond, 1);
1886 
1887  if (info == -1)
1888  warning ("inverse: matrix singular to machine precision, rcond = %g", rcond);
1889  }
1890  else
1891  atmp = a;
1892 
1893  FloatComplexMatrix result (atmp);
1894 
1895  bint--;
1896 
1897  while (bint > 0)
1898  {
1899  if (bint & 1)
1900  // Use atmp * result instead of result * atmp
1901  // for ML compatibility (bug #52706).
1902  result = atmp * result;
1903 
1904  bint >>= 1;
1905 
1906  if (bint > 0)
1907  atmp = atmp * atmp;
1908  }
1909 
1910  retval = result;
1911  }
1912  }
1913  else
1914  {
1915  FloatEIG a_eig (a);
1916 
1917  try
1918  {
1919  FloatComplexColumnVector lambda (a_eig.eigenvalues ());
1921 
1922  for (octave_idx_type i = 0; i < nr; i++)
1923  lambda(i) = std::pow (lambda(i), b);
1924 
1925  FloatComplexDiagMatrix D (lambda);
1926 
1927  retval = FloatComplexMatrix (Q * D * Q.inverse ());
1928  }
1929  catch (const octave::execution_exception&)
1930  {
1932  }
1933  }
1934 
1935  return retval;
1936 }
1937 
1938 // -*- 12 -*-
1941 {
1943 
1944  octave_idx_type nr = a.rows ();
1945  octave_idx_type nc = a.cols ();
1946 
1947  if (nr == 0 || nc == 0 || nr != nc)
1949 
1950  FloatEIG a_eig (a);
1951 
1952  try
1953  {
1954  FloatComplexColumnVector lambda (a_eig.eigenvalues ());
1956 
1957  for (octave_idx_type i = 0; i < nr; i++)
1958  lambda(i) = std::pow (lambda(i), b);
1959 
1960  FloatComplexDiagMatrix D (lambda);
1961 
1962  retval = FloatComplexMatrix (Q * D * Q.inverse ());
1963  }
1964  catch (const octave::execution_exception&)
1965  {
1967  }
1968 
1969  return retval;
1970 }
1971 
1972 // -*- 12d -*-
1975 {
1977 
1978  octave_idx_type nr = a.rows ();
1979  octave_idx_type nc = a.cols ();
1980 
1981  if (nr == 0 || nc == 0 || nr != nc)
1983 
1984  FloatComplexDiagMatrix r (nr, nc);
1985  for (octave_idx_type i = 0; i < nc; i++)
1986  r(i, i) = std::pow (a(i, i), b);
1987  retval = r;
1988 
1989  return retval;
1990 }
1991 
1992 // mixed
1995 {
1996  return xpow (a, static_cast<FloatComplex> (b));
1997 }
1998 
2001 {
2002  return xpow (FloatComplexDiagMatrix (a), b);
2003 }
2004 
2005 // Safer pow functions that work elementwise for matrices.
2006 //
2007 // op2 \ op1: s m cs cm
2008 // +-- +---+---+----+----+
2009 // scalar | | * | 3 | * | 9 |
2010 // +---+---+----+----+
2011 // matrix | 1 | 4 | 7 | 10 |
2012 // +---+---+----+----+
2013 // complex_scalar | * | 5 | * | 11 |
2014 // +---+---+----+----+
2015 // complex_matrix | 2 | 6 | 8 | 12 |
2016 // +---+---+----+----+
2017 //
2018 // * -> not needed.
2019 
2020 // FIXME: these functions need to be fixed so that things like
2021 //
2022 // a = -1; b = [ 0, 0.5, 1 ]; r = a .^ b
2023 //
2024 // and
2025 //
2026 // a = -1; b = [ 0, 0.5, 1 ]; for i = 1:3, r(i) = a .^ b(i), end
2027 //
2028 // produce identical results. Also, it would be nice if -1^0.5
2029 // produced a pure imaginary result instead of a complex number with a
2030 // small real part. But perhaps that's really a problem with the math
2031 // library...
2032 
2033 // -*- 1 -*-
2035 elem_xpow (float a, const FloatMatrix& b)
2036 {
2038 
2039  octave_idx_type nr = b.rows ();
2040  octave_idx_type nc = b.cols ();
2041 
2042  float d1, d2;
2043 
2044  if (a < 0.0 && ! b.all_integers (d1, d2))
2045  {
2046  FloatComplex atmp (a);
2047  FloatComplexMatrix result (nr, nc);
2048 
2049  for (octave_idx_type j = 0; j < nc; j++)
2050  for (octave_idx_type i = 0; i < nr; i++)
2051  {
2052  octave_quit ();
2053  result(i, j) = std::pow (atmp, b(i, j));
2054  }
2055 
2056  retval = result;
2057  }
2058  else
2059  {
2060  FloatMatrix result (nr, nc);
2061 
2062  for (octave_idx_type j = 0; j < nc; j++)
2063  for (octave_idx_type i = 0; i < nr; i++)
2064  {
2065  octave_quit ();
2066  result(i, j) = std::pow (a, b(i, j));
2067  }
2068 
2069  retval = result;
2070  }
2071 
2072  return retval;
2073 }
2074 
2075 // -*- 2 -*-
2078 {
2079  octave_idx_type nr = b.rows ();
2080  octave_idx_type nc = b.cols ();
2081 
2082  FloatComplexMatrix result (nr, nc);
2083  FloatComplex atmp (a);
2084 
2085  for (octave_idx_type j = 0; j < nc; j++)
2086  for (octave_idx_type i = 0; i < nr; i++)
2087  {
2088  octave_quit ();
2089  result(i, j) = std::pow (atmp, b(i, j));
2090  }
2091 
2092  return result;
2093 }
2094 
2095 // -*- 3 -*-
2097 elem_xpow (const FloatMatrix& a, float b)
2098 {
2100 
2101  octave_idx_type nr = a.rows ();
2102  octave_idx_type nc = a.cols ();
2103 
2104  if (! xisint (b) && a.any_element_is_negative ())
2105  {
2106  FloatComplexMatrix result (nr, nc);
2107 
2108  for (octave_idx_type j = 0; j < nc; j++)
2109  for (octave_idx_type i = 0; i < nr; i++)
2110  {
2111  octave_quit ();
2112 
2113  FloatComplex atmp (a(i, j));
2114 
2115  result(i, j) = std::pow (atmp, b);
2116  }
2117 
2118  retval = result;
2119  }
2120  else
2121  {
2122  FloatMatrix result (nr, nc);
2123 
2124  for (octave_idx_type j = 0; j < nc; j++)
2125  for (octave_idx_type i = 0; i < nr; i++)
2126  {
2127  octave_quit ();
2128  result(i, j) = std::pow (a(i, j), b);
2129  }
2130 
2131  retval = result;
2132  }
2133 
2134  return retval;
2135 }
2136 
2137 // -*- 4 -*-
2140 {
2142 
2143  octave_idx_type nr = a.rows ();
2144  octave_idx_type nc = a.cols ();
2145 
2146  octave_idx_type b_nr = b.rows ();
2147  octave_idx_type b_nc = b.cols ();
2148 
2149  if (nr != b_nr || nc != b_nc)
2150  octave::err_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
2151 
2152  bool convert_to_complex = false;
2153  for (octave_idx_type j = 0; j < nc; j++)
2154  for (octave_idx_type i = 0; i < nr; i++)
2155  {
2156  octave_quit ();
2157  float atmp = a(i, j);
2158  float btmp = b(i, j);
2159  if (atmp < 0.0 && ! xisint (btmp))
2160  {
2161  convert_to_complex = true;
2162  goto done;
2163  }
2164  }
2165 
2166 done:
2167 
2168  if (convert_to_complex)
2169  {
2170  FloatComplexMatrix complex_result (nr, nc);
2171 
2172  for (octave_idx_type j = 0; j < nc; j++)
2173  for (octave_idx_type i = 0; i < nr; i++)
2174  {
2175  octave_quit ();
2176  FloatComplex atmp (a(i, j));
2177  FloatComplex btmp (b(i, j));
2178  complex_result(i, j) = std::pow (atmp, btmp);
2179  }
2180 
2181  retval = complex_result;
2182  }
2183  else
2184  {
2185  FloatMatrix result (nr, nc);
2186 
2187  for (octave_idx_type j = 0; j < nc; j++)
2188  for (octave_idx_type i = 0; i < nr; i++)
2189  {
2190  octave_quit ();
2191  result(i, j) = std::pow (a(i, j), b(i, j));
2192  }
2193 
2194  retval = result;
2195  }
2196 
2197  return retval;
2198 }
2199 
2200 // -*- 5 -*-
2203 {
2204  octave_idx_type nr = a.rows ();
2205  octave_idx_type nc = a.cols ();
2206 
2207  FloatComplexMatrix result (nr, nc);
2208 
2209  for (octave_idx_type j = 0; j < nc; j++)
2210  for (octave_idx_type i = 0; i < nr; i++)
2211  {
2212  octave_quit ();
2213  result(i, j) = std::pow (FloatComplex (a(i, j)), b);
2214  }
2215 
2216  return result;
2217 }
2218 
2219 // -*- 6 -*-
2222 {
2223  octave_idx_type nr = a.rows ();
2224  octave_idx_type nc = a.cols ();
2225 
2226  octave_idx_type b_nr = b.rows ();
2227  octave_idx_type b_nc = b.cols ();
2228 
2229  if (nr != b_nr || nc != b_nc)
2230  octave::err_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
2231 
2232  FloatComplexMatrix result (nr, nc);
2233 
2234  for (octave_idx_type j = 0; j < nc; j++)
2235  for (octave_idx_type i = 0; i < nr; i++)
2236  {
2237  octave_quit ();
2238  result(i, j) = std::pow (FloatComplex (a(i, j)), b(i, j));
2239  }
2240 
2241  return result;
2242 }
2243 
2244 // -*- 7 -*-
2247 {
2248  octave_idx_type nr = b.rows ();
2249  octave_idx_type nc = b.cols ();
2250 
2251  FloatComplexMatrix result (nr, nc);
2252 
2253  for (octave_idx_type j = 0; j < nc; j++)
2254  for (octave_idx_type i = 0; i < nr; i++)
2255  {
2256  octave_quit ();
2257  float btmp = b(i, j);
2258  if (xisint (btmp))
2259  result(i, j) = std::pow (a, static_cast<int> (btmp));
2260  else
2261  result(i, j) = std::pow (a, btmp);
2262  }
2263 
2264  return result;
2265 }
2266 
2267 // -*- 8 -*-
2270 {
2271  octave_idx_type nr = b.rows ();
2272  octave_idx_type nc = b.cols ();
2273 
2274  FloatComplexMatrix result (nr, nc);
2275 
2276  for (octave_idx_type j = 0; j < nc; j++)
2277  for (octave_idx_type i = 0; i < nr; i++)
2278  {
2279  octave_quit ();
2280  result(i, j) = std::pow (a, b(i, j));
2281  }
2282 
2283  return result;
2284 }
2285 
2286 // -*- 9 -*-
2289 {
2290  octave_idx_type nr = a.rows ();
2291  octave_idx_type nc = a.cols ();
2292 
2293  FloatComplexMatrix result (nr, nc);
2294 
2295  if (xisint (b))
2296  {
2297  int bint = static_cast<int> (b);
2298  for (octave_idx_type j = 0; j < nc; j++)
2299  for (octave_idx_type i = 0; i < nr; i++)
2300  {
2301  octave_quit ();
2302  result(i, j) = std::pow (a(i, j), bint);
2303  }
2304  }
2305  else
2306  {
2307  for (octave_idx_type j = 0; j < nc; j++)
2308  for (octave_idx_type i = 0; i < nr; i++)
2309  {
2310  octave_quit ();
2311  result(i, j) = std::pow (a(i, j), b);
2312  }
2313  }
2314 
2315  return result;
2316 }
2317 
2318 // -*- 10 -*-
2321 {
2322  octave_idx_type nr = a.rows ();
2323  octave_idx_type nc = a.cols ();
2324 
2325  octave_idx_type b_nr = b.rows ();
2326  octave_idx_type b_nc = b.cols ();
2327 
2328  if (nr != b_nr || nc != b_nc)
2329  octave::err_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
2330 
2331  FloatComplexMatrix result (nr, nc);
2332 
2333  for (octave_idx_type j = 0; j < nc; j++)
2334  for (octave_idx_type i = 0; i < nr; i++)
2335  {
2336  octave_quit ();
2337  float btmp = b(i, j);
2338  if (xisint (btmp))
2339  result(i, j) = std::pow (a(i, j), static_cast<int> (btmp));
2340  else
2341  result(i, j) = std::pow (a(i, j), btmp);
2342  }
2343 
2344  return result;
2345 }
2346 
2347 // -*- 11 -*-
2350 {
2351  octave_idx_type nr = a.rows ();
2352  octave_idx_type nc = a.cols ();
2353 
2354  FloatComplexMatrix result (nr, nc);
2355 
2356  for (octave_idx_type j = 0; j < nc; j++)
2357  for (octave_idx_type i = 0; i < nr; i++)
2358  {
2359  octave_quit ();
2360  result(i, j) = std::pow (a(i, j), b);
2361  }
2362 
2363  return result;
2364 }
2365 
2366 // -*- 12 -*-
2369 {
2370  octave_idx_type nr = a.rows ();
2371  octave_idx_type nc = a.cols ();
2372 
2373  octave_idx_type b_nr = b.rows ();
2374  octave_idx_type b_nc = b.cols ();
2375 
2376  if (nr != b_nr || nc != b_nc)
2377  octave::err_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
2378 
2379  FloatComplexMatrix result (nr, nc);
2380 
2381  for (octave_idx_type j = 0; j < nc; j++)
2382  for (octave_idx_type i = 0; i < nr; i++)
2383  {
2384  octave_quit ();
2385  result(i, j) = std::pow (a(i, j), b(i, j));
2386  }
2387 
2388  return result;
2389 }
2390 
2391 // Safer pow functions that work elementwise for N-D arrays.
2392 //
2393 // op2 \ op1: s nd cs cnd
2394 // +-- +---+---+----+----+
2395 // scalar | | * | 3 | * | 9 |
2396 // +---+---+----+----+
2397 // N_d | 1 | 4 | 7 | 10 |
2398 // +---+---+----+----+
2399 // complex_scalar | * | 5 | * | 11 |
2400 // +---+---+----+----+
2401 // complex_N_d | 2 | 6 | 8 | 12 |
2402 // +---+---+----+----+
2403 //
2404 // * -> not needed.
2405 
2406 // FIXME: these functions need to be fixed so that things like
2407 //
2408 // a = -1; b = [ 0, 0.5, 1 ]; r = a .^ b
2409 //
2410 // and
2411 //
2412 // a = -1; b = [ 0, 0.5, 1 ]; for i = 1:3, r(i) = a .^ b(i), end
2413 //
2414 // produce identical results. Also, it would be nice if -1^0.5
2415 // produced a pure imaginary result instead of a complex number with a
2416 // small real part. But perhaps that's really a problem with the math
2417 // library...
2418 
2419 // -*- 1 -*-
2421 elem_xpow (float a, const FloatNDArray& b)
2422 {
2424 
2425  if (a < 0.0 && ! b.all_integers ())
2426  {
2427  FloatComplex atmp (a);
2428  FloatComplexNDArray result (b.dims ());
2429  for (octave_idx_type i = 0; i < b.numel (); i++)
2430  {
2431  octave_quit ();
2432  result(i) = std::pow (atmp, b(i));
2433  }
2434 
2435  retval = result;
2436  }
2437  else
2438  {
2439  FloatNDArray result (b.dims ());
2440  for (octave_idx_type i = 0; i < b.numel (); i++)
2441  {
2442  octave_quit ();
2443  result(i) = std::pow (a, b(i));
2444  }
2445 
2446  retval = result;
2447  }
2448 
2449  return retval;
2450 }
2451 
2452 // -*- 2 -*-
2455 {
2456  FloatComplexNDArray result (b.dims ());
2457 
2458  for (octave_idx_type i = 0; i < b.numel (); i++)
2459  {
2460  octave_quit ();
2461  result(i) = std::pow (a, b(i));
2462  }
2463 
2464  return result;
2465 }
2466 
2467 // -*- 3 -*-
2469 elem_xpow (const FloatNDArray& a, float b)
2470 {
2472 
2473  if (! xisint (b))
2474  {
2475  if (a.any_element_is_negative ())
2476  {
2477  FloatComplexNDArray result (a.dims ());
2478 
2479  for (octave_idx_type i = 0; i < a.numel (); i++)
2480  {
2481  octave_quit ();
2482 
2483  FloatComplex atmp (a(i));
2484 
2485  result(i) = std::pow (atmp, b);
2486  }
2487 
2488  retval = result;
2489  }
2490  else
2491  {
2492  FloatNDArray result (a.dims ());
2493  for (octave_idx_type i = 0; i < a.numel (); i++)
2494  {
2495  octave_quit ();
2496  result(i) = std::pow (a(i), b);
2497  }
2498 
2499  retval = result;
2500  }
2501  }
2502  else
2503  {
2504  NoAlias<FloatNDArray> result (a.dims ());
2505 
2506  int ib = static_cast<int> (b);
2507  if (ib == 2)
2508  {
2509  for (octave_idx_type i = 0; i < a.numel (); i++)
2510  result(i) = a(i) * a(i);
2511  }
2512  else if (ib == 3)
2513  {
2514  for (octave_idx_type i = 0; i < a.numel (); i++)
2515  result(i) = a(i) * a(i) * a(i);
2516  }
2517  else if (ib == -1)
2518  {
2519  for (octave_idx_type i = 0; i < a.numel (); i++)
2520  result(i) = 1.0f / a(i);
2521  }
2522  else
2523  {
2524  for (octave_idx_type i = 0; i < a.numel (); i++)
2525  {
2526  octave_quit ();
2527  result(i) = std::pow (a(i), ib);
2528  }
2529  }
2530 
2531  retval = result;
2532  }
2533 
2534  return retval;
2535 }
2536 
2537 // -*- 4 -*-
2540 {
2542 
2543  dim_vector a_dims = a.dims ();
2544  dim_vector b_dims = b.dims ();
2545 
2546  if (a_dims != b_dims)
2547  {
2548  if (! is_valid_bsxfun ("operator .^", a_dims, b_dims))
2549  octave::err_nonconformant ("operator .^", a_dims, b_dims);
2550 
2551  // Potentially complex results
2554  if (! xb.all_integers () && xa.any_element_is_negative ())
2555  return octave_value (bsxfun_pow (FloatComplexNDArray (xa), xb));
2556  else
2557  return octave_value (bsxfun_pow (xa, xb));
2558  }
2559 
2560  int len = a.numel ();
2561 
2562  bool convert_to_complex = false;
2563 
2564  for (octave_idx_type i = 0; i < len; i++)
2565  {
2566  octave_quit ();
2567  float atmp = a(i);
2568  float btmp = b(i);
2569  if (atmp < 0.0 && ! xisint (btmp))
2570  {
2571  convert_to_complex = true;
2572  goto done;
2573  }
2574  }
2575 
2576 done:
2577 
2578  if (convert_to_complex)
2579  {
2580  FloatComplexNDArray complex_result (a_dims);
2581 
2582  for (octave_idx_type i = 0; i < len; i++)
2583  {
2584  octave_quit ();
2585  FloatComplex atmp (a(i));
2586  complex_result(i) = std::pow (atmp, b(i));
2587  }
2588 
2589  retval = complex_result;
2590  }
2591  else
2592  {
2593  FloatNDArray result (a_dims);
2594 
2595  for (octave_idx_type i = 0; i < len; i++)
2596  {
2597  octave_quit ();
2598  result(i) = std::pow (a(i), b(i));
2599  }
2600 
2601  retval = result;
2602  }
2603 
2604  return retval;
2605 }
2606 
2607 // -*- 5 -*-
2610 {
2611  FloatComplexNDArray result (a.dims ());
2612 
2613  for (octave_idx_type i = 0; i < a.numel (); i++)
2614  {
2615  octave_quit ();
2616  result(i) = std::pow (a(i), b);
2617  }
2618 
2619  return result;
2620 }
2621 
2622 // -*- 6 -*-
2625 {
2626  dim_vector a_dims = a.dims ();
2627  dim_vector b_dims = b.dims ();
2628 
2629  if (a_dims != b_dims)
2630  {
2631  if (! is_valid_bsxfun ("operator .^", a_dims, b_dims))
2632  octave::err_nonconformant ("operator .^", a_dims, b_dims);
2633 
2634  return bsxfun_pow (a, b);
2635  }
2636 
2637  FloatComplexNDArray result (a_dims);
2638 
2639  for (octave_idx_type i = 0; i < a.numel (); i++)
2640  {
2641  octave_quit ();
2642  result(i) = std::pow (a(i), b(i));
2643  }
2644 
2645  return result;
2646 }
2647 
2648 // -*- 7 -*-
2651 {
2652  FloatComplexNDArray result (b.dims ());
2653 
2654  for (octave_idx_type i = 0; i < b.numel (); i++)
2655  {
2656  octave_quit ();
2657  float btmp = b(i);
2658  if (xisint (btmp))
2659  result(i) = std::pow (a, static_cast<int> (btmp));
2660  else
2661  result(i) = std::pow (a, btmp);
2662  }
2663 
2664  return result;
2665 }
2666 
2667 // -*- 8 -*-
2670 {
2671  FloatComplexNDArray result (b.dims ());
2672 
2673  for (octave_idx_type i = 0; i < b.numel (); i++)
2674  {
2675  octave_quit ();
2676  result(i) = std::pow (a, b(i));
2677  }
2678 
2679  return result;
2680 }
2681 
2682 // -*- 9 -*-
2685 {
2686  FloatComplexNDArray result (a.dims ());
2687 
2688  if (xisint (b))
2689  {
2690  int bint = static_cast<int> (b);
2691  if (bint == -1)
2692  {
2693  for (octave_idx_type i = 0; i < a.numel (); i++)
2694  result.xelem (i) = 1.0f / a(i);
2695  }
2696  else
2697  {
2698  for (octave_idx_type i = 0; i < a.numel (); i++)
2699  {
2700  octave_quit ();
2701  result(i) = std::pow (a(i), bint);
2702  }
2703  }
2704  }
2705  else
2706  {
2707  for (octave_idx_type i = 0; i < a.numel (); i++)
2708  {
2709  octave_quit ();
2710  result(i) = std::pow (a(i), b);
2711  }
2712  }
2713 
2714  return result;
2715 }
2716 
2717 // -*- 10 -*-
2720 {
2721  dim_vector a_dims = a.dims ();
2722  dim_vector b_dims = b.dims ();
2723 
2724  if (a_dims != b_dims)
2725  {
2726  if (! is_valid_bsxfun ("operator .^", a_dims, b_dims))
2727  octave::err_nonconformant ("operator .^", a_dims, b_dims);
2728 
2729  return bsxfun_pow (a, b);
2730  }
2731 
2732  FloatComplexNDArray result (a_dims);
2733 
2734  for (octave_idx_type i = 0; i < a.numel (); i++)
2735  {
2736  octave_quit ();
2737  float btmp = b(i);
2738  if (xisint (btmp))
2739  result(i) = std::pow (a(i), static_cast<int> (btmp));
2740  else
2741  result(i) = std::pow (a(i), btmp);
2742  }
2743 
2744  return result;
2745 }
2746 
2747 // -*- 11 -*-
2750 {
2751  FloatComplexNDArray result (a.dims ());
2752 
2753  for (octave_idx_type i = 0; i < a.numel (); i++)
2754  {
2755  octave_quit ();
2756  result(i) = std::pow (a(i), b);
2757  }
2758 
2759  return result;
2760 }
2761 
2762 // -*- 12 -*-
2765 {
2766  dim_vector a_dims = a.dims ();
2767  dim_vector b_dims = b.dims ();
2768 
2769  if (a_dims != b_dims)
2770  {
2771  if (! is_valid_bsxfun ("operator .^", a_dims, b_dims))
2772  octave::err_nonconformant ("operator .^", a_dims, b_dims);
2773 
2774  return bsxfun_pow (a, b);
2775  }
2776 
2777  FloatComplexNDArray result (a_dims);
2778 
2779  for (octave_idx_type i = 0; i < a.numel (); i++)
2780  {
2781  octave_quit ();
2782  result(i) = std::pow (a(i), b(i));
2783  }
2784 
2785  return result;
2786 }
static void err_nonsquare_matrix(void)
Definition: xpow.cc:65
FloatNDArray octave_value_extract< FloatNDArray >(const octave_value &v)
Definition: ov.h:1669
octave_value elem_xpow(double a, const Matrix &b)
Definition: xpow.cc:645
T dgelem(octave_idx_type i) const
Definition: DiagArray2.h:122
#define C(a, b)
Definition: Faddeeva.cc:246
bool any_element_is_negative(bool=false) const
Definition: dNDArray.cc:539
bool is_valid_bsxfun(const std::string &name, const dim_vector &xdv, const dim_vector &ydv)
Definition: bsxfun.h:38
FloatComplexMatrix right_eigenvectors(void) const
Definition: fEIG.h:119
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE * f
bool all_elements_are_ints(void) const
Definition: Range.cc:39
Definition: EIG.h:35
Definition: Range.h:33
void error(const char *fmt,...)
Definition: error.cc:578
octave_idx_type b_nr
Definition: sylvester.cc:76
ComplexMatrix right_eigenvectors(void) const
Definition: EIG.h:119
static bool xisint(T x)
Definition: xpow.cc:73
double limit(void) const
Definition: Range.h:79
double base(void) const
Definition: Range.h:78
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:400
NDArray octave_value_extract< NDArray >(const octave_value &v)
Definition: ov.h:1668
done
Definition: syscalls.cc:251
octave_value xpow(double a, double b)
Definition: xpow.cc:95
Definition: fEIG.h:35
Matrix matrix_value(void) const
Definition: Range.cc:84
octave_idx_type numel(void) const
Definition: Range.h:85
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
octave_value retval
Definition: data.cc:6246
Definition: dMatrix.h:36
ComplexNDArray bsxfun_pow(const ComplexNDArray &x, const ComplexNDArray &y)
Definition: CNDArray.cc:898
With real return the complex result
Definition: data.cc:3260
FloatComplexColumnVector eigenvalues(void) const
Definition: fEIG.h:118
void warning(const char *fmt,...)
Definition: error.cc:801
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:227
F77_RET_T const F77_INT const F77_INT const F77_INT F77_DBLE const F77_INT F77_DBLE const F77_INT F77_DBLE * Q
This is a simple wrapper template that will subclass an Array<T> type or any later type derived from ...
Definition: Array.h:892
octave_idx_type b_nc
Definition: sylvester.cc:77
static bool same_sign(double a, double b)
Definition: xpow.cc:706
static void err_failed_diagonalization(void)
Definition: xpow.cc:59
b
Definition: cellfun.cc:400
ComplexColumnVector eigenvalues(void) const
Definition: EIG.h:118
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:141
for i
Definition: data.cc:5264
bool any_element_is_negative(bool=false) const
Definition: fNDArray.cc:491
std::complex< float > FloatComplex
Definition: oct-cmplx.h:32
std::complex< double > Complex
Definition: oct-cmplx.h:31
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:135
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
T x_nint(T x)
Definition: lo-mappers.h:284
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE * x
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:204
double inc(void) const
Definition: Range.h:80