Mercurial > octave-nkf
comparison src/DLD-FUNCTIONS/chol.cc @ 13953:642e43164af6
fix behavior of chol (..., 'lower') to be compatible with matlab
* chol.cc: transpose input matrix prior to factorization when
chol (..., 'lower') is invoked so that only the lower triangular
part is used.
author | Carlo de Falco <kingcrimson@tiscali.it> |
---|---|
date | Mon, 28 Nov 2011 12:39:39 +0100 |
parents | 5fa482628bf6 |
children | b0cdd60db5e5 |
comparison
equal
deleted
inserted
replaced
13952:acaf33ccc04f | 13953:642e43164af6 |
---|---|
59 return octave_value (fact.chol_matrix ().transpose (), | 59 return octave_value (fact.chol_matrix ().transpose (), |
60 MatrixType (MatrixType::Lower)); | 60 MatrixType (MatrixType::Lower)); |
61 } | 61 } |
62 | 62 |
63 DEFUN_DLD (chol, args, nargout, | 63 DEFUN_DLD (chol, args, nargout, |
64 "-*- texinfo -*-\n\ | 64 "-*- texinfo -*-\n\ |
65 @deftypefn {Loadable Function} {@var{R} =} chol (@var{A})\n\ | 65 @deftypefn {Loadable Function} {@var{R} =} chol (@var{A})\n\ |
66 @deftypefnx {Loadable Function} {[@var{R}, @var{p}] =} chol (@var{A})\n\ | 66 @deftypefnx {Loadable Function} {[@var{R}, @var{p}] =} chol (@var{A})\n\ |
67 @deftypefnx {Loadable Function} {[@var{R}, @var{p}, @var{Q}] =} chol (@var{S})\n\ | 67 @deftypefnx {Loadable Function} {[@var{R}, @var{p}, @var{Q}] =} chol (@var{S})\n\ |
68 @deftypefnx {Loadable Function} {[@var{R}, @var{p}, @var{Q}] =} chol (@var{S}, 'vector')\n\ | 68 @deftypefnx {Loadable Function} {[@var{R}, @var{p}, @var{Q}] =} chol (@var{S}, 'vector')\n\ |
69 @deftypefnx {Loadable Function} {[@var{L}, @dots{}] =} chol (@dots{}, 'lower')\n\ | 69 @deftypefnx {Loadable Function} {[@var{L}, @dots{}] =} chol (@dots{}, 'lower')\n\ |
70 @deftypefnx {Loadable Function} {[@var{L}, @dots{}] =} chol (@dots{}, 'upper')\n\ | |
70 @cindex Cholesky factorization\n\ | 71 @cindex Cholesky factorization\n\ |
71 Compute the Cholesky@tie{}factor, @var{R}, of the symmetric positive definite\n\ | 72 Compute the Cholesky@tie{}factor, @var{R}, of the symmetric positive definite\n\ |
72 matrix @var{A}, where\n\ | 73 matrix @var{A}, where\n\ |
73 @tex\n\ | 74 @tex\n\ |
74 $ R^T R = A $.\n\ | 75 $ R^T R = A $.\n\ |
125 @example\n\ | 126 @example\n\ |
126 @var{L} * @var{L}' = @var{A}.\n\ | 127 @var{L} * @var{L}' = @var{A}.\n\ |
127 @end example\n\ | 128 @end example\n\ |
128 \n\ | 129 \n\ |
129 @end ifnottex\n\ | 130 @end ifnottex\n\ |
131 \n\ | |
132 For full matrices, if the 'lower' flag is set only the lower triangular part of the matrix \ | |
133 is used for the factorization, otherwise the upper triangular part is used.\n\ | |
130 \n\ | 134 \n\ |
131 In general the lower triangular factorization is significantly faster for\n\ | 135 In general the lower triangular factorization is significantly faster for\n\ |
132 sparse matrices.\n\ | 136 sparse matrices.\n\ |
133 @seealso{cholinv, chol2inv}\n\ | 137 @seealso{cholinv, chol2inv}\n\ |
134 @end deftypefn") | 138 @end deftypefn") |
153 if (! error_state ) | 157 if (! error_state ) |
154 { | 158 { |
155 if (tmp.compare ("vector") == 0) | 159 if (tmp.compare ("vector") == 0) |
156 vecout = true; | 160 vecout = true; |
157 else if (tmp.compare ("lower") == 0) | 161 else if (tmp.compare ("lower") == 0) |
162 // FIXME currently the option "lower" is handled by transposing the | |
163 // matrix, factorizing it with the lapack function DPOTRF ('U', ...) | |
164 // and finally transposing the factor. It would be more efficient to use | |
165 // DPOTRF ('L', ...) in this case. | |
158 LLt = true; | 166 LLt = true; |
159 else if (tmp.compare ("upper") == 0) | 167 else if (tmp.compare ("upper") == 0) |
160 LLt = false; | 168 LLt = false; |
161 else | 169 else |
162 error ("chol: unexpected second or third input"); | 170 error ("chol: unexpected second or third input"); |
249 FloatMatrix m = arg.float_matrix_value (); | 257 FloatMatrix m = arg.float_matrix_value (); |
250 | 258 |
251 if (! error_state) | 259 if (! error_state) |
252 { | 260 { |
253 octave_idx_type info; | 261 octave_idx_type info; |
254 FloatCHOL fact (m, info); | 262 |
263 FloatCHOL fact; | |
264 if (LLt) | |
265 fact = FloatCHOL (m.transpose (), info); | |
266 else | |
267 fact = FloatCHOL (m, info); | |
268 | |
255 if (nargout == 2 || info == 0) | 269 if (nargout == 2 || info == 0) |
256 { | 270 { |
257 retval(1) = info; | 271 retval(1) = info; |
258 if (LLt) | 272 if (LLt) |
259 retval(0) = get_chol_l (fact); | 273 retval(0) = get_chol_l (fact); |
269 FloatComplexMatrix m = arg.float_complex_matrix_value (); | 283 FloatComplexMatrix m = arg.float_complex_matrix_value (); |
270 | 284 |
271 if (! error_state) | 285 if (! error_state) |
272 { | 286 { |
273 octave_idx_type info; | 287 octave_idx_type info; |
274 FloatComplexCHOL fact (m, info); | 288 |
289 FloatComplexCHOL fact; | |
290 if (LLt) | |
291 fact = FloatComplexCHOL (m.transpose (), info); | |
292 else | |
293 fact = FloatComplexCHOL (m, info); | |
294 | |
275 if (nargout == 2 || info == 0) | 295 if (nargout == 2 || info == 0) |
276 { | 296 { |
277 retval(1) = info; | 297 retval(1) = info; |
278 if (LLt) | 298 if (LLt) |
279 retval(0) = get_chol_l (fact); | 299 retval(0) = get_chol_l (fact); |
294 Matrix m = arg.matrix_value (); | 314 Matrix m = arg.matrix_value (); |
295 | 315 |
296 if (! error_state) | 316 if (! error_state) |
297 { | 317 { |
298 octave_idx_type info; | 318 octave_idx_type info; |
299 CHOL fact (m, info); | 319 |
320 CHOL fact; | |
321 if (LLt) | |
322 fact = CHOL (m.transpose (), info); | |
323 else | |
324 fact = CHOL (m, info); | |
325 | |
300 if (nargout == 2 || info == 0) | 326 if (nargout == 2 || info == 0) |
301 { | 327 { |
302 retval(1) = info; | 328 retval(1) = info; |
303 if (LLt) | 329 if (LLt) |
304 retval(0) = get_chol_l (fact); | 330 retval(0) = get_chol_l (fact); |
314 ComplexMatrix m = arg.complex_matrix_value (); | 340 ComplexMatrix m = arg.complex_matrix_value (); |
315 | 341 |
316 if (! error_state) | 342 if (! error_state) |
317 { | 343 { |
318 octave_idx_type info; | 344 octave_idx_type info; |
319 ComplexCHOL fact (m, info); | 345 |
346 ComplexCHOL fact; | |
347 if (LLt) | |
348 fact = ComplexCHOL (m.transpose (), info); | |
349 else | |
350 fact = ComplexCHOL (m, info); | |
351 | |
320 if (nargout == 2 || info == 0) | 352 if (nargout == 2 || info == 0) |
321 { | 353 { |
322 retval(1) = info; | 354 retval(1) = info; |
323 if (LLt) | 355 if (LLt) |
324 retval(0) = get_chol_l (fact); | 356 retval(0) = get_chol_l (fact); |
991 %! R1 = cholinsert(R,j,u2); A1 = R1'*R1; | 1023 %! R1 = cholinsert(R,j,u2); A1 = R1'*R1; |
992 %! | 1024 %! |
993 %! assert(norm(triu(R1)-R1,Inf) == 0) | 1025 %! assert(norm(triu(R1)-R1,Inf) == 0) |
994 %! assert(norm(A1(p,p) - single(Ac),Inf) < 2e1*eps('single')) | 1026 %! assert(norm(A1(p,p) - single(Ac),Inf) < 2e1*eps('single')) |
995 %! | 1027 %! |
1028 | |
1029 %!test | |
1030 %! cu = chol (triu (A), 'upper'); | |
1031 %! cl = chol (tril (A), 'lower'); | |
1032 %! assert (cu, cl', eps) | |
1033 %! | |
1034 %!test | |
1035 %! cca = chol (Ac); | |
1036 %! | |
1037 %! ccal = chol (Ac, 'lower'); | |
1038 %! ccal2 = chol (tril (Ac), 'lower'); | |
1039 %! | |
1040 %! ccau = chol (Ac, 'upper'); | |
1041 %! ccau2 = chol (triu (Ac), 'upper'); | |
1042 %! | |
1043 %! assert (cca'*cca, Ac, eps) | |
1044 %! assert (ccau'*ccau, Ac, eps) | |
1045 %! assert (ccau2'*ccau2, Ac, eps) | |
1046 %! | |
1047 %! assert (cca, ccal', eps) | |
1048 %! assert (cca, ccau, eps) | |
1049 %! assert (cca, ccal2', eps) | |
1050 %! assert (cca, ccau2, eps) | |
1051 %! | |
1052 %!test | |
1053 %! cca = chol (single (Ac)); | |
1054 %! | |
1055 %! ccal = chol (single (Ac), 'lower'); | |
1056 %! ccal2 = chol (tril (single (Ac)), 'lower'); | |
1057 %! | |
1058 %! ccau = chol (single (Ac), 'upper'); | |
1059 %! ccau2 = chol (triu (single (Ac)), 'upper'); | |
1060 %! | |
1061 %! assert (cca'*cca, single (Ac), eps ('single')) | |
1062 %! assert (ccau'*ccau, single (Ac), eps ('single')) | |
1063 %! assert (ccau2'*ccau2, single (Ac), eps ('single')) | |
1064 %! | |
1065 %! assert (cca, ccal', eps ('single')) | |
1066 %! assert (cca, ccau, eps ('single')) | |
1067 %! assert (cca, ccal2', eps ('single')) | |
1068 %! assert (cca, ccau2, eps ('single')) | |
1069 | |
1070 %!test | |
1071 %! a = [12, 2, 3, 4; | |
1072 %! 2, 14, 5, 3; | |
1073 %! 3, 5, 16, 6; | |
1074 %! 4, 3, 6, 16]; | |
1075 %! | |
1076 %! b = [0, 1, 2, 3; | |
1077 %! -1, 0, 1, 2; | |
1078 %! -2, -1, 0, 1; | |
1079 %! -3, -2, -1, 0]; | |
1080 %! | |
1081 %! ca = a + i*b; | |
1082 %! | |
1083 %! cca = chol (ca); | |
1084 %! | |
1085 %! ccal = chol (ca, 'lower'); | |
1086 %! ccal2 = chol (tril (ca), 'lower'); | |
1087 %! | |
1088 %! ccau = chol (ca, 'upper'); | |
1089 %! ccau2 = chol (triu (ca), 'upper'); | |
1090 %! | |
1091 %! assert (cca'*cca, ca, 16*eps) | |
1092 %! assert (ccau'*ccau, ca, 16*eps) | |
1093 %! assert (ccau2'*ccau2, ca, 16*eps) | |
1094 %! | |
1095 %! assert (cca, ccal', 16*eps) | |
1096 %! assert (cca, ccau, 16*eps) | |
1097 %! assert (cca, ccal2', 16*eps) | |
1098 %! assert (cca, ccau2, 16*eps) | |
1099 | |
996 */ | 1100 */ |
997 | 1101 |
998 DEFUN_DLD (choldelete, args, , | 1102 DEFUN_DLD (choldelete, args, , |
999 "-*- texinfo -*-\n\ | 1103 "-*- texinfo -*-\n\ |
1000 @deftypefn {Loadable Function} {@var{R1} =} choldelete (@var{R}, @var{j})\n\ | 1104 @deftypefn {Loadable Function} {@var{R1} =} choldelete (@var{R}, @var{j})\n\ |