GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MatrixType.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2006-2017 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 the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 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 <http://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 (0) { }
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 (0)
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 (0)
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 (0)
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 (0)
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 (0)
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 (0)
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 = (octave::math::real (d) > 0.0
511  && octave::math::imag (d) == 0.0);
512  diag(j) = octave::math::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 (0)
562 {
563  if (t == MatrixType::Unknown || t == MatrixType::Full
565  || t == MatrixType::Upper || t == MatrixType::Lower
567  || t == MatrixType::Rectangular)
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 (0)
579 {
581  && np > 0 && p != 0)
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 (0)
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;
625  bandden = a.bandden;
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)
965  retval.typ = MatrixType::Lower;
966  else if (typ == MatrixType::Permuted_Upper)
968  else if (typ == MatrixType::Lower)
969  retval.typ = MatrixType::Upper;
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>&);
octave_idx_type cols(void) const
Definition: Sparse.h:272
T * data(void)
Definition: Sparse.h:521
octave_idx_type rows(void) const
Definition: Sparse.h:271
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
Definition: lo-error.c:38
double conj(double x)
Definition: lo-mappers.h:93
void mark_as_symmetric(void)
Definition: MatrixType.cc:895
double sp_bandden
Definition: MatrixType.h:178
for large enough k
Definition: lu.cc:606
MatrixType & operator=(const MatrixType &a)
Definition: MatrixType.cc:619
is greater than zero
Definition: load-path.cc:2339
Array< T > diag(octave_idx_type k=0) const
Get the kth super or subdiagonal.
Definition: Array.cc:2529
octave_idx_type * cidx(void)
Definition: Sparse.h:543
T & elem(octave_idx_type n)
Definition: Array.h:482
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:935
Template for N-dimensional array classes with like-type math operators.
Definition: MArray.h:32
bool dense
Definition: MatrixType.h:182
~MatrixType(void)
Definition: MatrixType.cc:610
static double get_key(const std::string &key)
Definition: oct-spparms.cc:95
double real(double x)
Definition: lo-mappers.h:113
octave_idx_type rows(void) const
Definition: Array.h:401
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &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 F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
octave_idx_type nnz(void) const
Actual number of nonzero terms.
Definition: Sparse.h:253
octave_idx_type lower_band
Definition: MatrixType.h:181
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:398
OCTAVE_EXPORT octave_value_list 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:302
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:941
octave_idx_type upper_band
Definition: MatrixType.h:180
static void warn_cached(void)
Definition: MatrixType.cc:42
MatrixType transpose(void) const
Definition: MatrixType.cc:961
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:184
double norm(const ColumnVector &v)
Definition: graphics.cc:5197
double tmp
Definition: data.cc:6300
is false
Definition: cellfun.cc:398
void mark_as_unpermuted(void)
Definition: MatrixType.cc:944
octave_value retval
Definition: data.cc:6294
void mark_as_unsymmetric(void)
Definition: MatrixType.cc:911
double imag(double)
Definition: lo-mappers.h:103
Definition: dMatrix.h:37
matrix_type typ
Definition: MatrixType.h:177
octave_idx_type nnz(void) const
Count nonzero elements.
Definition: Array.cc:2231
MArray< T > hermitian(T(*fcn)(const T &)=0) const
Definition: MArray.h:106
octave_idx_type * perm
Definition: MatrixType.h:185
octave_idx_type * ridx(void)
Definition: Sparse.h:530
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
p
Definition: lu.cc:138
issues an error eealso double
Definition: ov-bool-mat.cc:594
static void warn_calculating_sparse_type(void)
Definition: MatrixType.cc:56
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:200
static void warn_invalid(void)
Definition: MatrixType.cc:49
octave_idx_type cols(void) const
Definition: Array.h:409
MatrixType::matrix_type matrix_real_probe(const MArray< T > &a)
Definition: MatrixType.cc:85
static double get_bandden(void)
Definition: oct-spparms.cc:102
double bandden
Definition: MatrixType.h:179
MatrixType::matrix_type matrix_complex_probe(const MArray< std::complex< T > > &a)
Definition: MatrixType.cc:143