GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
MatrixType.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2006-2018 David Bateman
4 Copyright (C) 2006 Andy Adler
5 Copyright (C) 2009 VZLU Prague
6 
7 This file is part of Octave.
8 
9 Octave is free software: you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Octave; see the file COPYING. If not, see
21 <https://www.gnu.org/licenses/>.
22 
23 */
24 
25 #if defined (HAVE_CONFIG_H)
26 # include "config.h"
27 #endif
28 
29 #include <vector>
30 
31 #include "MatrixType.h"
32 #include "dMatrix.h"
33 #include "fMatrix.h"
34 #include "CMatrix.h"
35 #include "fCMatrix.h"
36 #include "dSparse.h"
37 #include "CSparse.h"
38 #include "oct-spparms.h"
39 #include "oct-locbuf.h"
40 
41 static void
43 {
44  (*current_liboctave_warning_with_id_handler)
45  ("Octave:matrix-type-info", "using cached matrix type");
46 }
47 
48 static void
50 {
51  (*current_liboctave_warning_with_id_handler)
52  ("Octave:matrix-type-info", "invalid matrix type");
53 }
54 
55 static void
57 {
58  (*current_liboctave_warning_with_id_handler)
59  ("Octave:matrix-type-info", "calculating sparse matrix type");
60 }
61 
62 // FIXME: There is a large code duplication here
63 
65  : typ (MatrixType::Unknown),
66  sp_bandden (octave_sparse_params::get_bandden ()),
67  bandden (0), upper_band (0),
68  lower_band (0), dense (false), full (false), nperm (0), perm (nullptr) { }
69 
71  : typ (a.typ), sp_bandden (a.sp_bandden), bandden (a.bandden),
72  upper_band (a.upper_band), lower_band (a.lower_band),
73  dense (a.dense), full (a.full), nperm (a.nperm), perm (nullptr)
74 {
75  if (nperm != 0)
76  {
77  perm = new octave_idx_type [nperm];
78  for (octave_idx_type i = 0; i < nperm; i++)
79  perm[i] = a.perm[i];
80  }
81 }
82 
83 template <typename T>
86 {
88  octave_idx_type nrows = a.rows ();
89  octave_idx_type ncols = a.cols ();
90 
91  const T zero = 0;
92 
93  if (ncols == nrows)
94  {
95  bool upper = true;
96  bool lower = true;
97  bool hermitian = true;
98 
99  // do the checks for lower/upper/hermitian all in one pass.
100  OCTAVE_LOCAL_BUFFER (T, diag, ncols);
101 
102  for (octave_idx_type j = 0;
103  j < ncols && upper; j++)
104  {
105  T d = a.elem (j,j);
106  upper = upper && (d != zero);
107  lower = lower && (d != zero);
108  hermitian = hermitian && (d > zero);
109  diag[j] = d;
110  }
111 
112  for (octave_idx_type j = 0;
113  j < ncols && (upper || lower || hermitian); j++)
114  {
115  for (octave_idx_type i = 0; i < j; i++)
116  {
117  double aij = a.elem (i,j);
118  double aji = a.elem (j,i);
119  lower = lower && (aij == zero);
120  upper = upper && (aji == zero);
121  hermitian = hermitian && (aij == aji
122  && aij*aij < diag[i]*diag[j]);
123  }
124  }
125 
126  if (upper)
127  typ = MatrixType::Upper;
128  else if (lower)
129  typ = MatrixType::Lower;
130  else if (hermitian)
131  typ = MatrixType::Hermitian;
132  else
133  typ = MatrixType::Full;
134  }
135  else
137 
138  return typ;
139 }
140 
141 template <typename T>
143 matrix_complex_probe (const MArray<std::complex<T>>& a)
144 {
146  octave_idx_type nrows = a.rows ();
147  octave_idx_type ncols = a.cols ();
148 
149  const T zero = 0;
150  // get the real type
151 
152  if (ncols == nrows)
153  {
154  bool upper = true;
155  bool lower = true;
156  bool hermitian = true;
157 
158  // do the checks for lower/upper/hermitian all in one pass.
159  OCTAVE_LOCAL_BUFFER (T, diag, ncols);
160 
161  for (octave_idx_type j = 0;
162  j < ncols && upper; j++)
163  {
164  std::complex<T> d = a.elem (j,j);
165  upper = upper && (d != zero);
166  lower = lower && (d != zero);
167  hermitian = hermitian && (d.real () > zero && d.imag () == zero);
168  diag[j] = d.real ();
169  }
170 
171  for (octave_idx_type j = 0;
172  j < ncols && (upper || lower || hermitian); j++)
173  {
174  for (octave_idx_type i = 0; i < j; i++)
175  {
176  std::complex<T> aij = a.elem (i,j);
177  std::complex<T> aji = a.elem (j,i);
178  lower = lower && (aij == zero);
179  upper = upper && (aji == zero);
180  hermitian = hermitian && (aij == octave::math::conj (aji)
181  && std::norm (aij) < diag[i]*diag[j]);
182  }
183  }
184 
185  if (upper)
186  typ = MatrixType::Upper;
187  else if (lower)
188  typ = MatrixType::Lower;
189  else if (hermitian)
190  typ = MatrixType::Hermitian;
191  else if (ncols == nrows)
192  typ = MatrixType::Full;
193  }
194  else
196 
197  return typ;
198 }
199 
201  : typ (MatrixType::Unknown),
202  sp_bandden (0), bandden (0), upper_band (0), lower_band (0),
203  dense (false), full (true), nperm (0), perm (nullptr)
204 {
205  typ = matrix_real_probe (a);
206 }
207 
209  : typ (MatrixType::Unknown),
210  sp_bandden (0), bandden (0), upper_band (0), lower_band (0),
211  dense (false), full (true), nperm (0), perm (nullptr)
212 {
214 }
215 
217  : typ (MatrixType::Unknown),
218  sp_bandden (0), bandden (0), upper_band (0), lower_band (0),
219  dense (false), full (true), nperm (0), perm (nullptr)
220 {
221  typ = matrix_real_probe (a);
222 }
223 
225  : typ (MatrixType::Unknown),
226  sp_bandden (0), bandden (0), upper_band (0), lower_band (0),
227  dense (false), full (true), nperm (0), perm (nullptr)
228 {
230 }
231 
232 
233 template <typename T>
235  : typ (MatrixType::Unknown),
236  sp_bandden (0), bandden (0), upper_band (0), lower_band (0),
237  dense (false), full (false), nperm (0), perm (nullptr)
238 {
239  octave_idx_type nrows = a.rows ();
240  octave_idx_type ncols = a.cols ();
241  octave_idx_type nm = (ncols < nrows ? ncols : nrows);
242  octave_idx_type nnz = a.nnz ();
243 
244  if (octave_sparse_params::get_key ("spumoni") != 0.)
246 
248  bool maybe_hermitian = false;
250 
251  if (nnz == nm)
252  {
255  // Maybe the matrix is diagonal
256  for (i = 0; i < nm; i++)
257  {
258  if (a.cidx (i+1) != a.cidx (i) + 1)
259  {
260  tmp_typ = MatrixType::Full;
261  break;
262  }
263  if (a.ridx (i) != i)
264  {
266  break;
267  }
268  }
269 
270  if (tmp_typ == MatrixType::Permuted_Diagonal)
271  {
272  std::vector<bool> found (nrows);
273 
274  for (octave_idx_type j = 0; j < i; j++)
275  found[j] = true;
276  for (octave_idx_type j = i; j < nrows; j++)
277  found[j] = false;
278 
279  for (octave_idx_type j = i; j < nm; j++)
280  {
281  if ((a.cidx (j+1) > a.cidx (j) + 1)
282  || ((a.cidx (j+1) == a.cidx (j) + 1) && found[a.ridx (j)]))
283  {
284  tmp_typ = MatrixType::Full;
285  break;
286  }
287  found[a.ridx (j)] = true;
288  }
289  }
290  typ = tmp_typ;
291  }
292 
293  if (typ == MatrixType::Full)
294  {
295  // Search for banded, upper and lower triangular matrices
296  bool singular = false;
297  upper_band = 0;
298  lower_band = 0;
299  for (octave_idx_type j = 0; j < ncols; j++)
300  {
301  bool zero_on_diagonal = false;
302  if (j < nrows)
303  {
304  zero_on_diagonal = true;
305  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
306  if (a.ridx (i) == j)
307  {
308  zero_on_diagonal = false;
309  break;
310  }
311  }
312 
313  if (zero_on_diagonal)
314  {
315  singular = true;
316  break;
317  }
318 
319  if (a.cidx (j+1) != a.cidx (j))
320  {
321  octave_idx_type ru = a.ridx (a.cidx (j));
322  octave_idx_type rl = a.ridx (a.cidx (j+1)-1);
323 
324  if (j - ru > upper_band)
325  upper_band = j - ru;
326 
327  if (rl - j > lower_band)
328  lower_band = rl - j;
329  }
330  }
331 
332  if (! singular)
333  {
334  bandden = double (nnz) /
335  (double (ncols) * (double (lower_band) +
336  double (upper_band)) -
337  0.5 * double (upper_band + 1) * double (upper_band) -
338  0.5 * double (lower_band + 1) * double (lower_band));
339 
340  if (nrows == ncols && sp_bandden != 1. && bandden > sp_bandden)
341  {
342  if (upper_band == 1 && lower_band == 1)
344  else
346 
347  octave_idx_type nnz_in_band =
348  (upper_band + lower_band + 1) * nrows -
349  (1 + upper_band) * upper_band / 2 -
350  (1 + lower_band) * lower_band / 2;
351  if (nnz_in_band == nnz)
352  dense = true;
353  else
354  dense = false;
355  }
356 
357  // If a matrix is Banded but also Upper/Lower, set to the latter.
358  if (upper_band == 0)
360  else if (lower_band == 0)
362 
363  if (upper_band == lower_band && nrows == ncols)
364  maybe_hermitian = true;
365  }
366 
367  if (typ == MatrixType::Full)
368  {
369  // Search for a permuted triangular matrix, and test if
370  // permutation is singular
371 
372  // FIXME: Perhaps this should be based on a dmperm algorithm?
373  bool found = false;
374 
375  nperm = ncols;
376  perm = new octave_idx_type [ncols];
377 
378  for (octave_idx_type i = 0; i < ncols; i++)
379  perm[i] = -1;
380 
381  for (octave_idx_type i = 0; i < nm; i++)
382  {
383  found = false;
384 
385  for (octave_idx_type j = 0; j < ncols; j++)
386  {
387  if ((a.cidx (j+1) - a.cidx (j)) > 0
388  && (a.ridx (a.cidx (j+1)-1) == i))
389  {
390  perm[i] = j;
391  found = true;
392  break;
393  }
394  }
395 
396  if (! found)
397  break;
398  }
399 
400  if (found)
401  {
403  if (ncols > nrows)
404  {
405  octave_idx_type k = nrows;
406  for (octave_idx_type i = 0; i < ncols; i++)
407  if (perm[i] == -1)
408  perm[i] = k++;
409  }
410  }
411  else if (a.cidx (nm) == a.cidx (ncols))
412  {
413  nperm = nrows;
414  delete [] perm;
415  perm = new octave_idx_type [nrows];
417 
418  for (octave_idx_type i = 0; i < nrows; i++)
419  {
420  perm[i] = -1;
421  tmp[i] = -1;
422  }
423 
424  for (octave_idx_type j = 0; j < ncols; j++)
425  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
426  perm[a.ridx (i)] = j;
427 
428  found = true;
429  for (octave_idx_type i = 0; i < nm; i++)
430  if (perm[i] == -1)
431  {
432  found = false;
433  break;
434  }
435  else
436  {
437  tmp[perm[i]] = 1;
438  }
439 
440  if (found)
441  {
442  octave_idx_type k = ncols;
443  for (octave_idx_type i = 0; i < nrows; i++)
444  {
445  if (tmp[i] == -1)
446  {
447  if (k < nrows)
448  {
449  perm[k++] = i;
450  }
451  else
452  {
453  found = false;
454  break;
455  }
456  }
457  }
458  }
459 
460  if (found)
462  else
463  {
464  delete [] perm;
465  nperm = 0;
466  }
467  }
468  else
469  {
470  delete [] perm;
471  nperm = 0;
472  }
473  }
474 
475  // FIXME: Disable lower under-determined and upper over-determined
476  // problems as being detected, and force to treat as singular
477  // as this seems to cause issues.
479  && nrows > ncols)
481  && nrows < ncols))
482  {
485  delete [] perm;
486  nperm = 0;
488  }
489 
490  if (typ == MatrixType::Full && ncols != nrows)
492 
493  if (maybe_hermitian && (typ == MatrixType::Full
495  || typ == MatrixType::Banded))
496  {
497  bool is_herm = true;
498 
499  // first, check whether the diagonal is positive & extract it
500  ColumnVector diag (ncols);
501 
502  for (octave_idx_type j = 0; is_herm && j < ncols; j++)
503  {
504  is_herm = false;
505  for (octave_idx_type i = a.cidx (j); i < a.cidx (j+1); i++)
506  {
507  if (a.ridx (i) == j)
508  {
509  T d = a.data (i);
510  is_herm = (std::real (d) > 0.0
511  && std::imag (d) == 0.0);
512  diag(j) = std::real (d);
513  break;
514  }
515  }
516  }
517 
518  // next, check symmetry and 2x2 positiveness
519 
520  for (octave_idx_type j = 0; is_herm && j < ncols; j++)
521  for (octave_idx_type i = a.cidx (j); is_herm && i < a.cidx (j+1); i++)
522  {
523  octave_idx_type k = a.ridx (i);
524  is_herm = k == j;
525  if (is_herm)
526  continue;
527 
528  T d = a.data (i);
529  if (std::norm (d) < diag(j)*diag(k))
530  {
531  d = octave::math::conj (d);
532  for (octave_idx_type l = a.cidx (k); l < a.cidx (k+1); l++)
533  {
534  if (a.ridx (l) == j)
535  {
536  is_herm = a.data (l) == d;
537  break;
538  }
539  }
540  }
541  }
542 
543  if (is_herm)
544  {
545  if (typ == MatrixType::Full)
547  else if (typ == MatrixType::Banded)
549  else
551  }
552  }
553  }
554 }
555 
556 
558  : typ (MatrixType::Unknown),
559  sp_bandden (octave_sparse_params::get_bandden ()),
560  bandden (0), upper_band (0), lower_band (0),
561  dense (false), full (_full), nperm (0), perm (nullptr)
562 {
568  typ = t;
569  else
570  warn_invalid ();
571 }
572 
574  const octave_idx_type *p, bool _full)
575  : typ (MatrixType::Unknown),
576  sp_bandden (octave_sparse_params::get_bandden ()),
577  bandden (0), upper_band (0), lower_band (0),
578  dense (false), full (_full), nperm (0), perm (nullptr)
579 {
581  && np > 0 && p != nullptr)
582  {
583  typ = t;
584  nperm = np;
585  perm = new octave_idx_type [nperm];
586  for (octave_idx_type i = 0; i < nperm; i++)
587  perm[i] = p[i];
588  }
589  else
590  warn_invalid ();
591 }
592 
594  const octave_idx_type kl, bool _full)
595  : typ (MatrixType::Unknown),
596  sp_bandden (octave_sparse_params::get_bandden ()),
597  bandden (0), upper_band (0), lower_band (0),
598  dense (false), full (_full), nperm (0), perm (nullptr)
599 {
601  {
602  typ = t;
603  upper_band = ku;
604  lower_band = kl;
605  }
606  else
607  warn_invalid ();
608 }
609 
611 {
612  if (nperm != 0)
613  {
614  delete [] perm;
615  }
616 }
617 
618 MatrixType&
620 {
621  if (this != &a)
622  {
623  typ = a.typ;
624  sp_bandden = a.sp_bandden;
625  bandden = a.bandden;
626  upper_band = a.upper_band;
627  lower_band = a.lower_band;
628  dense = a.dense;
629  full = a.full;
630 
631  if (nperm)
632  {
633  delete[] perm;
634  }
635 
636  if (a.nperm != 0)
637  {
638  perm = new octave_idx_type [a.nperm];
639  for (octave_idx_type i = 0; i < a.nperm; i++)
640  perm[i] = a.perm[i];
641  }
642 
643  nperm = a.nperm;
644  }
645 
646  return *this;
647 }
648 
649 int
650 MatrixType::type (bool quiet)
651 {
652  if (typ != MatrixType::Unknown
654  {
655  if (! quiet && octave_sparse_params::get_key ("spumoni") != 0.)
656  warn_cached ();
657 
658  return typ;
659  }
660 
661  if (typ != MatrixType::Unknown
662  && octave_sparse_params::get_key ("spumoni") != 0.)
663  (*current_liboctave_warning_with_id_handler)
664  ("Octave:matrix-type-info", "invalidating matrix type");
665 
667 
668  return typ;
669 }
670 
671 int
673 {
674  if (typ != MatrixType::Unknown
676  {
677  if (octave_sparse_params::get_key ("spumoni") != 0.)
678  warn_cached ();
679 
680  return typ;
681  }
682 
683  MatrixType tmp_typ (a);
684  typ = tmp_typ.typ;
685  sp_bandden = tmp_typ.sp_bandden;
686  bandden = tmp_typ.bandden;
687  upper_band = tmp_typ.upper_band;
688  lower_band = tmp_typ.lower_band;
689  dense = tmp_typ.dense;
690  full = tmp_typ.full;
691  nperm = tmp_typ.nperm;
692 
693  if (nperm != 0)
694  {
695  perm = new octave_idx_type [nperm];
696  for (octave_idx_type i = 0; i < nperm; i++)
697  perm[i] = tmp_typ.perm[i];
698  }
699 
700  return typ;
701 }
702 
703 int
705 {
706  if (typ != MatrixType::Unknown
708  {
709  if (octave_sparse_params::get_key ("spumoni") != 0.)
710  warn_cached ();
711 
712  return typ;
713  }
714 
715  MatrixType tmp_typ (a);
716  typ = tmp_typ.typ;
717  sp_bandden = tmp_typ.sp_bandden;
718  bandden = tmp_typ.bandden;
719  upper_band = tmp_typ.upper_band;
720  lower_band = tmp_typ.lower_band;
721  dense = tmp_typ.dense;
722  full = tmp_typ.full;
723  nperm = tmp_typ.nperm;
724 
725  if (nperm != 0)
726  {
727  perm = new octave_idx_type [nperm];
728  for (octave_idx_type i = 0; i < nperm; i++)
729  perm[i] = tmp_typ.perm[i];
730  }
731 
732  return typ;
733 }
734 
735 int
737 {
738  if (typ != MatrixType::Unknown)
739  {
740  if (octave_sparse_params::get_key ("spumoni") != 0.)
741  warn_cached ();
742 
743  return typ;
744  }
745 
746  MatrixType tmp_typ (a);
747  typ = tmp_typ.typ;
748  full = tmp_typ.full;
749  nperm = tmp_typ.nperm;
750 
751  if (nperm != 0)
752  {
753  perm = new octave_idx_type [nperm];
754  for (octave_idx_type i = 0; i < nperm; i++)
755  perm[i] = tmp_typ.perm[i];
756  }
757 
758  return typ;
759 }
760 
761 int
763 {
764  if (typ != MatrixType::Unknown)
765  {
766  if (octave_sparse_params::get_key ("spumoni") != 0.)
767  warn_cached ();
768 
769  return typ;
770  }
771 
772  MatrixType tmp_typ (a);
773  typ = tmp_typ.typ;
774  full = tmp_typ.full;
775  nperm = tmp_typ.nperm;
776 
777  if (nperm != 0)
778  {
779  perm = new octave_idx_type [nperm];
780  for (octave_idx_type i = 0; i < nperm; i++)
781  perm[i] = tmp_typ.perm[i];
782  }
783 
784  return typ;
785 }
786 
787 int
789 {
790  if (typ != MatrixType::Unknown)
791  {
792  if (octave_sparse_params::get_key ("spumoni") != 0.)
793  warn_cached ();
794 
795  return typ;
796  }
797 
798  MatrixType tmp_typ (a);
799  typ = tmp_typ.typ;
800  full = tmp_typ.full;
801  nperm = tmp_typ.nperm;
802 
803  if (nperm != 0)
804  {
805  perm = new octave_idx_type [nperm];
806  for (octave_idx_type i = 0; i < nperm; i++)
807  perm[i] = tmp_typ.perm[i];
808  }
809 
810  return typ;
811 }
812 
813 int
815 {
816  if (typ != MatrixType::Unknown)
817  {
818  if (octave_sparse_params::get_key ("spumoni") != 0.)
819  warn_cached ();
820 
821  return typ;
822  }
823 
824  MatrixType tmp_typ (a);
825  typ = tmp_typ.typ;
826  full = tmp_typ.full;
827  nperm = tmp_typ.nperm;
828 
829  if (nperm != 0)
830  {
831  perm = new octave_idx_type [nperm];
832  for (octave_idx_type i = 0; i < nperm; i++)
833  perm[i] = tmp_typ.perm[i];
834  }
835 
836  return typ;
837 }
838 
839 void
841 {
842  if (octave_sparse_params::get_key ("spumoni") != 0.)
843  {
844  if (typ == MatrixType::Unknown)
845  (*current_liboctave_warning_with_id_handler)
846  ("Octave:matrix-type-info", "unknown matrix type");
847  else if (typ == MatrixType::Diagonal)
848  (*current_liboctave_warning_with_id_handler)
849  ("Octave:matrix-type-info", "diagonal sparse matrix");
851  (*current_liboctave_warning_with_id_handler)
852  ("Octave:matrix-type-info", "permuted diagonal sparse matrix");
853  else if (typ == MatrixType::Upper)
854  (*current_liboctave_warning_with_id_handler)
855  ("Octave:matrix-type-info", "upper triangular matrix");
856  else if (typ == MatrixType::Lower)
857  (*current_liboctave_warning_with_id_handler)
858  ("Octave:matrix-type-info", "lower triangular matrix");
859  else if (typ == MatrixType::Permuted_Upper)
860  (*current_liboctave_warning_with_id_handler)
861  ("Octave:matrix-type-info", "permuted upper triangular matrix");
862  else if (typ == MatrixType::Permuted_Lower)
863  (*current_liboctave_warning_with_id_handler)
864  ("Octave:matrix-type-info", "permuted lower triangular Matrix");
865  else if (typ == MatrixType::Banded)
866  (*current_liboctave_warning_with_id_handler)
867  ("Octave:matrix-type-info",
868  "banded sparse matrix %d-1-%d (density %f)",
870  else if (typ == MatrixType::Banded_Hermitian)
871  (*current_liboctave_warning_with_id_handler)
872  ("Octave:matrix-type-info",
873  "banded hermitian/symmetric sparse matrix %d-1-%d (density %f)",
875  else if (typ == MatrixType::Hermitian)
876  (*current_liboctave_warning_with_id_handler)
877  ("Octave:matrix-type-info", "hermitian/symmetric matrix");
878  else if (typ == MatrixType::Tridiagonal)
879  (*current_liboctave_warning_with_id_handler)
880  ("Octave:matrix-type-info", "tridiagonal sparse matrix");
882  (*current_liboctave_warning_with_id_handler)
883  ("Octave:matrix-type-info",
884  "hermitian/symmetric tridiagonal sparse matrix");
885  else if (typ == MatrixType::Rectangular)
886  (*current_liboctave_warning_with_id_handler)
887  ("Octave:matrix-type-info", "rectangular/singular matrix");
888  else if (typ == MatrixType::Full)
889  (*current_liboctave_warning_with_id_handler)
890  ("Octave:matrix-type-info", "full matrix");
891  }
892 }
893 
894 void
896 {
903  || typ == MatrixType::Unknown)
905  else
907  ("Can not mark current matrix type as symmetric");
908 }
909 
910 void
912 {
919  || typ == MatrixType::Unknown)
921 }
922 
923 void
925  const octave_idx_type *p)
926 {
927  nperm = np;
928  perm = new octave_idx_type [nperm];
929  for (octave_idx_type i = 0; i < nperm; i++)
930  perm[i] = p[i];
931 
938  else
940  ("Can not mark current matrix type as symmetric");
941 }
942 
943 void
945 {
946  if (nperm)
947  {
948  nperm = 0;
949  delete [] perm;
950  }
951 
958 }
959 
962 {
963  MatrixType retval (*this);
964  if (typ == MatrixType::Upper)
966  else if (typ == MatrixType::Permuted_Upper)
968  else if (typ == MatrixType::Lower)
970  else if (typ == MatrixType::Permuted_Lower)
972  else if (typ == MatrixType::Banded)
973  {
974  retval.upper_band = lower_band;
975  retval.lower_band = upper_band;
976  }
977 
978  return retval;
979 }
980 
981 // Instantiate MatrixType template constructors that we need.
982 
983 template MatrixType::MatrixType (const MSparse<double>&);
984 template MatrixType::MatrixType (const MSparse<Complex>&);
Template for N-dimensional array classes with like-type math operators.
Definition: MArray.h:32
is already an absolute the name is checked against the file system instead of Octave s loadpath In this if otherwise an empty string is returned If the first argument is a cell array of search each directory of the loadpath for element of the cell array and return the first that matches If the second optional argument return a cell array containing the list of all files that have the same name in the path If no files are found
Definition: utils.cc:305
MArray< T > hermitian(T(*fcn)(const T &)=nullptr) const
Definition: MArray.h:106
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
Definition: lo-error.c:38
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol zero divided by zero($0/0$)
double conj(double x)
Definition: lo-mappers.h:85
void mark_as_symmetric(void)
Definition: MatrixType.cc:895
double sp_bandden
Definition: MatrixType.h:198
for large enough k
Definition: lu.cc:617
MatrixType & operator=(const MatrixType &a)
Definition: MatrixType.cc:619
void info(void) const
Definition: MatrixType.cc:840
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function t
Definition: ov-usr-fcn.cc:997
bool dense
Definition: MatrixType.h:202
~MatrixType(void)
Definition: MatrixType.cc:610
static double get_key(const std::string &key)
Definition: oct-spparms.cc:97
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
octave_idx_type lower_band
Definition: MatrixType.h:201
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:400
octave_idx_type nnz(void) const
Count nonzero elements.
Definition: Array.cc:2212
MatrixType(void)
Definition: MatrixType.cc:64
int type(bool quiet=true)
Definition: MatrixType.cc:650
OCTAVE_EXPORT octave_value_list isdir nd deftypefn *std::string nm
Definition: utils.cc:975
octave_idx_type upper_band
Definition: MatrixType.h:200
static void warn_cached(void)
Definition: MatrixType.cc:42
void mark_as_permuted(const octave_idx_type np, const octave_idx_type *p)
Definition: MatrixType.cc:924
octave_idx_type nperm
Definition: MatrixType.h:204
double norm(const ColumnVector &v)
Definition: graphics.cc:5489
double tmp
Definition: data.cc:6252
is false
Definition: cellfun.cc:400
void mark_as_unpermuted(void)
Definition: MatrixType.cc:944
octave_value retval
Definition: data.cc:6246
void mark_as_unsymmetric(void)
Definition: MatrixType.cc:911
Definition: dMatrix.h:36
matrix_type typ
Definition: MatrixType.h:197
octave_idx_type * perm
Definition: MatrixType.h:205
Array< T > diag(octave_idx_type k=0) const
Get the kth super or subdiagonal.
Definition: Array.cc:2530
p
Definition: lu.cc:138
static void warn_calculating_sparse_type(void)
Definition: MatrixType.cc:56
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:41
MatrixType::matrix_type matrix_complex_probe(const MArray< std::complex< T >> &a)
Definition: MatrixType.cc:143
static void warn_invalid(void)
Definition: MatrixType.cc:49
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:141
for i
Definition: data.cc:5264
MatrixType transpose(void) const
Definition: MatrixType.cc:961
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:135
MatrixType::matrix_type matrix_real_probe(const MArray< T > &a)
Definition: MatrixType.cc:85
static double get_bandden(void)
Definition: oct-spparms.cc:104
double bandden
Definition: MatrixType.h:199