Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "defun-dld.h"
00028 #include "error.h"
00029 #include "gripes.h"
00030 #include "oct-obj.h"
00031 #include "ops.h"
00032 #include "ov-re-diag.h"
00033 #include "ov-cx-diag.h"
00034 #include "ov-flt-re-diag.h"
00035 #include "ov-flt-cx-diag.h"
00036 #include "ov-perm.h"
00037 #include "utils.h"
00038
00039 DEFUN_DLD (inv, args, nargout,
00040 "-*- texinfo -*-\n\
00041 @deftypefn {Loadable Function} {@var{x} =} inv (@var{A})\n\
00042 @deftypefnx {Loadable Function} {[@var{x}, @var{rcond}] =} inv (@var{A})\n\
00043 Compute the inverse of the square matrix @var{A}. Return an estimate\n\
00044 of the reciprocal condition number if requested, otherwise warn of an\n\
00045 ill-conditioned matrix if the reciprocal condition number is small.\n\
00046 \n\
00047 In general it is best to avoid calculating the inverse of a matrix\n\
00048 directly. For example, it is both faster and more accurate to solve\n\
00049 systems of equations (@var{A}*@math{x} = @math{b}) with\n\
00050 @code{@var{y} = @var{A} \\ @math{b}}, rather than\n\
00051 @code{@var{y} = inv (@var{A}) * @math{b}}.\n\
00052 \n\
00053 If called with a sparse matrix, then in general @var{x} will be a full\n\
00054 matrix requiring significantly more storage. Avoid forming the inverse\n\
00055 of a sparse matrix if possible.\n\
00056 @seealso{ldivide, rdivide}\n\
00057 @end deftypefn")
00058 {
00059 octave_value_list retval;
00060
00061 int nargin = args.length ();
00062
00063 if (nargin != 1)
00064 {
00065 print_usage ();
00066 return retval;
00067 }
00068
00069 octave_value arg = args(0);
00070
00071 octave_idx_type nr = arg.rows ();
00072 octave_idx_type nc = arg.columns ();
00073
00074 int arg_is_empty = empty_arg ("inverse", nr, nc);
00075
00076 if (arg_is_empty < 0)
00077 return retval;
00078 else if (arg_is_empty > 0)
00079 return octave_value (Matrix ());
00080
00081 if (nr != nc)
00082 {
00083 gripe_square_matrix_required ("inverse");
00084 return retval;
00085 }
00086
00087 octave_value result;
00088 octave_idx_type info;
00089 double rcond = 0.0;
00090 float frcond = 0.0;
00091 bool isfloat = arg.is_single_type ();
00092
00093 if (arg.is_diag_matrix ())
00094 {
00095 rcond = 1.0;
00096 frcond = 1.0f;
00097 if (arg.is_complex_type ())
00098 {
00099 if (isfloat)
00100 {
00101 result = arg.float_complex_diag_matrix_value ().inverse (info);
00102 if (nargout > 1)
00103 frcond = arg.float_complex_diag_matrix_value ().rcond ();
00104 }
00105 else
00106 {
00107 result = arg.complex_diag_matrix_value ().inverse (info);
00108 if (nargout > 1)
00109 rcond = arg.complex_diag_matrix_value ().rcond ();
00110 }
00111 }
00112 else
00113 {
00114 if (isfloat)
00115 {
00116 result = arg.float_diag_matrix_value ().inverse (info);
00117 if (nargout > 1)
00118 frcond = arg.float_diag_matrix_value ().rcond ();
00119 }
00120 else
00121 {
00122 result = arg.diag_matrix_value ().inverse (info);
00123 if (nargout > 1)
00124 rcond = arg.diag_matrix_value ().rcond ();
00125 }
00126 }
00127 }
00128 else if (arg.is_perm_matrix ())
00129 {
00130 rcond = 1.0;
00131 info = 0;
00132 result = arg.perm_matrix_value ().inverse ();
00133 }
00134 else if (isfloat)
00135 {
00136 if (arg.is_real_type ())
00137 {
00138 FloatMatrix m = arg.float_matrix_value ();
00139 if (! error_state)
00140 {
00141 MatrixType mattyp = args(0).matrix_type ();
00142 result = m.inverse (mattyp, info, frcond, 1);
00143 args(0).matrix_type (mattyp);
00144 }
00145 }
00146 else if (arg.is_complex_type ())
00147 {
00148 FloatComplexMatrix m = arg.float_complex_matrix_value ();
00149 if (! error_state)
00150 {
00151 MatrixType mattyp = args(0).matrix_type ();
00152 result = m.inverse (mattyp, info, frcond, 1);
00153 args(0).matrix_type (mattyp);
00154 }
00155 }
00156 }
00157 else
00158 {
00159 if (arg.is_real_type ())
00160 {
00161 if (arg.is_sparse_type ())
00162 {
00163 SparseMatrix m = arg.sparse_matrix_value ();
00164 if (! error_state)
00165 {
00166 MatrixType mattyp = args(0).matrix_type ();
00167 result = m.inverse (mattyp, info, rcond, 1);
00168 args(0).matrix_type (mattyp);
00169 }
00170 }
00171 else
00172 {
00173 Matrix m = arg.matrix_value ();
00174 if (! error_state)
00175 {
00176 MatrixType mattyp = args(0).matrix_type ();
00177 result = m.inverse (mattyp, info, rcond, 1);
00178 args(0).matrix_type (mattyp);
00179 }
00180 }
00181 }
00182 else if (arg.is_complex_type ())
00183 {
00184 if (arg.is_sparse_type ())
00185 {
00186 SparseComplexMatrix m = arg.sparse_complex_matrix_value ();
00187 if (! error_state)
00188 {
00189 MatrixType mattyp = args(0).matrix_type ();
00190 result = m.inverse (mattyp, info, rcond, 1);
00191 args(0).matrix_type (mattyp);
00192 }
00193 }
00194 else
00195 {
00196 ComplexMatrix m = arg.complex_matrix_value ();
00197 if (! error_state)
00198 {
00199 MatrixType mattyp = args(0).matrix_type ();
00200 result = m.inverse (mattyp, info, rcond, 1);
00201 args(0).matrix_type (mattyp);
00202 }
00203 }
00204 }
00205 else
00206 gripe_wrong_type_arg ("inv", arg);
00207 }
00208
00209 if (! error_state)
00210 {
00211 if (nargout > 1)
00212 retval(1) = isfloat ? octave_value (frcond) : octave_value (rcond);
00213
00214 retval(0) = result;
00215
00216 volatile double xrcond = rcond;
00217 xrcond += 1.0;
00218 if (nargout < 2 && (info == -1 || xrcond == 1.0))
00219 warning ("inverse: matrix singular to machine precision, rcond = %g",
00220 rcond);
00221 }
00222
00223 return retval;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 DEFUN_DLD (inverse, args, nargout,
00242 "-*- texinfo -*-\n\
00243 @deftypefn {Loadable Function} {@var{x} =} inverse (@var{A})\n\
00244 @deftypefnx {Loadable Function} {[@var{x}, @var{rcond}] =} inverse (@var{A})\n\
00245 Compute the inverse of the square matrix @var{A}.\n\
00246 \n\
00247 This is an alias for @code{inv}.\n\
00248 @seealso{inv}\n\
00249 @end deftypefn")
00250 {
00251 return Finv (args, nargout);
00252 }