Mercurial > hg > octave-nkf
changeset 8840:c690e3772583
support diagonal matrices in pinv
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Mon, 23 Feb 2009 14:54:56 +0100 |
parents | fcba62cc4549 |
children | c74389115610 |
files | liboctave/CDiagMatrix.cc liboctave/CDiagMatrix.h liboctave/ChangeLog liboctave/dDiagMatrix.cc liboctave/dDiagMatrix.h liboctave/fCDiagMatrix.cc liboctave/fCDiagMatrix.h liboctave/fDiagMatrix.cc liboctave/fDiagMatrix.h src/ChangeLog src/DLD-FUNCTIONS/pinv.cc |
diffstat | 11 files changed, 156 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/CDiagMatrix.cc +++ b/liboctave/CDiagMatrix.cc @@ -387,6 +387,26 @@ return retval; } +ComplexDiagMatrix +ComplexDiagMatrix::pseudo_inverse (void) const +{ + octave_idx_type r = rows (); + octave_idx_type c = cols (); + octave_idx_type len = length (); + + ComplexDiagMatrix retval (c, r); + + for (octave_idx_type i = 0; i < len; i++) + { + if (elem (i, i) != 0.0) + retval.elem (i, i) = 1.0 / elem (i, i); + else + retval.elem (i, i) = 0.0; + } + + return retval; +} + bool ComplexDiagMatrix::all_elements_are_real (void) const {
--- a/liboctave/CDiagMatrix.h +++ b/liboctave/CDiagMatrix.h @@ -112,6 +112,7 @@ ComplexDiagMatrix inverse (octave_idx_type& info) const; ComplexDiagMatrix inverse (void) const; + ComplexDiagMatrix pseudo_inverse (void) const; bool all_elements_are_real (void) const;
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,14 @@ +2009-02-23 Jaroslav Hajek <highegg@gmail.com> + + * dDiagMatrix.cc (DiagMatrix::pseudo_inverse): New method. + * dDiagMatrix.h: Declare it. + * fDiagMatrix.cc (FloatDiagMatrix::pseudo_inverse): New method. + * fDiagMatrix.h: Declare it. + * CDiagMatrix.cc (ComplexDiagMatrix::pseudo_inverse): New method. + * CDiagMatrix.h: Declare it. + * fCDiagMatrix.cc (FloatComplexDiagMatrix::pseudo_inverse): New method. + * fCDiagMatrix.h: Declare it. + 2009-02-20 Jaroslav Hajek <highegg@gmail.com> * oct-sort.h (octave_sort<T>::MergeState::MergeState): New
--- a/liboctave/dDiagMatrix.cc +++ b/liboctave/dDiagMatrix.cc @@ -303,6 +303,26 @@ return retval; } +DiagMatrix +DiagMatrix::pseudo_inverse (void) const +{ + octave_idx_type r = rows (); + octave_idx_type c = cols (); + octave_idx_type len = length (); + + DiagMatrix retval (c, r); + + for (octave_idx_type i = 0; i < len; i++) + { + if (elem (i, i) != 0.0) + retval.elem (i, i) = 1.0 / elem (i, i); + else + retval.elem (i, i) = 0.0; + } + + return retval; +} + // diagonal matrix by diagonal matrix -> diagonal matrix operations // diagonal matrix by diagonal matrix -> diagonal matrix operations
--- a/liboctave/dDiagMatrix.h +++ b/liboctave/dDiagMatrix.h @@ -94,6 +94,7 @@ DiagMatrix inverse (void) const; DiagMatrix inverse (octave_idx_type& info) const; + DiagMatrix pseudo_inverse (void) const; // other operations
--- a/liboctave/fCDiagMatrix.cc +++ b/liboctave/fCDiagMatrix.cc @@ -387,6 +387,26 @@ return retval; } +FloatComplexDiagMatrix +FloatComplexDiagMatrix::pseudo_inverse (void) const +{ + octave_idx_type r = rows (); + octave_idx_type c = cols (); + octave_idx_type len = length (); + + FloatComplexDiagMatrix retval (c, r); + + for (octave_idx_type i = 0; i < len; i++) + { + if (elem (i, i) != 0.0f) + retval.elem (i, i) = 1.0f / elem (i, i); + else + retval.elem (i, i) = 0.0f; + } + + return retval; +} + bool FloatComplexDiagMatrix::all_elements_are_real (void) const {
--- a/liboctave/fCDiagMatrix.h +++ b/liboctave/fCDiagMatrix.h @@ -112,6 +112,7 @@ FloatComplexDiagMatrix inverse (octave_idx_type& info) const; FloatComplexDiagMatrix inverse (void) const; + FloatComplexDiagMatrix pseudo_inverse (void) const; bool all_elements_are_real (void) const;
--- a/liboctave/fDiagMatrix.cc +++ b/liboctave/fDiagMatrix.cc @@ -303,6 +303,26 @@ return retval; } +FloatDiagMatrix +FloatDiagMatrix::pseudo_inverse (void) const +{ + octave_idx_type r = rows (); + octave_idx_type c = cols (); + octave_idx_type len = length (); + + FloatDiagMatrix retval (c, r); + + for (octave_idx_type i = 0; i < len; i++) + { + if (elem (i, i) != 0.0f) + retval.elem (i, i) = 1.0f / elem (i, i); + else + retval.elem (i, i) = 0.0f; + } + + return retval; +} + // diagonal matrix by diagonal matrix -> diagonal matrix operations // diagonal matrix by diagonal matrix -> diagonal matrix operations
--- a/liboctave/fDiagMatrix.h +++ b/liboctave/fDiagMatrix.h @@ -94,6 +94,7 @@ FloatDiagMatrix inverse (void) const; FloatDiagMatrix inverse (octave_idx_type& info) const; + FloatDiagMatrix pseudo_inverse (void) const; // other operations
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2009-02-23 Jaroslav Hajek <highegg@gmail.com> + + * DLD-FUNCTIONS/pinv.cc: Support diagonal and permutation matrices. + 2008-02-21 David Bateman <dbateman@free.fr> * OPERATORS/op-cs-scm.cc, OPERATORS/op-cs-sm.cc, OPERATORS/op-s-scm.cc,
--- a/src/DLD-FUNCTIONS/pinv.cc +++ b/src/DLD-FUNCTIONS/pinv.cc @@ -29,6 +29,13 @@ #include "gripes.h" #include "oct-obj.h" #include "utils.h" +#include "ops.h" +#include "ov-re-diag.h" +#include "ov-cx-diag.h" +#include "ov-flt-re-diag.h" +#include "ov-flt-cx-diag.h" +#include "ov-perm.h" +#include "ov-flt-perm.h" DEFUN_DLD (pinv, args, , "-*- texinfo -*-\n\ @@ -65,7 +72,56 @@ else if (arg_is_empty > 0) return octave_value (Matrix ()); - if (arg.is_single_type ()) + bool isfloat = arg.is_single_type (); + + if (arg.is_diag_matrix ()) + { + if (nargin == 2) + warning ("pinv: tol is ignored for diagonal matrices"); + + const octave_base_value& a = arg.get_rep (); + if (arg.is_complex_type ()) + { + if (isfloat) + { + CAST_CONV_ARG (const octave_float_complex_diag_matrix&); + retval = v.float_complex_diag_matrix_value ().pseudo_inverse (); + } + else + { + CAST_CONV_ARG (const octave_complex_diag_matrix&); + retval = v.complex_diag_matrix_value ().pseudo_inverse (); + } + } + else + { + if (isfloat) + { + CAST_CONV_ARG (const octave_float_diag_matrix&); + retval = v.float_diag_matrix_value ().pseudo_inverse (); + } + else + { + CAST_CONV_ARG (const octave_diag_matrix&); + retval = v.diag_matrix_value ().pseudo_inverse (); + } + } + } + else if (arg.is_perm_matrix ()) + { + const octave_base_value& a = arg.get_rep (); + if (isfloat) + { + CAST_CONV_ARG (const octave_float_perm_matrix&); + retval = v.perm_matrix_value ().inverse (); + } + else + { + CAST_CONV_ARG (const octave_perm_matrix&); + retval = v.perm_matrix_value ().inverse (); + } + } + else if (isfloat) { float tol = 0.0; if (nargin == 2)