comparison libinterp/corefcn/pinv.cc @ 18467:c5a101de2d88

Allow pinv to work on Diagonal Matrices with a tolerance (bug #41546). * pinv.cc (Fpinv): Validate tolerance argument and pass it through to pseudo_inverse(). CDiagMatrix.h, dDiagMatrix.h, fCDiagMatrix.h, fDiagMatrix.h: Redefine prototype for pseudo_inverse to accept a single argument for tolerance. * CDiagMatrix.cc (pseudo_inverse), dDiagMatrix.cc(pseudo_inverse), fCDiagMatrix.cc(pseudo_inverse), fDiagMatrix.cc(pseudo_inverse): Use std::abs(elem) to get magnitude of element and only invert if value is greater than tolerance.
author Rik <rik@octave.org>
date Sat, 15 Feb 2014 14:42:07 -0800
parents 175b392e91fe
children 1fa5bba16218
comparison
equal deleted inserted replaced
18466:a3611f3e80eb 18467:c5a101de2d88
74 74
75 bool isfloat = arg.is_single_type (); 75 bool isfloat = arg.is_single_type ();
76 76
77 if (arg.is_diag_matrix ()) 77 if (arg.is_diag_matrix ())
78 { 78 {
79 if (nargin == 2) 79 if (isfloat)
80 warning ("pinv: tol is ignored for diagonal matrices"); 80 {
81 81 float tol = 0.0;
82 if (arg.is_complex_type ()) 82 if (nargin == 2)
83 { 83 tol = args(1).float_value ();
84 if (isfloat) 84
85 retval = arg.float_complex_diag_matrix_value ().pseudo_inverse (); 85 if (error_state)
86 return retval;
87
88 if (tol < 0.0)
89 {
90 error ("pinv: TOL must be greater than zero");
91 return retval;
92 }
93
94 if (arg.is_real_type ())
95 retval = arg.float_diag_matrix_value ().pseudo_inverse (tol);
86 else 96 else
87 retval = arg.complex_diag_matrix_value ().pseudo_inverse (); 97 retval = arg.float_complex_diag_matrix_value ().pseudo_inverse (tol);
88 } 98 }
89 else 99 else
90 { 100 {
91 if (isfloat) 101 double tol = 0.0;
92 retval = arg.float_diag_matrix_value ().pseudo_inverse (); 102 if (nargin == 2)
103 tol = args(1).double_value ();
104
105 if (error_state)
106 return retval;
107
108 if (tol < 0.0)
109 {
110 error ("pinv: TOL must be greater than zero");
111 return retval;
112 }
113
114 if (arg.is_real_type ())
115 retval = arg.diag_matrix_value ().pseudo_inverse (tol);
93 else 116 else
94 retval = arg.diag_matrix_value ().pseudo_inverse (); 117 retval = arg.complex_diag_matrix_value ().pseudo_inverse (tol);
95 } 118 }
96 } 119 }
97 else if (arg.is_perm_matrix ()) 120 else if (arg.is_perm_matrix ())
98 { 121 {
99 retval = arg.perm_matrix_value ().inverse (); 122 retval = arg.perm_matrix_value ().inverse ();