GNU Octave  8.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
sparse-xpow.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1998-2023 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 "oct-cmplx.h"
36 #include "quit.h"
37 
38 #include "error.h"
39 #include "ovl.h"
40 #include "utils.h"
41 
42 #include "dSparse.h"
43 #include "CSparse.h"
44 #include "ov-re-sparse.h"
45 #include "ov-cx-sparse.h"
46 #include "sparse-xpow.h"
47 
49 
50 static inline bool
51 xisint (double x)
52 {
53  return (octave::math::x_nint (x) == x
54  && ((x >= 0 && x < std::numeric_limits<int>::max ())
55  || (x <= 0 && x > std::numeric_limits<int>::min ())));
56 }
57 
58 // Safer pow functions. Only two make sense for sparse matrices, the
59 // others should all promote to full matrices.
60 
62 xpow (const SparseMatrix& a, double b)
63 {
64  octave_value retval;
65 
66  octave_idx_type nr = a.rows ();
67  octave_idx_type nc = a.cols ();
68 
69  if (nr == 0 || nc == 0)
70  return SparseMatrix ();
71 
72  // If we are here, A is not empty ==> A needs to be square.
73  if (nr != nc)
74  error ("for A^b, A must be a square matrix. Use .^ for elementwise power.");
75 
76  if (! xisint (b))
77  error ("use full(a) ^ full(b)");
78 
79  int btmp = static_cast<int> (b);
80  if (btmp == 0)
81  {
82  SparseMatrix tmp = SparseMatrix (nr, nr, nr);
83  for (octave_idx_type i = 0; i < nr; i++)
84  {
85  tmp.data (i) = 1.0;
86  tmp.ridx (i) = i;
87  }
88  for (octave_idx_type i = 0; i < nr + 1; i++)
89  tmp.cidx (i) = i;
90 
91  retval = tmp;
92  }
93  else
94  {
95  SparseMatrix atmp;
96  if (btmp < 0)
97  {
98  btmp = -btmp;
99 
100  octave_idx_type info;
101  double rcond = 0.0;
102  MatrixType mattyp (a);
103 
104  // FIXME: This causes an error if the input sparse matrix is all-zeros.
105  // That behavior is inconsistent with A ^ b when A is a full all-zeros
106  // matrix, which just returns Inf of the same size with a warning.
107  atmp = a.inverse (mattyp, info, rcond, 1);
108 
109  if (info == -1)
110  warning ("inverse: matrix singular to machine precision, rcond = %g", rcond);
111  }
112  else
113  atmp = a;
114 
115  if (atmp.nnz () == 0) // Fast return for all-zeros matrix
116  return atmp;
117 
118  SparseMatrix result (atmp);
119 
120  btmp--;
121 
122  // There are two approaches to the actual exponentiation.
123  // Exponentiation by squaring uses only a logarithmic number
124  // of multiplications but the matrices it multiplies tend to be dense
125  // towards the end.
126  // Linear multiplication uses a linear number of multiplications
127  // but one of the matrices it uses will be as sparse as the original
128  // matrix.
129  //
130  // The time to multiply fixed-size matrices is strongly affected by their
131  // sparsity. Denser matrices take much longer to multiply together.
132  // See this URL for a worked-through example:
133  // https://octave.discourse.group/t/3216/4
134  //
135  // The tradeoff is between many fast multiplications or a few slow ones.
136  //
137  // Large exponents favor the squaring technique, and sparse matrices
138  // favor linear multiplication.
139  //
140  // We calculate a threshold based on the sparsity of the input
141  // and use squaring for exponents larger than that.
142  //
143  // FIXME: Improve this threshold calculation.
144 
145  uint64_t sparsity = atmp.numel () / atmp.nnz (); // reciprocal of density
146  int threshold = (sparsity >= 1000) ? 40
147  : (sparsity >= 100) ? 20
148  : 3;
149 
150  if (btmp > threshold) // use squaring technique
151  {
152  while (btmp > 0)
153  {
154  if (btmp & 1)
155  result = result * atmp;
156 
157  btmp >>= 1;
158 
159  if (btmp > 0)
160  atmp = atmp * atmp;
161  }
162  }
163  else // use linear multiplication
164  {
165  for (int i = 0; i < btmp; i++)
166  result = result * atmp;
167  }
168 
169  retval = result;
170  }
171 
172  return retval;
173 }
174 
176 xpow (const SparseComplexMatrix& a, double b)
177 {
178  octave_value retval;
179 
180  octave_idx_type nr = a.rows ();
181  octave_idx_type nc = a.cols ();
182 
183  if (nr == 0 || nc == 0)
184  return SparseMatrix ();
185 
186  // If we are here, A is not empty ==> A needs to be square.
187  if (nr != nc)
188  error ("for A^b, A must be a square matrix. Use .^ for elementwise power.");
189 
190  if (! xisint (b))
191  error ("use full(a) ^ full(b)");
192 
193  int btmp = static_cast<int> (b);
194  if (btmp == 0)
195  {
196  SparseMatrix tmp = SparseMatrix (nr, nr, nr);
197  for (octave_idx_type i = 0; i < nr; i++)
198  {
199  tmp.data (i) = 1.0;
200  tmp.ridx (i) = i;
201  }
202  for (octave_idx_type i = 0; i < nr + 1; i++)
203  tmp.cidx (i) = i;
204 
205  retval = tmp;
206  }
207  else
208  {
209  SparseComplexMatrix atmp;
210  if (btmp < 0)
211  {
212  btmp = -btmp;
213 
214  octave_idx_type info;
215  double rcond = 0.0;
216  MatrixType mattyp (a);
217 
218  atmp = a.inverse (mattyp, info, rcond, 1);
219 
220  if (info == -1)
221  warning ("inverse: matrix singular to machine precision, rcond = %g", rcond);
222  }
223  else
224  atmp = a;
225 
226  if (atmp.nnz () == 0) // Fast return for all-zeros matrix
227  return atmp;
228 
229  SparseComplexMatrix result (atmp);
230 
231  btmp--;
232 
233  // Select multiplication sequence based on sparsity of atmp.
234  // See the long comment in xpow (const SparseMatrix& a, double b)
235  // for more details.
236  //
237  // FIXME: Improve this threshold calculation.
238 
239  uint64_t sparsity = atmp.numel () / atmp.nnz (); // reciprocal of density
240  int threshold = (sparsity >= 1000) ? 40
241  : (sparsity >= 100) ? 20
242  : 3;
243 
244  if (btmp > threshold) // use squaring technique
245  {
246  while (btmp > 0)
247  {
248  if (btmp & 1)
249  result = result * atmp;
250 
251  btmp >>= 1;
252 
253  if (btmp > 0)
254  atmp = atmp * atmp;
255  }
256  }
257  else // use linear multiplication
258  {
259  for (int i = 0; i < btmp; i++)
260  result = result * atmp;
261  }
262 
263  retval = result;
264  }
265 
266  return retval;
267 }
268 
269 // Safer pow functions that work elementwise for matrices.
270 //
271 // op2 \ op1: s m cs cm
272 // +-- +---+---+----+----+
273 // scalar | | * | 3 | * | 9 |
274 // +---+---+----+----+
275 // matrix | 1 | 4 | 7 | 10 |
276 // +---+---+----+----+
277 // complex_scalar | * | 5 | * | 11 |
278 // +---+---+----+----+
279 // complex_matrix | 2 | 6 | 8 | 12 |
280 // +---+---+----+----+
281 //
282 // * -> not needed.
283 
284 // FIXME: these functions need to be fixed so that things
285 // like
286 //
287 // a = -1; b = [ 0, 0.5, 1 ]; r = a .^ b
288 //
289 // and
290 //
291 // a = -1; b = [ 0, 0.5, 1 ]; for i = 1:3, r(i) = a .^ b(i), end
292 //
293 // produce identical results. Also, it would be nice if -1^0.5
294 // produced a pure imaginary result instead of a complex number with a
295 // small real part. But perhaps that's really a problem with the math
296 // library...
297 
298 // Handle special case of scalar-sparse-matrix .^ sparse-matrix.
299 // Forwarding to the scalar elem_xpow function and then converting the
300 // result back to a sparse matrix is a bit wasteful but it does not
301 // seem worth the effort to optimize -- how often does this case come up
302 // in practice?
303 
304 template <typename S, typename SM>
305 inline octave_value
306 scalar_xpow (const S& a, const SM& b)
307 {
308  octave_value val = elem_xpow (a, b);
309 
310  if (val.iscomplex ())
312  else
313  return SparseMatrix (val.matrix_value ());
314 }
315 
316 /*
317 %!assert (sparse (2) .^ [3, 4], sparse ([8, 16]))
318 %!assert <47775> (sparse (2i) .^ [3, 4], sparse ([-0-8i, 16]))
319 
320 %!test <*63080>
321 %! Z = sparse ([]);
322 %! A = sparse (zeros (0, 2));
323 %! B = sparse (zeros (2, 0));
324 %! assert (Z ^ 1, Z);
325 %! assert (Z ^ 0, Z);
326 %! assert (Z ^ -1, Z);
327 %! assert (A ^ 1, Z);
328 %! assert (A ^ 0, Z);
329 %! assert (A ^ -1, Z);
330 %! assert (B ^ 1, Z);
331 %! assert (B ^ 0, Z);
332 %! assert (B ^ -1, Z);
333 
334 %!test <*63080>
335 %! A = sparse (zeros (2, 2));
336 %! assert (A ^ 1, A);
337 %! assert (A ^ 0, sparse (eye (2, 2)));
338 
339 %!test <63080>
340 %! A = sparse (zeros (2, 2));
341 %! assert (A ^ -1, sparse (inf (2, 2)));
342 
343 */
344 
345 // -*- 1 -*-
347 elem_xpow (double a, const SparseMatrix& b)
348 {
349  octave_value retval;
350 
351  octave_idx_type nr = b.rows ();
352  octave_idx_type nc = b.cols ();
353 
354  double d1, d2;
355 
356  if (a < 0.0 && ! b.all_integers (d1, d2))
357  {
358  Complex atmp (a);
359  ComplexMatrix result (nr, nc);
360 
361  for (octave_idx_type j = 0; j < nc; j++)
362  {
363  for (octave_idx_type i = 0; i < nr; i++)
364  {
365  octave_quit ();
366  result(i, j) = std::pow (atmp, b(i, j));
367  }
368  }
369 
370  retval = result;
371  }
372  else
373  {
374  Matrix result (nr, nc);
375 
376  for (octave_idx_type j = 0; j < nc; j++)
377  {
378  for (octave_idx_type i = 0; i < nr; i++)
379  {
380  octave_quit ();
381  result(i, j) = std::pow (a, b(i, j));
382  }
383  }
384 
385  retval = result;
386  }
387 
388  return retval;
389 }
390 
391 // -*- 2 -*-
393 elem_xpow (double a, const SparseComplexMatrix& b)
394 {
395  octave_idx_type nr = b.rows ();
396  octave_idx_type nc = b.cols ();
397 
398  Complex atmp (a);
399  ComplexMatrix result (nr, nc);
400 
401  for (octave_idx_type j = 0; j < nc; j++)
402  {
403  for (octave_idx_type i = 0; i < nr; i++)
404  {
405  octave_quit ();
406  result(i, j) = std::pow (atmp, b(i, j));
407  }
408  }
409 
410  return result;
411 }
412 
413 // -*- 3 -*-
415 elem_xpow (const SparseMatrix& a, double b)
416 {
417  // FIXME: What should a .^ 0 give? Matlab gives a
418  // sparse matrix with same structure as a, which is strictly
419  // incorrect. Keep compatibility.
420 
421  octave_value retval;
422 
423  octave_idx_type nz = a.nnz ();
424 
425  if (b <= 0.0)
426  {
427  octave_idx_type nr = a.rows ();
428  octave_idx_type nc = a.cols ();
429 
430  if (! xisint (b) && a.any_element_is_negative ())
431  {
432  ComplexMatrix result (nr, nc, Complex (std::pow (0.0, b)));
433 
434  // FIXME: avoid apparent GNU libm bug by
435  // converting A and B to complex instead of just A.
436  Complex btmp (b);
437 
438  for (octave_idx_type j = 0; j < nc; j++)
439  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
440  {
441  octave_quit ();
442 
443  Complex atmp (a.data (i));
444 
445  result(a.ridx (i), j) = std::pow (atmp, btmp);
446  }
447 
448  retval = octave_value (result);
449  }
450  else
451  {
452  Matrix result (nr, nc, (std::pow (0.0, b)));
453 
454  for (octave_idx_type j = 0; j < nc; j++)
455  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
456  {
457  octave_quit ();
458  result(a.ridx (i), j) = std::pow (a.data (i), b);
459  }
460 
461  retval = octave_value (result);
462  }
463  }
464  else if (! xisint (b) && a.any_element_is_negative ())
465  {
466  SparseComplexMatrix result (a);
467 
468  for (octave_idx_type i = 0; i < nz; i++)
469  {
470  octave_quit ();
471 
472  // FIXME: avoid apparent GNU libm bug by
473  // converting A and B to complex instead of just A.
474 
475  Complex atmp (a.data (i));
476  Complex btmp (b);
477 
478  result.data (i) = std::pow (atmp, btmp);
479  }
480 
481  result.maybe_compress (true);
482 
483  retval = result;
484  }
485  else
486  {
487  SparseMatrix result (a);
488 
489  for (octave_idx_type i = 0; i < nz; i++)
490  {
491  octave_quit ();
492  result.data (i) = std::pow (a.data (i), b);
493  }
494 
495  result.maybe_compress (true);
496 
497  retval = result;
498  }
499 
500  return retval;
501 }
502 
503 // -*- 4 -*-
505 elem_xpow (const SparseMatrix& a, const SparseMatrix& b)
506 {
507  octave_value retval;
508 
509  octave_idx_type nr = a.rows ();
510  octave_idx_type nc = a.cols ();
511 
512  octave_idx_type b_nr = b.rows ();
513  octave_idx_type b_nc = b.cols ();
514 
515  if (a.numel () == 1 && b.numel () > 1)
516  return scalar_xpow (a(0), b);
517 
518  if (nr != b_nr || nc != b_nc)
519  octave::err_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
520 
521  int convert_to_complex = 0;
522  for (octave_idx_type j = 0; j < nc; j++)
523  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
524  {
525  if (a.data(i) < 0.0)
526  {
527  double btmp = b (a.ridx (i), j);
528  if (! xisint (btmp))
529  {
530  convert_to_complex = 1;
531  goto done;
532  }
533  }
534  }
535 
536 done:
537 
538  // This is a dumb operator for sparse matrices anyway, and there is
539  // no sensible way to handle the 0.^0 versus the 0.^x cases. Therefore
540  // allocate a full matrix filled for the 0.^0 case and shrink it later
541  // as needed.
542 
543  if (convert_to_complex)
544  {
545  SparseComplexMatrix complex_result (nr, nc, Complex (1.0, 0.0));
546 
547  for (octave_idx_type j = 0; j < nc; j++)
548  {
549  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
550  {
551  octave_quit ();
552  complex_result.xelem (a.ridx (i), j)
553  = std::pow (Complex (a.data (i)), Complex (b(a.ridx (i), j)));
554  }
555  }
556  complex_result.maybe_compress (true);
557  retval = complex_result;
558  }
559  else
560  {
561  SparseMatrix result (nr, nc, 1.0);
562 
563  for (octave_idx_type j = 0; j < nc; j++)
564  {
565  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
566  {
567  octave_quit ();
568  result.xelem (a.ridx (i), j) = std::pow (a.data (i),
569  b(a.ridx (i), j));
570  }
571  }
572  result.maybe_compress (true);
573  retval = result;
574  }
575 
576  return retval;
577 }
578 
579 // -*- 5 -*-
581 elem_xpow (const SparseMatrix& a, const Complex& b)
582 {
583  octave_value retval;
584 
585  if (b == 0.0)
586  // Can this case ever happen, due to automatic retyping with maybe_mutate?
587  retval = octave_value (NDArray (a.dims (), 1));
588  else
589  {
590  octave_idx_type nz = a.nnz ();
591  SparseComplexMatrix result (a);
592 
593  for (octave_idx_type i = 0; i < nz; i++)
594  {
595  octave_quit ();
596  result.data (i) = std::pow (Complex (a.data (i)), b);
597  }
598 
599  result.maybe_compress (true);
600 
601  retval = result;
602  }
603 
604  return retval;
605 }
606 
607 // -*- 6 -*-
610 {
611  octave_idx_type nr = a.rows ();
612  octave_idx_type nc = a.cols ();
613 
614  octave_idx_type b_nr = b.rows ();
615  octave_idx_type b_nc = b.cols ();
616 
617  if (a.numel () == 1 && b.numel () > 1)
618  return scalar_xpow (a(0), b);
619 
620  if (nr != b_nr || nc != b_nc)
621  octave::err_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
622 
623  SparseComplexMatrix result (nr, nc, Complex (1.0, 0.0));
624  for (octave_idx_type j = 0; j < nc; j++)
625  {
626  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
627  {
628  octave_quit ();
629  result.xelem (a.ridx(i), j) = std::pow (a.data (i), b(a.ridx (i), j));
630  }
631  }
632 
633  result.maybe_compress (true);
634 
635  return result;
636 }
637 
638 // -*- 7 -*-
640 elem_xpow (const Complex& a, const SparseMatrix& b)
641 {
642  octave_idx_type nr = b.rows ();
643  octave_idx_type nc = b.cols ();
644 
645  ComplexMatrix result (nr, nc);
646 
647  for (octave_idx_type j = 0; j < nc; j++)
648  {
649  for (octave_idx_type i = 0; i < nr; i++)
650  {
651  octave_quit ();
652  double btmp = b (i, j);
653  if (xisint (btmp))
654  result (i, j) = std::pow (a, static_cast<int> (btmp));
655  else
656  result (i, j) = std::pow (a, btmp);
657  }
658  }
659 
660  return result;
661 }
662 
663 // -*- 8 -*-
666 {
667  octave_idx_type nr = b.rows ();
668  octave_idx_type nc = b.cols ();
669 
670  ComplexMatrix result (nr, nc);
671  for (octave_idx_type j = 0; j < nc; j++)
672  for (octave_idx_type i = 0; i < nr; i++)
673  {
674  octave_quit ();
675  result (i, j) = std::pow (a, b (i, j));
676  }
677 
678  return result;
679 }
680 
681 // -*- 9 -*-
683 elem_xpow (const SparseComplexMatrix& a, double b)
684 {
685  octave_value retval;
686 
687  if (b <= 0)
688  {
689  octave_idx_type nr = a.rows ();
690  octave_idx_type nc = a.cols ();
691 
692  ComplexMatrix result (nr, nc, Complex (std::pow (0.0, b)));
693 
694  if (xisint (b))
695  {
696  for (octave_idx_type j = 0; j < nc; j++)
697  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
698  {
699  octave_quit ();
700  result (a.ridx (i), j)
701  = std::pow (a.data (i), static_cast<int> (b));
702  }
703  }
704  else
705  {
706  for (octave_idx_type j = 0; j < nc; j++)
707  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
708  {
709  octave_quit ();
710  result (a.ridx (i), j) = std::pow (a.data (i), b);
711  }
712  }
713 
714  retval = result;
715  }
716  else
717  {
718  octave_idx_type nz = a.nnz ();
719 
720  SparseComplexMatrix result (a);
721 
722  if (xisint (b))
723  {
724  for (octave_idx_type i = 0; i < nz; i++)
725  {
726  octave_quit ();
727  result.data (i) = std::pow (a.data (i), static_cast<int> (b));
728  }
729  }
730  else
731  {
732  for (octave_idx_type i = 0; i < nz; i++)
733  {
734  octave_quit ();
735  result.data (i) = std::pow (a.data (i), b);
736  }
737  }
738 
739  result.maybe_compress (true);
740 
741  retval = result;
742  }
743 
744  return retval;
745 }
746 
747 // -*- 10 -*-
750 {
751  octave_idx_type nr = a.rows ();
752  octave_idx_type nc = a.cols ();
753 
754  octave_idx_type b_nr = b.rows ();
755  octave_idx_type b_nc = b.cols ();
756 
757  if (a.numel () == 1 && b.numel () > 1)
758  return scalar_xpow (a(0), b);
759 
760  if (nr != b_nr || nc != b_nc)
761  octave::err_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
762 
763  SparseComplexMatrix result (nr, nc, Complex (1.0, 0.0));
764  for (octave_idx_type j = 0; j < nc; j++)
765  {
766  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
767  {
768  octave_quit ();
769  double btmp = b(a.ridx (i), j);
770 
771  if (xisint (btmp))
772  result.xelem (a.ridx (i), j) = std::pow (a.data (i),
773  static_cast<int> (btmp));
774  else
775  result.xelem (a.ridx (i), j) = std::pow (a.data (i), btmp);
776  }
777  }
778 
779  result.maybe_compress (true);
780 
781  return result;
782 }
783 
784 // -*- 11 -*-
787 {
788  octave_value retval;
789 
790  if (b == 0.0)
791  // Can this case ever happen, due to automatic retyping with maybe_mutate?
792  retval = octave_value (NDArray (a.dims (), 1));
793  else
794  {
795 
796  octave_idx_type nz = a.nnz ();
797 
798  SparseComplexMatrix result (a);
799 
800  for (octave_idx_type i = 0; i < nz; i++)
801  {
802  octave_quit ();
803  result.data (i) = std::pow (a.data (i), b);
804  }
805 
806  result.maybe_compress (true);
807 
808  retval = result;
809  }
810 
811  return retval;
812 }
813 
814 // -*- 12 -*-
817 {
818  octave_idx_type nr = a.rows ();
819  octave_idx_type nc = a.cols ();
820 
821  octave_idx_type b_nr = b.rows ();
822  octave_idx_type b_nc = b.cols ();
823 
824  if (a.numel () == 1 && b.numel () > 1)
825  return scalar_xpow (a(0), b);
826 
827  if (nr != b_nr || nc != b_nc)
828  octave::err_nonconformant ("operator .^", nr, nc, b_nr, b_nc);
829 
830  SparseComplexMatrix result (nr, nc, Complex (1.0, 0.0));
831  for (octave_idx_type j = 0; j < nc; j++)
832  {
833  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
834  {
835  octave_quit ();
836  result.xelem (a.ridx (i), j) = std::pow (a.data (i),
837  b(a.ridx (i), j));
838  }
839  }
840  result.maybe_compress (true);
841 
842  return result;
843 }
844 
845 
OCTAVE_END_NAMESPACE(octave)
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:230
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
Definition: dMatrix.h:42
OCTAVE_API SparseComplexMatrix inverse(void) const
Definition: CSparse.cc:660
OCTAVE_API bool all_integers(double &max_val, double &min_val) const
Definition: dSparse.cc:7296
OCTAVE_API SparseMatrix inverse(void) const
Definition: dSparse.cc:603
OCTAVE_API bool any_element_is_negative(bool=false) const
Definition: dSparse.cc:7198
octave_idx_type rows(void) const
Definition: Sparse.h:351
octave_idx_type * cidx(void)
Definition: Sparse.h:596
octave_idx_type * ridx(void)
Definition: Sparse.h:583
T * data(void)
Definition: Sparse.h:574
octave_idx_type nnz(void) const
Actual number of nonzero terms.
Definition: Sparse.h:339
dim_vector dims(void) const
Definition: Sparse.h:371
Sparse< T, Alloc > maybe_compress(bool remove_zeros=false)
Definition: Sparse.h:531
T & xelem(octave_idx_type n)
Definition: Sparse.h:395
octave_idx_type cols(void) const
Definition: Sparse.h:352
octave_idx_type numel(void) const
Definition: Sparse.h:343
ComplexMatrix complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:916
Matrix matrix_value(bool frc_str_conv=false) const
Definition: ov.h:898
bool iscomplex(void) const
Definition: ov.h:786
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void warning(const char *fmt,...)
Definition: error.cc:1054
void error(const char *fmt,...)
Definition: error.cc:979
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
T x_nint(T x)
Definition: lo-mappers.h:269
F77_RET_T const F77_DBLE * x
class OCTAVE_API SparseMatrix
Definition: mx-fwd.h:55
class OCTAVE_API SparseComplexMatrix
Definition: mx-fwd.h:56
std::complex< double > Complex
Definition: oct-cmplx.h:33
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()) ? '\'' :'"'))
octave_value xpow(const SparseMatrix &a, double b)
Definition: sparse-xpow.cc:62
octave_value elem_xpow(double a, const SparseMatrix &b)
Definition: sparse-xpow.cc:347
octave_value scalar_xpow(const S &a, const SM &b)
Definition: sparse-xpow.cc:306
static bool xisint(double x)
Definition: sparse-xpow.cc:51