GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
det.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2017 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include "DET.h"
28 
29 #include "defun.h"
30 #include "error.h"
31 #include "errwarn.h"
32 #include "ovl.h"
33 #include "ops.h"
34 
35 #include "ov-re-mat.h"
36 #include "ov-cx-mat.h"
37 #include "ov-flt-re-mat.h"
38 #include "ov-flt-cx-mat.h"
39 #include "ov-re-diag.h"
40 #include "ov-cx-diag.h"
41 #include "ov-flt-re-diag.h"
42 #include "ov-flt-cx-diag.h"
43 #include "ov-perm.h"
44 
45 #define MAYBE_CAST(VAR, CLASS) \
46  const CLASS *VAR = (arg.type_id () == CLASS::static_type_id () \
47  ? dynamic_cast<const CLASS *> (&arg.get_rep ()) \
48  : 0)
49 
50 DEFUN (det, args, nargout,
51  doc: /* -*- texinfo -*-
52 @deftypefn {} {} det (@var{A})
53 @deftypefnx {} {[@var{d}, @var{rcond}] =} det (@var{A})
54 Compute the determinant of @var{A}.
55 
56 Return an estimate of the reciprocal condition number if requested.
57 
58 Programming Notes: Routines from @sc{lapack} are used for full matrices and
59 code from @sc{umfpack} is used for sparse matrices.
60 
61 The determinant should not be used to check a matrix for singularity.
62 For that, use any of the condition number functions: @code{cond},
63 @code{condest}, @code{rcond}.
64 @seealso{cond, condest, rcond}
65 @end deftypefn */)
66 {
67  if (args.length () != 1)
68  print_usage ();
69 
70  octave_value arg = args(0);
71 
72  if (arg.is_empty ())
73  return ovl (1.0);
74 
75  if (arg.rows () != arg.columns ())
76  err_square_matrix_required ("det", "A");
77 
79 
80  bool isfloat = arg.is_single_type ();
81 
82  if (arg.is_diag_matrix ())
83  {
84  if (nargout <= 1)
85  retval.resize (1);
86 
87  if (arg.is_complex_type ())
88  {
89  if (isfloat)
90  {
92  .determinant ().value ();
93  if (nargout > 1)
95  }
96  else
97  {
99  .determinant ().value ();
100  if (nargout > 1)
101  retval(1) = arg.complex_diag_matrix_value ().rcond ();
102  }
103  }
104  else
105  {
106  if (isfloat)
107  {
108  retval(0) = arg.float_diag_matrix_value ()
109  .determinant ().value ();
110  if (nargout > 1)
111  retval(1) = arg.float_diag_matrix_value ().rcond ();
112  }
113  else
114  {
115  retval(0) = arg.diag_matrix_value ().determinant ().value ();
116  if (nargout > 1)
117  retval(1) = arg.diag_matrix_value ().rcond ();
118  }
119  }
120  }
121  else if (arg.is_perm_matrix ())
122  {
123  if (nargout <= 1)
124  retval.resize (1);
125 
126  retval(0) = static_cast<double> (arg.perm_matrix_value ().determinant ());
127  if (nargout > 1)
128  retval(1) = 1.0;
129  }
130  else if (arg.is_single_type ())
131  {
132  if (arg.is_real_type ())
133  {
134  octave_idx_type info;
135  float rcond = 0.0;
136  // Always compute rcond, so we can detect singular matrices.
138 
140  MatrixType mtype = rep ? rep -> matrix_type () : MatrixType ();
141  FloatDET det = m.determinant (mtype, info, rcond);
142  retval(0) = info == -1 ? 0.0f : det.value ();
143  retval(1) = rcond;
144  if (rep)
145  rep->matrix_type (mtype);
146  }
147  else if (arg.is_complex_type ())
148  {
149  octave_idx_type info;
150  float rcond = 0.0;
151  // Always compute rcond, so we can detect singular matrices.
153 
155  MatrixType mtype = rep ? rep -> matrix_type () : MatrixType ();
156  FloatComplexDET det = m.determinant (mtype, info, rcond);
157  retval(0) = info == -1 ? FloatComplex (0.0) : det.value ();
158  retval(1) = rcond;
159  if (rep)
160  rep->matrix_type (mtype);
161  }
162  }
163  else
164  {
165  if (arg.is_real_type ())
166  {
167  octave_idx_type info;
168  double rcond = 0.0;
169  // Always compute rcond, so we can detect singular matrices.
170  if (arg.is_sparse_type ())
171  {
173 
174  DET det = m.determinant (info, rcond);
175  retval(0) = info == -1 ? 0.0 : det.value ();
176  retval(1) = rcond;
177  }
178  else
179  {
180  Matrix m = arg.matrix_value ();
181 
182  MAYBE_CAST (rep, octave_matrix);
183  MatrixType mtype = rep ? rep -> matrix_type ()
184  : MatrixType ();
185  DET det = m.determinant (mtype, info, rcond);
186  retval(0) = info == -1 ? 0.0 : det.value ();
187  retval(1) = rcond;
188  if (rep)
189  rep->matrix_type (mtype);
190  }
191  }
192  else if (arg.is_complex_type ())
193  {
194  octave_idx_type info;
195  double rcond = 0.0;
196  // Always compute rcond, so we can detect singular matrices.
197  if (arg.is_sparse_type ())
198  {
200 
201  ComplexDET det = m.determinant (info, rcond);
202  retval(0) = info == -1 ? Complex (0.0) : det.value ();
203  retval(1) = rcond;
204  }
205  else
206  {
208 
210  MatrixType mtype = rep ? rep -> matrix_type ()
211  : MatrixType ();
212  ComplexDET det = m.determinant (mtype, info, rcond);
213  retval(0) = info == -1 ? Complex (0.0) : det.value ();
214  retval(1) = rcond;
215  if (rep)
216  rep->matrix_type (mtype);
217  }
218  }
219  else
220  err_wrong_type_arg ("det", arg);
221  }
222 
223  return retval;
224 }
225 
226 /*
227 %!assert (det ([1, 2; 3, 4]), -2, 10*eps)
228 %!assert (det (single ([1, 2; 3, 4])), single (-2), 10*eps ("single"))
229 %!error det ()
230 %!error det (1, 2)
231 %!error <must be a square matrix> det ([1, 2; 3, 4; 5, 6])
232 */
FloatComplexDiagMatrix float_complex_diag_matrix_value(bool force=false) const
Definition: ov.h:854
bool is_real_type(void) const
Definition: ov.h:667
ComplexDET determinant(void) const
Definition: CMatrix.cc:1298
octave_idx_type rows(void) const
Definition: ov.h:489
FloatComplexMatrix float_complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:809
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
float rcond(void) const
OCTINTERP_API void print_usage(void)
Definition: defun.cc:52
FloatDET determinant(void) const
Definition: fMatrix.cc:1003
#define DEFUN(name, args_name, nargout_name, doc)
Definition: defun.h:46
bool is_perm_matrix(void) const
Definition: ov.h:575
DET determinant(void) const
Definition: dDiagMatrix.cc:308
FloatDET determinant(void) const
Definition: fDiagMatrix.cc:308
void err_square_matrix_required(const char *fcn, const char *name)
Definition: errwarn.cc:112
T value() const
Definition: DET.h:68
ComplexDiagMatrix complex_diag_matrix_value(bool force=false) const
Definition: ov.h:850
octave_value arg
Definition: pr-output.cc:3440
octave_idx_type determinant(void) const
Definition: PermMatrix.cc:129
JNIEnv void * args
Definition: ov-java.cc:67
octave_idx_type columns(void) const
Definition: ov.h:491
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function xample nargout(@histc)
Definition: ov-usr-fcn.cc:935
DET determinant(void) const
Definition: dSparse.cc:1131
bool is_sparse_type(void) const
Definition: ov.h:682
OCTAVE_EXPORT octave_value_list isfloat
Definition: data.cc:3327
FloatDiagMatrix float_diag_matrix_value(bool force=false) const
Definition: ov.h:847
nd deftypefn *octave_map m
Definition: ov-struct.cc:2058
Definition: DET.h:33
bool is_complex_type(void) const
Definition: ov.h:670
ComplexDET determinant(void) const
Definition: CSparse.cc:1054
octave_value retval
Definition: data.cc:6294
#define MAYBE_CAST(VAR, CLASS)
Definition: det.cc:45
float rcond(void) const
Definition: fDiagMatrix.cc:322
Definition: dMatrix.h:37
SparseComplexMatrix sparse_complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:838
Matrix matrix_value(bool frc_str_conv=false) const
Definition: ov.h:787
void err_wrong_type_arg(const char *name, const char *s)
Definition: errwarn.cc:156
FloatComplexDET determinant(void) const
double rcond(void) const
Definition: dDiagMatrix.cc:322
DET determinant(void) const
Definition: dMatrix.cc:999
double rcond(void) const
Definition: CDiagMatrix.cc:486
MatrixType matrix_type(void) const
Definition: ov.h:527
DiagMatrix diag_matrix_value(bool force=false) const
Definition: ov.h:844
ComplexDET determinant(void) const
Definition: CDiagMatrix.cc:472
bool is_empty(void) const
Definition: ov.h:542
ComplexMatrix complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:805
FloatMatrix float_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:790
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
Definition: ovl.h:100
std::complex< float > FloatComplex
Definition: oct-cmplx.h:32
PermMatrix perm_matrix_value(void) const
Definition: ov.h:857
SparseMatrix sparse_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:834
FloatComplexDET determinant(void) const
Definition: fCMatrix.cc:1298
std::complex< double > Complex
Definition: oct-cmplx.h:31
bool is_single_type(void) const
Definition: ov.h:627
bool is_diag_matrix(void) const
Definition: ov.h:572