Mercurial > hg > octave-nkf
comparison liboctave/array/CMatrix.cc @ 20809:ffc6cdcd02c5 stable
Fix segfault when complex double matrix calls ZGETRF (bug #45577).
* CMatrix.cc (finverse, determinant, rcond, fsolve): Calculate norm of matrix
and if it is NaN, skip calling ZGETRF in LAPACK and set info to non-zero value
to signal an error.
author | Rik <rik@octave.org> |
---|---|
date | Sat, 10 Oct 2015 16:46:00 -0700 |
parents | 17d647821d61 |
children | 1c5a86b7f838 |
comparison
equal
deleted
inserted
replaced
20808:7890893a0e69 | 20809:ffc6cdcd02c5 |
---|---|
1129 | 1129 |
1130 info = 0; | 1130 info = 0; |
1131 | 1131 |
1132 // Calculate the norm of the matrix, for later use. | 1132 // Calculate the norm of the matrix, for later use. |
1133 double anorm; | 1133 double anorm; |
1134 if (calc_cond) | 1134 //if (calc_cond) // Must always calculate anorm for bug #45577 |
1135 anorm = retval.abs ().sum ().row (static_cast<octave_idx_type>(0)) | 1135 anorm = retval.abs ().sum ().row (static_cast<octave_idx_type>(0)).max (); |
1136 .max (); | 1136 |
1137 | 1137 // Work around bug #45577, LAPACK crashes Octave if norm is NaN |
1138 F77_XFCN (zgetrf, ZGETRF, (nc, nc, tmp_data, nr, pipvt, info)); | 1138 if (xisnan (anorm)) |
1139 info = -1; | |
1140 else | |
1141 F77_XFCN (zgetrf, ZGETRF, (nc, nc, tmp_data, nr, pipvt, info)); | |
1139 | 1142 |
1140 // Throw-away extra info LAPACK gives so as to not change output. | 1143 // Throw-away extra info LAPACK gives so as to not change output. |
1141 rcon = 0.0; | 1144 rcon = 0.0; |
1142 if (info != 0) | 1145 if (info != 0) |
1143 info = -1; | 1146 info = -1; |
1696 | 1699 |
1697 info = 0; | 1700 info = 0; |
1698 | 1701 |
1699 // Calculate the norm of the matrix, for later use. | 1702 // Calculate the norm of the matrix, for later use. |
1700 double anorm = 0; | 1703 double anorm = 0; |
1701 if (calc_cond) anorm = xnorm (*this, 1); | 1704 //if (calc_cond) // Must always calculate anorm for bug #45577 |
1702 | 1705 anorm = xnorm (*this, 1); |
1703 F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info)); | 1706 |
1707 // Work around bug #45577, LAPACK crashes Octave if norm is NaN | |
1708 if (xisnan (anorm)) | |
1709 info = -1; | |
1710 else | |
1711 F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info)); | |
1704 | 1712 |
1705 // Throw-away extra info LAPACK gives so as to not change output. | 1713 // Throw-away extra info LAPACK gives so as to not change output. |
1706 rcon = 0.0; | 1714 rcon = 0.0; |
1707 if (info != 0) | 1715 if (info != 0) |
1708 { | 1716 { |
1889 Array<Complex> z (dim_vector (2 * nc, 1)); | 1897 Array<Complex> z (dim_vector (2 * nc, 1)); |
1890 Complex *pz = z.fortran_vec (); | 1898 Complex *pz = z.fortran_vec (); |
1891 Array<double> rz (dim_vector (2 * nc, 1)); | 1899 Array<double> rz (dim_vector (2 * nc, 1)); |
1892 double *prz = rz.fortran_vec (); | 1900 double *prz = rz.fortran_vec (); |
1893 | 1901 |
1894 F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info)); | 1902 // Work around bug #45577, LAPACK crashes Octave if norm is NaN |
1903 if (xisnan (anorm)) | |
1904 info = -1; | |
1905 else | |
1906 F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info)); | |
1895 | 1907 |
1896 if (info != 0) | 1908 if (info != 0) |
1897 { | 1909 { |
1898 rcon = 0.0; | 1910 rcon = 0.0; |
1899 mattype.mark_as_rectangular (); | 1911 mattype.mark_as_rectangular (); |
2223 // Calculate the norm of the matrix, for later use. | 2235 // Calculate the norm of the matrix, for later use. |
2224 if (anorm < 0.) | 2236 if (anorm < 0.) |
2225 anorm = atmp.abs ().sum ().row (static_cast<octave_idx_type>(0)) | 2237 anorm = atmp.abs ().sum ().row (static_cast<octave_idx_type>(0)) |
2226 .max (); | 2238 .max (); |
2227 | 2239 |
2228 F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info)); | 2240 // Work around bug #45577, LAPACK crashes Octave if norm is NaN |
2241 if (xisnan (anorm)) | |
2242 info = -2; | |
2243 else | |
2244 F77_XFCN (zgetrf, ZGETRF, (nr, nr, tmp_data, nr, pipvt, info)); | |
2229 | 2245 |
2230 // Throw-away extra info LAPACK gives so as to not change output. | 2246 // Throw-away extra info LAPACK gives so as to not change output. |
2231 rcon = 0.0; | 2247 rcon = 0.0; |
2232 if (info != 0) | 2248 if (info != 0) |
2233 { | 2249 { |