Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dlib
Commits
dd0dacb8
"examples/git@developer.sourcefind.cn:OpenDAS/dgl.git" did not exist on "04d4680d5b01ff61b11a84c2182234324597d559"
Commit
dd0dacb8
authored
Feb 01, 2014
by
Davis King
Browse files
Gave pinv() an optional tolerance option.
parent
27136609
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
75 additions
and
7 deletions
+75
-7
dlib/matrix/matrix_la.h
dlib/matrix/matrix_la.h
+32
-6
dlib/matrix/matrix_la_abstract.h
dlib/matrix/matrix_la_abstract.h
+9
-1
dlib/test/matrix.cpp
dlib/test/matrix.cpp
+34
-0
No files found.
dlib/matrix/matrix_la.h
View file @
dd0dacb8
...
@@ -1290,6 +1290,25 @@ convergence:
...
@@ -1290,6 +1290,25 @@ convergence:
return
matrix_diag_op
<
op
>
(
op
(
reciprocal
(
diag
(
m
))));
return
matrix_diag_op
<
op
>
(
op
(
reciprocal
(
diag
(
m
))));
}
}
// ----------------------------------------------------------------------------------------
template
<
typename
EXP
>
const
matrix_diag_op
<
op_diag_inv
<
EXP
>
>
pinv
(
const
matrix_diag_exp
<
EXP
>&
m
,
double
tol
)
{
DLIB_ASSERT
(
tol
>=
0
,
"
\t
const matrix_exp::type pinv(const matrix_exp& m)"
<<
"
\n\t
tol can't be negative"
<<
"
\n\t
tol: "
<<
tol
);
typedef
op_diag_inv
<
EXP
>
op
;
return
matrix_diag_op
<
op
>
(
op
(
reciprocal
(
round_zeros
(
diag
(
m
),
tol
))));
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template
<
typename
EXP
>
template
<
typename
EXP
>
...
@@ -1519,7 +1538,8 @@ convergence:
...
@@ -1519,7 +1538,8 @@ convergence:
typename
EXP
typename
EXP
>
>
const
matrix
<
typename
EXP
::
type
,
EXP
::
NC
,
EXP
::
NR
,
typename
EXP
::
mem_manager_type
>
pinv_helper
(
const
matrix
<
typename
EXP
::
type
,
EXP
::
NC
,
EXP
::
NR
,
typename
EXP
::
mem_manager_type
>
pinv_helper
(
const
matrix_exp
<
EXP
>&
m
const
matrix_exp
<
EXP
>&
m
,
double
tol
)
)
/*!
/*!
ensures
ensures
...
@@ -1541,8 +1561,8 @@ convergence:
...
@@ -1541,8 +1561,8 @@ convergence:
const
double
machine_eps
=
std
::
numeric_limits
<
typename
EXP
::
type
>::
epsilon
();
const
double
machine_eps
=
std
::
numeric_limits
<
typename
EXP
::
type
>::
epsilon
();
// compute a reasonable epsilon below which we round to zero before doing the
// compute a reasonable epsilon below which we round to zero before doing the
// reciprocal
// reciprocal
. Unless a non-zero tol is given then we just use tol.
const
double
eps
=
machine_eps
*
std
::
max
(
m
.
nr
(),
m
.
nc
())
*
max
(
w
);
const
double
eps
=
(
tol
!=
0
)
?
tol
:
machine_eps
*
std
::
max
(
m
.
nr
(),
m
.
nc
())
*
max
(
w
);
// now compute the pseudoinverse
// now compute the pseudoinverse
return
tmp
(
scale_columns
(
v
,
reciprocal
(
round_zeros
(
w
,
eps
))))
*
trans
(
u
);
return
tmp
(
scale_columns
(
v
,
reciprocal
(
round_zeros
(
w
,
eps
))))
*
trans
(
u
);
...
@@ -1552,15 +1572,21 @@ convergence:
...
@@ -1552,15 +1572,21 @@ convergence:
typename
EXP
typename
EXP
>
>
const
matrix
<
typename
EXP
::
type
,
EXP
::
NC
,
EXP
::
NR
,
typename
EXP
::
mem_manager_type
>
pinv
(
const
matrix
<
typename
EXP
::
type
,
EXP
::
NC
,
EXP
::
NR
,
typename
EXP
::
mem_manager_type
>
pinv
(
const
matrix_exp
<
EXP
>&
m
const
matrix_exp
<
EXP
>&
m
,
double
tol
=
0
)
)
{
{
DLIB_ASSERT
(
tol
>=
0
,
"
\t
const matrix_exp::type pinv(const matrix_exp& m)"
<<
"
\n\t
tol can't be negative"
<<
"
\n\t
tol: "
<<
tol
);
// if m has more columns then rows then it is more efficient to
// if m has more columns then rows then it is more efficient to
// compute the pseudo-inverse of its transpose (given the way I'm doing it below).
// compute the pseudo-inverse of its transpose (given the way I'm doing it below).
if
(
m
.
nc
()
>
m
.
nr
())
if
(
m
.
nc
()
>
m
.
nr
())
return
trans
(
pinv_helper
(
trans
(
m
)));
return
trans
(
pinv_helper
(
trans
(
m
)
,
tol
));
else
else
return
pinv_helper
(
m
);
return
pinv_helper
(
m
,
tol
);
}
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
...
...
dlib/matrix/matrix_la_abstract.h
View file @
dd0dacb8
...
@@ -31,12 +31,20 @@ namespace dlib
...
@@ -31,12 +31,20 @@ namespace dlib
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
const
matrix
pinv
(
const
matrix
pinv
(
const
matrix_exp
&
m
const
matrix_exp
&
m
,
double
tol
=
0
);
);
/*!
/*!
requires
- tol >= 0
ensures
ensures
- returns the Moore-Penrose pseudoinverse of m.
- returns the Moore-Penrose pseudoinverse of m.
- The returned matrix has m.nc() rows and m.nr() columns.
- The returned matrix has m.nc() rows and m.nr() columns.
- if (tol == 0) then
- singular values less than max(m.nr(),m.nc()) times the machine epsilon
times the largest singular value are ignored.
- else
- singular values less than tol are ignored.
!*/
!*/
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
...
...
dlib/test/matrix.cpp
View file @
dd0dacb8
...
@@ -67,6 +67,40 @@ namespace
...
@@ -67,6 +67,40 @@ namespace
DLIB_TEST
((
equal
(
round_zeros
(
m
*
mi
,
0.000001
)
,
identity_matrix
<
double
,
5
>
())));
DLIB_TEST
((
equal
(
round_zeros
(
m
*
mi
,
0.000001
)
,
identity_matrix
<
double
,
5
>
())));
DLIB_TEST
((
equal
(
round_zeros
(
mi
*
m
,
0.000001
)
,
identity_matrix
(
m
))));
DLIB_TEST
((
equal
(
round_zeros
(
mi
*
m
,
0.000001
)
,
identity_matrix
(
m
))));
DLIB_TEST
((
equal
(
round_zeros
(
m
*
mi
,
0.000001
)
,
identity_matrix
(
m
))));
DLIB_TEST
((
equal
(
round_zeros
(
m
*
mi
,
0.000001
)
,
identity_matrix
(
m
))));
mi
=
pinv
(
m
,
1e-12
);
DLIB_TEST
(
mi
.
nr
()
==
m
.
nc
());
DLIB_TEST
(
mi
.
nc
()
==
m
.
nr
());
DLIB_TEST
((
equal
(
round_zeros
(
mi
*
m
,
0.000001
)
,
identity_matrix
<
double
,
5
>
())));
DLIB_TEST
((
equal
(
round_zeros
(
m
*
mi
,
0.000001
)
,
identity_matrix
<
double
,
5
>
())));
DLIB_TEST
((
equal
(
round_zeros
(
mi
*
m
,
0.000001
)
,
identity_matrix
(
m
))));
DLIB_TEST
((
equal
(
round_zeros
(
m
*
mi
,
0.000001
)
,
identity_matrix
(
m
))));
m
=
diagm
(
diag
(
m
));
mi
=
pinv
(
diagm
(
diag
(
m
)),
1e-12
);
DLIB_TEST
(
mi
.
nr
()
==
m
.
nc
());
DLIB_TEST
(
mi
.
nc
()
==
m
.
nr
());
DLIB_TEST
((
equal
(
round_zeros
(
mi
*
m
,
0.000001
)
,
identity_matrix
<
double
,
5
>
())));
DLIB_TEST
((
equal
(
round_zeros
(
m
*
mi
,
0.000001
)
,
identity_matrix
<
double
,
5
>
())));
DLIB_TEST
((
equal
(
round_zeros
(
mi
*
m
,
0.000001
)
,
identity_matrix
(
m
))));
DLIB_TEST
((
equal
(
round_zeros
(
m
*
mi
,
0.000001
)
,
identity_matrix
(
m
))));
mi
=
pinv
(
m
,
0
);
DLIB_TEST
(
mi
.
nr
()
==
m
.
nc
());
DLIB_TEST
(
mi
.
nc
()
==
m
.
nr
());
DLIB_TEST
((
equal
(
round_zeros
(
mi
*
m
,
0.000001
)
,
identity_matrix
<
double
,
5
>
())));
DLIB_TEST
((
equal
(
round_zeros
(
m
*
mi
,
0.000001
)
,
identity_matrix
<
double
,
5
>
())));
DLIB_TEST
((
equal
(
round_zeros
(
mi
*
m
,
0.000001
)
,
identity_matrix
(
m
))));
DLIB_TEST
((
equal
(
round_zeros
(
m
*
mi
,
0.000001
)
,
identity_matrix
(
m
))));
m
=
diagm
(
diag
(
m
));
mi
=
pinv
(
diagm
(
diag
(
m
)),
0
);
DLIB_TEST
(
mi
.
nr
()
==
m
.
nc
());
DLIB_TEST
(
mi
.
nc
()
==
m
.
nr
());
DLIB_TEST
((
equal
(
round_zeros
(
mi
*
m
,
0.000001
)
,
identity_matrix
<
double
,
5
>
())));
DLIB_TEST
((
equal
(
round_zeros
(
m
*
mi
,
0.000001
)
,
identity_matrix
<
double
,
5
>
())));
DLIB_TEST
((
equal
(
round_zeros
(
mi
*
m
,
0.000001
)
,
identity_matrix
(
m
))));
DLIB_TEST
((
equal
(
round_zeros
(
m
*
mi
,
0.000001
)
,
identity_matrix
(
m
))));
}
}
{
{
matrix
<
double
,
5
,
0
,
MM
>
m
(
5
,
5
);
matrix
<
double
,
5
,
0
,
MM
>
m
(
5
,
5
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment