14 #include "IncrementalSVDFastUpdate.h"
15 #include "utils/HDFDatabase.h"
24 IncrementalSVDFastUpdate::IncrementalSVDFastUpdate(
26 const std::string& basis_file_name) :
31 d_singular_value_tol(options.singular_value_tol)
33 CAROM_VERIFY(options.singular_value_tol >= 0);
40 if (options.restore_state && d_state_database) {
43 d_state_database->getInteger(
"Up_num_rows", num_rows);
45 d_state_database->getInteger(
"Up_num_cols", num_cols);
46 d_Up =
new Matrix(num_rows, num_cols,
true);
47 d_state_database->getDoubleArray(
"Up",
52 d_state_database->close();
53 delete d_state_database;
60 IncrementalSVDFastUpdate::~IncrementalSVDFastUpdate()
68 if (d_save_state && (!isFirstSample())) {
71 d_state_database->create(d_state_file_name);
74 int num_rows = d_Up->numRows();
75 d_state_database->putInteger(
"Up_num_rows", num_rows);
76 int num_cols = d_Up->numColumns();
77 d_state_database->putInteger(
"Up_num_cols", num_cols);
78 d_state_database->putDoubleArray(
"Up",
90 IncrementalSVDFastUpdate::buildInitialSVD(
96 d_S =
new Vector(1,
false);
97 Vector u_vec(u, d_dim,
true);
98 double norm_u = u_vec.norm();
99 d_S->item(0) = norm_u;
102 d_Up =
new Matrix(1, 1,
false);
103 d_Up->item(0, 0) = 1.0;
106 d_U =
new Matrix(d_dim, 1,
true);
107 for (
int i = 0; i < d_dim; ++i) {
108 d_U->item(i, 0) = u[i]/norm_u;
112 if (d_update_right_SV) {
113 d_W =
new Matrix(1, 1,
false);
114 d_W->item(0, 0) = 1.0;
127 IncrementalSVDFastUpdate::computeBasis()
129 d_basis = d_U->mult(d_Up);
130 if(d_update_right_SV)
132 delete d_basis_right;
133 d_basis_right =
new Matrix(*d_W);
137 std::cout <<
"d_num_samples = " << d_num_samples <<
"\n";
138 std::cout <<
"d_num_rows_of_W = " << d_num_rows_of_W <<
"\n";
139 std::cout <<
"d_singular_value_tol = " << d_singular_value_tol <<
"\n";
140 std::cout <<
"smallest SV = " << d_S->item(d_num_samples-1) <<
"\n";
141 if (d_num_samples > 1) {
142 std::cout <<
"next smallest SV = " << d_S->item(d_num_samples-2) <<
"\n";
146 if ( (d_singular_value_tol != 0.0) &&
147 (d_S->item(d_num_samples-1) < d_singular_value_tol) &&
148 (d_num_samples != 1) ) {
150 if (d_rank == 0) std::cout <<
"removing a small singular value!\n";
152 Matrix* d_basis_new =
new Matrix(d_dim, d_num_samples-1,
153 d_basis->distributed());
154 for (
int row = 0; row < d_dim; ++row) {
155 for (
int col = 0; col < d_num_samples-1; ++col) {
156 d_basis_new->item(row, col) = d_basis->item(row,col);
160 d_basis = d_basis_new;
162 if (d_update_right_SV)
164 Matrix* d_basis_right_new =
new Matrix(d_num_rows_of_W, d_num_samples-1,
165 d_basis_right->distributed());
166 for (
int row = 0; row < d_num_rows_of_W; ++row) {
167 for (
int col = 0; col < d_num_samples-1; ++col) {
168 d_basis_right_new->item(row, col) = d_basis_right->item(row,col);
171 delete d_basis_right;
172 d_basis_right = d_basis_right_new;
178 if (fabs(checkOrthogonality(d_basis)) >
179 std::numeric_limits<double>::epsilon()*
static_cast<double>(d_num_samples)) {
180 d_basis->orthogonalize();
182 if(d_update_right_SV)
184 if (fabs(checkOrthogonality(d_basis_right)) >
185 std::numeric_limits<double>::epsilon()*d_num_samples) {
186 d_basis_right->orthogonalize();
193 IncrementalSVDFastUpdate::addLinearlyDependentSample(
198 CAROM_VERIFY(A != 0);
199 CAROM_VERIFY(sigma != 0);
203 Matrix Amod(d_num_samples, d_num_samples,
false);
204 for (
int row = 0; row < d_num_samples; ++row) {
205 for (
int col = 0; col < d_num_samples; ++col) {
206 Amod.item(row, col) = A->item(row, col);
209 d_S->item(col) = sigma->item(row, col);
215 Matrix* Up_times_Amod = d_Up->mult(Amod);
217 d_Up = Up_times_Amod;
220 if (d_update_right_SV) {
226 new_d_W =
new Matrix(d_num_rows_of_W+1, d_num_samples,
false);
227 for (
int row = 0; row < d_num_rows_of_W; ++row) {
228 for (
int col = 0; col < d_num_samples; ++col) {
229 double new_d_W_entry = 0.0;
230 for (
int entry = 0; entry < d_num_samples; ++entry) {
231 new_d_W_entry += d_W->item(row, entry)*W->item(entry, col);
233 new_d_W->item(row, col) = new_d_W_entry;
236 for (
int col = 0; col < d_num_samples; ++col) {
237 new_d_W->item(d_num_rows_of_W, col) = W->item(d_num_samples, col);
247 IncrementalSVDFastUpdate::addNewSample(
253 CAROM_VERIFY(j != 0);
254 CAROM_VERIFY(A != 0);
255 CAROM_VERIFY(sigma != 0);
258 Matrix* newU =
new Matrix(d_dim, d_num_samples+1,
true);
259 for (
int row = 0; row < d_dim; ++row) {
260 for (
int col = 0; col < d_num_samples; ++col) {
261 newU->item(row, col) = d_U->item(row, col);
263 newU->item(row, d_num_samples) = j->item(row);
269 if (d_update_right_SV) {
275 new_d_W =
new Matrix(d_num_rows_of_W+1, d_num_samples+1,
false);
276 for (
int row = 0; row < d_num_rows_of_W; ++row) {
277 for (
int col = 0; col < d_num_samples+1; ++col) {
278 double new_d_W_entry = 0.0;
279 for (
int entry = 0; entry < d_num_samples; ++entry) {
280 new_d_W_entry += d_W->item(row, entry)*W->item(entry, col);
282 new_d_W->item(row, col) = new_d_W_entry;
285 for (
int col = 0; col < d_num_samples+1; ++col) {
286 new_d_W->item(d_num_rows_of_W, col) = W->item(d_num_samples, col);
297 Matrix* new_d_Up =
new Matrix(d_num_samples+1, d_num_samples+1,
false);
298 for (
int row = 0; row < d_num_samples; ++row) {
299 for (
int col = 0; col < d_num_samples+1; ++col) {
300 double new_d_Up_entry = 0.0;
301 for (
int entry = 0; entry < d_num_samples; ++entry) {
302 new_d_Up_entry += d_Up->item(row, entry)*A->item(entry, col);
304 new_d_Up->item(row, col) = new_d_Up_entry;
307 for (
int col = 0; col < d_num_samples+1; ++col) {
308 new_d_Up->item(d_num_samples, col) = A->item(d_num_samples, col);
315 int num_dim = std::min(sigma->numRows(), sigma->numColumns());
316 d_S =
new Vector(num_dim,
false);
317 for (
int i = 0; i < num_dim; i++) {
318 d_S->item(i) = sigma->item(i,i);
327 if (d_num_samples > d_total_dim) {
328 max_U_dim = d_num_samples;
331 max_U_dim = d_total_dim;