15 #include "IncrementalSVDStandard.h"
16 #include "utils/HDFDatabase.h"
25 IncrementalSVDStandard::IncrementalSVDStandard(
27 const std::string& basis_file_name) :
37 if (options.restore_state && d_state_database) {
39 d_state_database->close();
40 delete d_state_database;
47 IncrementalSVDStandard::~IncrementalSVDStandard()
55 if (d_save_state && (!isFirstSample())) {
58 d_state_database->create(d_state_file_name);
63 IncrementalSVDStandard::buildInitialSVD(
69 d_S.reset(
new Vector(1,
false));
70 Vector u_vec(u, d_dim,
true);
71 double norm_u = u_vec.norm();
72 d_S->item(0) = norm_u;
75 d_U.reset(
new Matrix(d_dim, 1,
true));
76 for (
int i = 0; i < d_dim; ++i) {
77 d_U->item(i, 0) = u[i]/norm_u;
81 if (d_update_right_SV) {
82 d_W.reset(
new Matrix(1, 1,
false));
83 d_W->item(0, 0) = 1.0;
94 IncrementalSVDStandard::computeBasis()
97 d_basis.reset(
new Matrix(*d_U));
99 if (d_update_right_SV)
101 d_basis_right.reset(
new Matrix(*d_W));
106 IncrementalSVDStandard::addLinearlyDependentSample(
109 const Matrix & sigma)
113 Matrix Amod(d_num_samples, d_num_samples,
false);
114 for (
int row = 0; row < d_num_samples; ++row) {
115 for (
int col = 0; col < d_num_samples; ++col) {
116 Amod.item(row, col) = A.item(row, col);
119 d_S->item(col) = sigma.item(row, col);
125 Matrix *U_times_Amod =
new Matrix(d_U->numRows(), Amod.numColumns(),
false);
126 d_U->mult(Amod, *U_times_Amod);
127 d_U.reset(U_times_Amod);
130 if (d_update_right_SV) {
131 Matrix *new_d_W =
new Matrix(d_num_rows_of_W+1, d_num_samples,
false);
132 for (
int row = 0; row < d_num_rows_of_W; ++row) {
133 for (
int col = 0; col < d_num_samples; ++col) {
134 double new_d_W_entry = 0.0;
135 for (
int entry = 0; entry < d_num_samples; ++entry) {
136 new_d_W_entry += d_W->item(row, entry)*W.item(entry, col);
138 new_d_W->item(row, col) = new_d_W_entry;
141 for (
int col = 0; col < d_num_samples; ++col) {
142 new_d_W->item(d_num_rows_of_W, col) = W.item(d_num_samples, col);
150 if (d_num_samples > d_total_dim) {
151 max_U_dim = d_num_samples;
154 max_U_dim = d_total_dim;
156 if (fabs(checkOrthogonality(*d_U)) >
157 std::numeric_limits<double>::epsilon()*
static_cast<double>(max_U_dim)) {
158 d_U->orthogonalize();
163 IncrementalSVDStandard::addNewSample(
167 const Matrix & sigma)
170 Matrix tmp(d_dim, d_num_samples+1,
true);
171 for (
int row = 0; row < d_dim; ++row) {
172 for (
int col = 0; col < d_num_samples; ++col) {
173 tmp.item(row, col) = d_U->item(row, col);
175 tmp.item(row, d_num_samples) = j.item(row);
179 if (d_update_right_SV) {
180 Matrix *new_d_W =
new Matrix(d_num_rows_of_W+1, d_num_samples+1,
false);
181 for (
int row = 0; row < d_num_rows_of_W; ++row) {
182 for (
int col = 0; col < d_num_samples+1; ++col) {
183 double new_d_W_entry = 0.0;
184 for (
int entry = 0; entry < d_num_samples; ++entry) {
185 new_d_W_entry += d_W->item(row, entry)*W.item(entry, col);
187 new_d_W->item(row, col) = new_d_W_entry;
190 for (
int col = 0; col < d_num_samples+1; ++col) {
191 new_d_W->item(d_num_rows_of_W, col) = W.item(d_num_samples, col);
196 int num_dim = std::min(sigma.numRows(), sigma.numColumns());
197 d_S.reset(
new Vector(num_dim,
false));
198 for (
int i = 0; i < num_dim; i++) {
199 d_S->item(i) = sigma.item(i,i);
208 if (d_num_samples > d_total_dim) {
209 max_U_dim = d_num_samples;
212 max_U_dim = d_total_dim;
214 if (fabs(checkOrthogonality(*d_U)) >
215 std::numeric_limits<double>::epsilon()*
static_cast<double>(max_U_dim)) {
216 d_U->orthogonalize();
218 if (d_update_right_SV) {
219 if (fabs(checkOrthogonality(*d_W)) >
220 std::numeric_limits<double>::epsilon()*d_num_samples) {
221 d_W->orthogonalize();