comparison src/DLD-FUNCTIONS/matrix_type.cc @ 5785:6b9cec830d72

[project @ 2006-05-03 19:32:46 by dbateman]
author dbateman
date Wed, 03 May 2006 19:32:48 +0000
parents ace8d8d26933
children 080c08b192d8
comparison
equal deleted inserted replaced
5784:70f7659d0fb9 5785:6b9cec830d72
28 #include <algorithm> 28 #include <algorithm>
29 29
30 #include "ov.h" 30 #include "ov.h"
31 #include "defun-dld.h" 31 #include "defun-dld.h"
32 #include "error.h" 32 #include "error.h"
33 #include "ov-re-mat.h"
34 #include "ov-cx-mat.h"
33 #include "ov-re-sparse.h" 35 #include "ov-re-sparse.h"
34 #include "ov-cx-sparse.h" 36 #include "ov-cx-sparse.h"
35 #include "SparseType.h" 37 #include "MatrixType.h"
36 38
37 DEFUN_DLD (matrix_type, args, , 39 DEFUN_DLD (matrix_type, args, ,
38 "-*- texinfo -*-\n\ 40 "-*- texinfo -*-\n\
39 @deftypefn {Loadable Function} {@var{type} =} matrix_type (@var{a})\n\ 41 @deftypefn {Loadable Function} {@var{type} =} matrix_type (@var{a})\n\
40 @deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, @var{type})\n\ 42 @deftypefnx {Loadable Function} {@var{a} =} matrix_type (@var{a}, @var{type})\n\
109 { 111 {
110 if (args(0).is_sparse_type ()) 112 if (args(0).is_sparse_type ())
111 { 113 {
112 if (nargin == 1) 114 if (nargin == 1)
113 { 115 {
114 SparseType mattyp; 116 MatrixType mattyp;
115 117
116 if (args(0).type_name () == "sparse complex matrix" ) 118 if (args(0).type_name () == "sparse complex matrix" )
117 { 119 {
118 const octave_sparse_complex_matrix& rep 120 mattyp = args(0).matrix_type ();
119 = dynamic_cast<const octave_sparse_complex_matrix&> (args(0).get_rep ());
120
121 mattyp = rep.sparse_type ();
122 121
123 if (mattyp.is_unknown ()) 122 if (mattyp.is_unknown ())
124 { 123 {
125 SparseComplexMatrix m = 124 SparseComplexMatrix m =
126 args(0).sparse_complex_matrix_value (); 125 args(0).sparse_complex_matrix_value ();
127 if (!error_state) 126 if (!error_state)
128 { 127 {
129 mattyp = SparseType (m); 128 mattyp = MatrixType (m);
130 rep.sparse_type (mattyp); 129 args(0).matrix_type (mattyp);
131 } 130 }
132 } 131 }
133 } 132 }
134 else 133 else
135 { 134 {
136 const octave_sparse_matrix& rep 135 mattyp = args(0).matrix_type ();
137 = dynamic_cast<const octave_sparse_matrix&> (args(0).get_rep ());
138
139 mattyp = rep.sparse_type ();
140 136
141 if (mattyp.is_unknown ()) 137 if (mattyp.is_unknown ())
142 { 138 {
143 SparseMatrix m = args(0).sparse_matrix_value (); 139 SparseMatrix m = args(0).sparse_matrix_value ();
144 if (!error_state) 140 if (!error_state)
145 { 141 {
146 mattyp = SparseType (m); 142 mattyp = MatrixType (m);
147 rep.sparse_type (mattyp); 143 args(0).matrix_type (mattyp);
148 } 144 }
149 } 145 }
150 } 146 }
151 147
152 int typ = mattyp.type (); 148 int typ = mattyp.type ();
153 149
154 if (typ == SparseType::Diagonal) 150 if (typ == MatrixType::Diagonal)
155 retval = octave_value ("Diagonal"); 151 retval = octave_value ("Diagonal");
156 else if (typ == SparseType::Permuted_Diagonal) 152 else if (typ == MatrixType::Permuted_Diagonal)
157 retval = octave_value ("Permuted Diagonal"); 153 retval = octave_value ("Permuted Diagonal");
158 else if (typ == SparseType::Upper) 154 else if (typ == MatrixType::Upper)
159 retval = octave_value ("Upper"); 155 retval = octave_value ("Upper");
160 else if (typ == SparseType::Permuted_Upper) 156 else if (typ == MatrixType::Permuted_Upper)
161 retval = octave_value ("Permuted Upper"); 157 retval = octave_value ("Permuted Upper");
162 else if (typ == SparseType::Lower) 158 else if (typ == MatrixType::Lower)
163 retval = octave_value ("Lower"); 159 retval = octave_value ("Lower");
164 else if (typ == SparseType::Permuted_Lower) 160 else if (typ == MatrixType::Permuted_Lower)
165 retval = octave_value ("Permuted Lower"); 161 retval = octave_value ("Permuted Lower");
166 else if (typ == SparseType::Banded) 162 else if (typ == MatrixType::Banded)
167 retval = octave_value ("Banded"); 163 retval = octave_value ("Banded");
168 else if (typ == SparseType::Banded_Hermitian) 164 else if (typ == MatrixType::Banded_Hermitian)
169 retval = octave_value ("Banded Positive Definite"); 165 retval = octave_value ("Banded Positive Definite");
170 else if (typ == SparseType::Tridiagonal) 166 else if (typ == MatrixType::Tridiagonal)
171 retval = octave_value ("Tridiagonal"); 167 retval = octave_value ("Tridiagonal");
172 else if (typ == SparseType::Tridiagonal_Hermitian) 168 else if (typ == MatrixType::Tridiagonal_Hermitian)
173 retval = octave_value ("Tridiagonal Positive Definite"); 169 retval = octave_value ("Tridiagonal Positive Definite");
174 else if (typ == SparseType::Hermitian) 170 else if (typ == MatrixType::Hermitian)
175 retval = octave_value ("Positive Definite"); 171 retval = octave_value ("Positive Definite");
176 else if (typ == SparseType::Rectangular) 172 else if (typ == MatrixType::Rectangular)
177 { 173 {
178 if (args(0).rows() == args(0).columns()) 174 if (args(0).rows() == args(0).columns())
179 retval = octave_value ("Singular"); 175 retval = octave_value ("Singular");
180 else 176 else
181 retval = octave_value ("Rectangular"); 177 retval = octave_value ("Rectangular");
182 } 178 }
183 else if (typ == SparseType::Full) 179 else if (typ == MatrixType::Full)
184 retval = octave_value ("Full"); 180 retval = octave_value ("Full");
185 else 181 else
186 // This should never happen!!! 182 // This should never happen!!!
187 retval = octave_value ("Unknown"); 183 retval = octave_value ("Unknown");
188 } 184 }
190 { 186 {
191 // Ok, we're changing the matrix type 187 // Ok, we're changing the matrix type
192 std::string str_typ = args(1).string_value (); 188 std::string str_typ = args(1).string_value ();
193 189
194 // FIXME -- why do I have to explicitly call the constructor? 190 // FIXME -- why do I have to explicitly call the constructor?
195 SparseType mattyp = SparseType (); 191 MatrixType mattyp = MatrixType ();
196 192
197 octave_idx_type nl = 0; 193 octave_idx_type nl = 0;
198 octave_idx_type nu = 0; 194 octave_idx_type nu = 0;
199 195
200 if (error_state) 196 if (error_state)
298 } 294 }
299 } 295 }
300 } 296 }
301 } 297 }
302 else 298 else
303 error ("matrix_type: Only sparse matrices treated at the moment"); 299 {
300 if (nargin == 1)
301 {
302 MatrixType mattyp;
303
304 if (args(0).type_name () == "complex matrix" )
305 {
306 mattyp = args(0).matrix_type ();
307
308 if (mattyp.is_unknown ())
309 {
310 ComplexMatrix m = args(0).complex_matrix_value ();
311 if (!error_state)
312 {
313 mattyp = MatrixType (m);
314 args(0).matrix_type (mattyp);
315 }
316 }
317 }
318 else
319 {
320 mattyp = args(0).matrix_type ();
321
322 if (mattyp.is_unknown ())
323 {
324 Matrix m = args(0).matrix_value ();
325 if (!error_state)
326 {
327 mattyp = MatrixType (m);
328 args(0).matrix_type (mattyp);
329 }
330 }
331 }
332
333 int typ = mattyp.type ();
334
335 if (typ == MatrixType::Upper)
336 retval = octave_value ("Upper");
337 else if (typ == MatrixType::Permuted_Upper)
338 retval = octave_value ("Permuted Upper");
339 else if (typ == MatrixType::Lower)
340 retval = octave_value ("Lower");
341 else if (typ == MatrixType::Permuted_Lower)
342 retval = octave_value ("Permuted Lower");
343 else if (typ == MatrixType::Hermitian)
344 retval = octave_value ("Positive Definite");
345 else if (typ == MatrixType::Rectangular)
346 {
347 if (args(0).rows() == args(0).columns())
348 retval = octave_value ("Singular");
349 else
350 retval = octave_value ("Rectangular");
351 }
352 else if (typ == MatrixType::Full)
353 retval = octave_value ("Full");
354 else
355 // This should never happen!!!
356 retval = octave_value ("Unknown");
357 }
358 else
359 {
360 // Ok, we're changing the matrix type
361 std::string str_typ = args(1).string_value ();
362
363 // FIXME -- why do I have to explicitly call the constructor?
364 MatrixType mattyp = MatrixType (MatrixType::Unknown, true);
365
366 if (error_state)
367 error ("Matrix type must be a string");
368 else
369 {
370 // Use STL function to convert to lower case
371 std::transform (str_typ.begin (), str_typ.end (),
372 str_typ.begin (), tolower);
373
374 if (str_typ == "upper")
375 mattyp.mark_as_upper_triangular ();
376 else if (str_typ == "lower")
377 mattyp.mark_as_lower_triangular ();
378 else if (str_typ == "positive definite")
379 {
380 mattyp.mark_as_full ();
381 mattyp.mark_as_symmetric ();
382 }
383 else if (str_typ == "singular")
384 mattyp.mark_as_rectangular ();
385 else if (str_typ == "full")
386 mattyp.mark_as_full ();
387 else if (str_typ == "unknown")
388 mattyp.invalidate_type ();
389 else
390 error ("matrix_type: Unknown matrix type %s", str_typ.c_str());
391
392 if (! error_state)
393 {
394 if (nargin == 3 && (str_typ == "upper"
395 || str_typ == "lower"))
396 {
397 const ColumnVector perm =
398 ColumnVector (args (2).vector_value ());
399
400 if (error_state)
401 error ("matrix_type: Invalid permutation vector");
402 else
403 {
404 octave_idx_type len = perm.length ();
405 dim_vector dv = args(0).dims ();
406
407 if (len != dv(0))
408 error ("matrix_type: Invalid permutation vector");
409 else
410 {
411 OCTAVE_LOCAL_BUFFER (octave_idx_type, p, len);
412
413 for (octave_idx_type i = 0; i < len; i++)
414 p[i] = static_cast<octave_idx_type> (perm (i)) - 1;
415
416 if (str_typ == "upper")
417 mattyp.mark_as_permuted (len, p);
418 else
419 mattyp.mark_as_permuted (len, p);
420 }
421 }
422 }
423 else if (nargin != 2)
424 error ("matrix_type: Invalid number of arguments");
425
426 if (! error_state)
427 {
428 // Set the matrix type
429 if (args(0).type_name () == "complex matrix" )
430 retval =
431 octave_value (args(0).complex_matrix_value (),
432 mattyp);
433 else
434 retval = octave_value (args(0).matrix_value (),
435 mattyp);
436 }
437 }
438 }
439 }
440 }
304 } 441 }
305 442
306 return retval; 443 return retval;
307 } 444 }
308 445
309 /* 446 /*
310 447
311 ## FIXME 448 ## FIXME
312 ## Disable tests for lower under-determined and upper over-determined 449 ## Disable tests for lower under-determined and upper over-determined
313 ## matrices and this detection is disabled in SparseType due to issues 450 ## matrices and this detection is disabled in MatrixType due to issues
314 ## of non minimum norm solution being found. 451 ## of non minimum norm solution being found.
315 452
316 %!assert(matrix_type(speye(10,10)),"Diagonal"); 453 %!assert(matrix_type(speye(10,10)),"Diagonal");
317 %!assert(matrix_type(speye(10,10)([2:10,1],:)),"Permuted Diagonal"); 454 %!assert(matrix_type(speye(10,10)([2:10,1],:)),"Permuted Diagonal");
318 %!assert(matrix_type([[speye(10,10);sparse(1,10)],[1;sparse(9,1);1]]),"Upper"); 455 %!assert(matrix_type([[speye(10,10);sparse(1,10)],[1;sparse(9,1);1]]),"Upper");
391 528
392 %!test 529 %!test
393 %! a = matrix_type(spdiags(randn(10,3),[-1,0,1],10,10),"Singular"); 530 %! a = matrix_type(spdiags(randn(10,3),[-1,0,1],10,10),"Singular");
394 %! assert(matrix_type(a),"Singular"); 531 %! assert(matrix_type(a),"Singular");
395 532
533 %!assert(matrix_type(triu(ones(10,10))),"Upper");
534 %!assert(matrix_type(triu(ones(10,10),-1)),"Full");
535 %!assert(matrix_type(tril(ones(10,10))),"Lower");
536 %!assert(matrix_type(tril(ones(10,10),1)),"Full");
537 %!assert(matrix_type(10*eye(10,10) + ones(10,10)), "Positive Definite");
538 %!assert(matrix_type(ones(11,10)),"Rectangular")
539 %!test
540 %! a = matrix_type(ones(10,10),"Singular");
541 %! assert(matrix_type(a),"Singular");
542
543 %!assert(matrix_type(triu(1i*ones(10,10))),"Upper");
544 %!assert(matrix_type(triu(1i*ones(10,10),-1)),"Full");
545 %!assert(matrix_type(tril(1i*ones(10,10))),"Lower");
546 %!assert(matrix_type(tril(1i*ones(10,10),1)),"Full");
547 %!assert(matrix_type(10*eye(10,10) + 1i*triu(ones(10,10),1) -1i*tril(ones(10,10),-1)), "Positive Definite");
548 %!assert(matrix_type(ones(11,10)),"Rectangular")
549 %!test
550 %! a = matrix_type(ones(10,10),"Singular");
551 %! assert(matrix_type(a),"Singular");
552
396 */ 553 */
397 554
398 /* 555 /*
399 ;;; Local Variables: *** 556 ;;; Local Variables: ***
400 ;;; mode: C++ *** 557 ;;; mode: C++ ***