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