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