GNU Octave
3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
Main Page
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Pages
libinterp
corefcn
pinv.cc
Go to the documentation of this file.
1
/*
2
3
Copyright (C) 1996-2013 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
#ifdef HAVE_CONFIG_H
24
#include <config.h>
25
#endif
26
27
#include "
defun.h
"
28
#include "
error.h
"
29
#include "
gripes.h
"
30
#include "
oct-obj.h
"
31
#include "
utils.h
"
32
#include "
ops.h
"
33
#include "
ov-re-diag.h
"
34
#include "
ov-cx-diag.h
"
35
#include "
ov-flt-re-diag.h
"
36
#include "
ov-flt-cx-diag.h
"
37
#include "
ov-perm.h
"
38
39
DEFUN
(pinv, args, ,
40
"-*- texinfo -*-\n\
41
@deftypefn {Built-in Function} {} pinv (@var{x})\n\
42
@deftypefnx {Built-in Function} {} pinv (@var{x}, @var{tol})\n\
43
Return the pseudoinverse of @var{x}. Singular values less than\n\
44
@var{tol} are ignored.\n\
45
\n\
46
If the second argument is omitted, it is taken to be\n\
47
\n\
48
@example\n\
49
tol = max (size (@var{x})) * sigma_max (@var{x}) * eps,\n\
50
@end example\n\
51
\n\
52
@noindent\n\
53
where @code{sigma_max (@var{x})} is the maximal singular value of @var{x}.\n\
54
@end deftypefn"
)
55
{
56
octave_value
retval;
57
58
int
nargin = args.
length
();
59
60
if
(nargin < 1 || nargin > 2)
61
{
62
print_usage
();
63
return
retval;
64
}
65
66
octave_value
arg
= args(0);
67
68
int
arg_is_empty =
empty_arg
(
"pinv"
, arg.
rows
(), arg.
columns
());
69
70
if
(arg_is_empty < 0)
71
return
retval;
72
else
if
(arg_is_empty > 0)
73
return
octave_value
(
Matrix
());
74
75
bool
isfloat = arg.
is_single_type
();
76
77
if
(arg.
is_diag_matrix
())
78
{
79
if
(nargin == 2)
80
warning
(
"pinv: tol is ignored for diagonal matrices"
);
81
82
if
(arg.
is_complex_type
())
83
{
84
if
(isfloat)
85
retval = arg.
float_complex_diag_matrix_value
().
pseudo_inverse
();
86
else
87
retval = arg.
complex_diag_matrix_value
().
pseudo_inverse
();
88
}
89
else
90
{
91
if
(isfloat)
92
retval = arg.
float_diag_matrix_value
().
pseudo_inverse
();
93
else
94
retval = arg.
diag_matrix_value
().
pseudo_inverse
();
95
}
96
}
97
else
if
(arg.
is_perm_matrix
())
98
{
99
retval = arg.
perm_matrix_value
().
inverse
();
100
}
101
else
if
(isfloat)
102
{
103
float
tol = 0.0;
104
if
(nargin == 2)
105
tol = args(1).float_value ();
106
107
if
(
error_state
)
108
return
retval;
109
110
if
(tol < 0.0)
111
{
112
error
(
"pinv: TOL must be greater than zero"
);
113
return
retval;
114
}
115
116
if
(arg.
is_real_type
())
117
{
118
FloatMatrix
m = arg.
float_matrix_value
();
119
120
if
(!
error_state
)
121
retval = m.
pseudo_inverse
(tol);
122
}
123
else
if
(arg.
is_complex_type
())
124
{
125
FloatComplexMatrix
m = arg.
float_complex_matrix_value
();
126
127
if
(!
error_state
)
128
retval = m.
pseudo_inverse
(tol);
129
}
130
else
131
{
132
gripe_wrong_type_arg
(
"pinv"
, arg);
133
}
134
}
135
else
136
{
137
double
tol = 0.0;
138
if
(nargin == 2)
139
tol = args(1).double_value ();
140
141
if
(
error_state
)
142
return
retval;
143
144
if
(tol < 0.0)
145
{
146
error
(
"pinv: TOL must be greater than zero"
);
147
return
retval;
148
}
149
150
if
(arg.
is_real_type
())
151
{
152
Matrix
m = arg.
matrix_value
();
153
154
if
(!
error_state
)
155
retval = m.
pseudo_inverse
(tol);
156
}
157
else
if
(arg.
is_complex_type
())
158
{
159
ComplexMatrix
m = arg.
complex_matrix_value
();
160
161
if
(!
error_state
)
162
retval = m.
pseudo_inverse
(tol);
163
}
164
else
165
{
166
gripe_wrong_type_arg
(
"pinv"
, arg);
167
}
168
}
169
170
return
retval;
171
}
172
173
/*
174
%!shared a, b, tol, hitol, d, u, x, y
175
%! a = reshape (rand*[1:16], 4, 4); # Rank 2 matrix
176
%! b = pinv (a);
177
%! tol = 4e-14;
178
%! hitol = 40*sqrt (eps);
179
%! d = diag ([rand, rand, hitol, hitol]);
180
%! u = rand (4); # Could be singular by freak accident
181
%! x = inv (u)*d*u;
182
%! y = pinv (x, sqrt (eps));
183
%!
184
%!assert (a*b*a, a, tol)
185
%!assert (b*a*b, b, tol)
186
%!assert ((b*a)', b*a, tol)
187
%!assert ((a*b)', a*b, tol)
188
%!assert (x*y*x, x, -hitol)
189
%!assert (y*x*y, y, -hitol)
190
%!assert ((x*y)', x*y, hitol)
191
%!assert ((y*x)', y*x, hitol)
192
*/
Generated on Mon Dec 30 2013 03:04:28 for GNU Octave by
1.8.1.2