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
bf2edbec
Commit
bf2edbec
authored
Aug 26, 2012
by
Davis King
Browse files
Added dpca_matrix_of_size() to discriminant_pca. It allows the user
to easily get a transformation matrix of a particular size.
parent
d9746486
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
150 additions
and
45 deletions
+150
-45
dlib/statistics/dpca.h
dlib/statistics/dpca.h
+100
-45
dlib/statistics/dpca_abstract.h
dlib/statistics/dpca_abstract.h
+41
-0
dlib/test/discriminant_pca.cpp
dlib/test/discriminant_pca.cpp
+9
-0
No files found.
dlib/statistics/dpca.h
View file @
bf2edbec
...
...
@@ -239,6 +239,25 @@ namespace dlib
return
dpca_mat
;
}
const
general_matrix
dpca_matrix_of_size
(
const
long
num_rows
)
{
// make sure requires clause is not broken
DLIB_ASSERT
(
0
<
num_rows
&&
num_rows
<=
in_vector_size
(),
"
\t
general_matrix discriminant_pca::dpca_matrix_of_size()"
<<
"
\n\t
Invalid inputs were given to this function"
<<
"
\n\t
num_rows: "
<<
num_rows
<<
"
\n\t
in_vector_size(): "
<<
in_vector_size
()
<<
"
\n\t
this: "
<<
this
);
general_matrix
dpca_mat
;
general_matrix
eigenvalues
;
dpca_matrix_of_size
(
dpca_mat
,
eigenvalues
,
num_rows
);
return
dpca_mat
;
}
void
dpca_matrix
(
general_matrix
&
dpca_mat
,
general_matrix
&
eigenvalues
,
...
...
@@ -254,53 +273,25 @@ namespace dlib
<<
"
\n\t
this: "
<<
this
);
general_matrix
cov
;
// now combine the three measures of variance into a single matrix by using the
// within_weight and between_weight weights.
cov
=
get_total_covariance_matrix
();
if
(
within_count
!=
0
)
cov
-=
within_weight
*
within_cov
/
within_count
;
if
(
between_count
!=
0
)
cov
+=
between_weight
*
between_cov
/
between_count
;
eigenvalue_decomposition
<
general_matrix
>
eig
(
make_symmetric
(
cov
));
eigenvalues
=
eig
.
get_real_eigenvalues
();
dpca_mat
=
eig
.
get_pseudo_v
();
// sort the eigenvalues and eigenvectors so that the biggest eigenvalues come first
rsort_columns
(
dpca_mat
,
eigenvalues
);
// Some of the eigenvalues might be negative. So first lets zero those out
// so they won't get considered.
eigenvalues
=
pointwise_multiply
(
eigenvalues
>
0
,
eigenvalues
);
// figure out how many eigenvectors we want in our dpca matrix
const
double
thresh
=
sum
(
eigenvalues
)
*
eps
;
long
num_vectors
=
0
;
double
total
=
0
;
for
(
long
r
=
0
;
r
<
eigenvalues
.
size
()
&&
total
<
thresh
;
++
r
)
{
// Don't even think about looking at eigenvalues that are 0. If we go this
// far then we have all we need.
if
(
eigenvalues
(
r
)
==
0
)
break
;
++
num_vectors
;
total
+=
eigenvalues
(
r
);
compute_dpca_matrix
(
dpca_mat
,
eigenvalues
,
eps
,
0
);
}
if
(
num_vectors
==
0
)
throw
discriminant_pca_error
(
"While performing discriminant_pca, all eigenvalues were negative or 0"
);
// So now we know we want to use num_vectors of the first eigenvectors. So
// pull those out and discard the rest.
dpca_mat
=
trans
(
colm
(
dpca_mat
,
range
(
0
,
num_vectors
-
1
)));
// also clip off the eigenvalues we aren't using
eigenvalues
=
rowm
(
eigenvalues
,
range
(
0
,
num_vectors
-
1
));
void
dpca_matrix_of_size
(
general_matrix
&
dpca_mat
,
general_matrix
&
eigenvalues
,
const
long
num_rows
)
{
// make sure requires clause is not broken
DLIB_ASSERT
(
0
<
num_rows
&&
num_rows
<=
in_vector_size
(),
"
\t
general_matrix discriminant_pca::dpca_matrix_of_size()"
<<
"
\n\t
Invalid inputs were given to this function"
<<
"
\n\t
num_rows: "
<<
num_rows
<<
"
\n\t
in_vector_size(): "
<<
in_vector_size
()
<<
"
\n\t
this: "
<<
this
);
compute_dpca_matrix
(
dpca_mat
,
eigenvalues
,
1
,
num_rows
);
}
void
swap
(
...
...
@@ -419,6 +410,70 @@ namespace dlib
private:
void
compute_dpca_matrix
(
general_matrix
&
dpca_mat
,
general_matrix
&
eigenvalues
,
const
double
eps
,
long
num_rows
)
const
{
general_matrix
cov
;
// now combine the three measures of variance into a single matrix by using the
// within_weight and between_weight weights.
cov
=
get_total_covariance_matrix
();
if
(
within_count
!=
0
)
cov
-=
within_weight
*
within_cov
/
within_count
;
if
(
between_count
!=
0
)
cov
+=
between_weight
*
between_cov
/
between_count
;
eigenvalue_decomposition
<
general_matrix
>
eig
(
make_symmetric
(
cov
));
eigenvalues
=
eig
.
get_real_eigenvalues
();
dpca_mat
=
eig
.
get_pseudo_v
();
// sort the eigenvalues and eigenvectors so that the biggest eigenvalues come first
rsort_columns
(
dpca_mat
,
eigenvalues
);
long
num_vectors
=
0
;
if
(
num_rows
==
0
)
{
// Some of the eigenvalues might be negative. So first lets zero those out
// so they won't get considered.
eigenvalues
=
pointwise_multiply
(
eigenvalues
>
0
,
eigenvalues
);
// figure out how many eigenvectors we want in our dpca matrix
const
double
thresh
=
sum
(
eigenvalues
)
*
eps
;
double
total
=
0
;
for
(
long
r
=
0
;
r
<
eigenvalues
.
size
()
&&
total
<
thresh
;
++
r
)
{
// Don't even think about looking at eigenvalues that are 0. If we go this
// far then we have all we need.
if
(
eigenvalues
(
r
)
==
0
)
break
;
++
num_vectors
;
total
+=
eigenvalues
(
r
);
}
if
(
num_vectors
==
0
)
throw
discriminant_pca_error
(
"While performing discriminant_pca, all eigenvalues were negative or 0"
);
}
else
{
num_vectors
=
num_rows
;
}
// So now we know we want to use num_vectors of the first eigenvectors. So
// pull those out and discard the rest.
dpca_mat
=
trans
(
colm
(
dpca_mat
,
range
(
0
,
num_vectors
-
1
)));
// also clip off the eigenvalues we aren't using
eigenvalues
=
rowm
(
eigenvalues
,
range
(
0
,
num_vectors
-
1
));
}
general_matrix
get_total_covariance_matrix
(
)
const
/*!
...
...
dlib/statistics/dpca_abstract.h
View file @
bf2edbec
...
...
@@ -240,6 +240,47 @@ namespace dlib
that prevents this algorithm from working properly.
!*/
const
general_matrix
dpca_matrix_of_size
(
const
long
num_rows
);
/*!
requires
- 0 < num_rows <= in_vector_size()
ensures
- computes and returns the matrix MAT given by dpca_matrix_of_size(MAT,eigen,num_rows).
That is, this function returns the dpca_matrix computed by the function
defined below.
- Note that MAT is the desired linear transformation matrix. That is,
multiplying a vector by MAT performs the desired linear dimensionality
reduction to num_rows dimensions.
!*/
void
dpca_matrix_of_size
(
general_matrix
&
dpca_mat
,
general_matrix
&
eigenvalues
,
const
long
num_rows
);
/*!
requires
- 0 < num_rows <= in_vector_size()
ensures
- is_col_vector(#eigenvalues) == true
- #dpca_mat.nr() == eigenvalues.size()
- #dpca_mat.nr() == num_rows
- #dpca_mat.nc() == in_vector_size()
- rowm(#dpca_mat,i) represents the ith eigenvector of the S matrix described
in the class description and its eigenvalue is given by eigenvalues(i).
- The values in #eigenvalues might be positive or negative. Additionally, the
eigenvalues are in sorted order with the largest eigenvalue stored at
eigenvalues(0).
- (#dpca_mat)*trans(#dpca_mat) == identity_matrix.
(i.e. the rows of the dpca_matrix are all unit length vectors and are mutually
orthogonal)
- Note that #dpca_mat is the desired linear transformation matrix. That is,
multiplying a vector by #dpca_mat performs the desired linear dimensionality
reduction to num_rows dimensions.
!*/
const
discriminant_pca
operator
+
(
const
discriminant_pca
&
item
)
const
;
...
...
dlib/test/discriminant_pca.cpp
View file @
bf2edbec
...
...
@@ -80,6 +80,15 @@ namespace
DLIB_TEST
(
last
>=
eig
(
i
));
}
{
matrix
<
double
>
mat
=
dpca
.
dpca_matrix_of_size
(
4
);
DLIB_TEST
(
equal
(
mat
*
trans
(
mat
),
identity_matrix
<
double
>
(
4
)));
}
{
matrix
<
double
>
mat
=
dpca
.
dpca_matrix_of_size
(
3
);
DLIB_TEST
(
equal
(
mat
*
trans
(
mat
),
identity_matrix
<
double
>
(
3
)));
}
dpca
.
set_within_class_weight
(
5
);
dpca
.
set_between_class_weight
(
6
);
...
...
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