00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "matrix_ops.h"
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021 #include <math.h>
00022
00023 static double p_iteration_threshold = 1e-3;
00024
00025 boolean
00026 power_iteration(double **square_mat, int n, int neigs, double **eigs,
00027 double *evals, boolean initialize)
00028 {
00029
00030
00031 int i, j;
00032 double *tmp_vec = N_GNEW(n, double);
00033 double *last_vec = N_GNEW(n, double);
00034 double *curr_vector;
00035 double len;
00036 double angle;
00037 double alpha;
00038 int iteration = 0;
00039 int largest_index;
00040 double largest_eval;
00041 int Max_iterations = 30 * n;
00042
00043 double tol = 1 - p_iteration_threshold;
00044
00045 if (neigs >= n) {
00046 neigs = n;
00047 }
00048
00049 for (i = 0; i < neigs; i++) {
00050 curr_vector = eigs[i];
00051
00052 choose:
00053 if (initialize)
00054 for (j = 0; j < n; j++)
00055 curr_vector[j] = rand() % 100;
00056
00057 for (j = 0; j < i; j++) {
00058 alpha = -dot(eigs[j], 0, n - 1, curr_vector);
00059 scadd(curr_vector, 0, n - 1, alpha, eigs[j]);
00060 }
00061 len = norm(curr_vector, 0, n - 1);
00062 if (len < 1e-10) {
00063
00064 goto choose;
00065 }
00066 vecscale(curr_vector, 0, n - 1, 1.0 / len, curr_vector);
00067 iteration = 0;
00068 do {
00069 iteration++;
00070 cpvec(last_vec, 0, n - 1, curr_vector);
00071
00072 right_mult_with_vector_d(square_mat, n, n, curr_vector,
00073 tmp_vec);
00074 cpvec(curr_vector, 0, n - 1, tmp_vec);
00075
00076
00077 for (j = 0; j < i; j++) {
00078 alpha = -dot(eigs[j], 0, n - 1, curr_vector);
00079 scadd(curr_vector, 0, n - 1, alpha, eigs[j]);
00080 }
00081 len = norm(curr_vector, 0, n - 1);
00082 if (len < 1e-10 || iteration > Max_iterations) {
00083
00084 goto exit;
00085 }
00086
00087 vecscale(curr_vector, 0, n - 1, 1.0 / len, curr_vector);
00088 angle = dot(curr_vector, 0, n - 1, last_vec);
00089 } while (fabs(angle) < tol);
00090 evals[i] = angle * len;
00091
00092
00093 }
00094 exit:
00095 for (; i < neigs; i++) {
00096
00097
00098
00099 curr_vector = eigs[i];
00100
00101 for (j = 0; j < n; j++)
00102 curr_vector[j] = rand() % 100;
00103
00104 for (j = 0; j < i; j++) {
00105 alpha = -dot(eigs[j], 0, n - 1, curr_vector);
00106 scadd(curr_vector, 0, n - 1, alpha, eigs[j]);
00107 }
00108 len = norm(curr_vector, 0, n - 1);
00109 vecscale(curr_vector, 0, n - 1, 1.0 / len, curr_vector);
00110 evals[i] = 0;
00111
00112 }
00113
00114
00115
00116 for (i = 0; i < neigs - 1; i++) {
00117 largest_index = i;
00118 largest_eval = evals[largest_index];
00119 for (j = i + 1; j < neigs; j++) {
00120 if (largest_eval < evals[j]) {
00121 largest_index = j;
00122 largest_eval = evals[largest_index];
00123 }
00124 }
00125 if (largest_index != i) {
00126 cpvec(tmp_vec, 0, n - 1, eigs[i]);
00127 cpvec(eigs[i], 0, n - 1, eigs[largest_index]);
00128 cpvec(eigs[largest_index], 0, n - 1, tmp_vec);
00129
00130 evals[largest_index] = evals[i];
00131 evals[i] = largest_eval;
00132 }
00133 }
00134
00135 free(tmp_vec);
00136 free(last_vec);
00137
00138 return (iteration <= Max_iterations);
00139 }
00140
00141
00142
00143 void
00144 mult_dense_mat(double **A, float **B, int dim1, int dim2, int dim3,
00145 float ***CC)
00146 {
00147
00148
00149
00150
00151 double sum;
00152 int i, j, k;
00153 float *storage;
00154 float **C = *CC;
00155 if (C != NULL) {
00156 storage = (float *) realloc(C[0], dim1 * dim3 * sizeof(A[0]));
00157 *CC = C = (float **) realloc(C, dim1 * sizeof(A));
00158 } else {
00159 storage = (float *) malloc(dim1 * dim3 * sizeof(A[0]));
00160 *CC = C = (float **) malloc(dim1 * sizeof(A));
00161 }
00162
00163 for (i = 0; i < dim1; i++) {
00164 C[i] = storage;
00165 storage += dim3;
00166 }
00167
00168 for (i = 0; i < dim1; i++) {
00169 for (j = 0; j < dim3; j++) {
00170 sum = 0;
00171 for (k = 0; k < dim2; k++) {
00172 sum += A[i][k] * B[k][j];
00173 }
00174 C[i][j] = (float) (sum);
00175 }
00176 }
00177 }
00178
00179 void
00180 mult_dense_mat_d(double **A, float **B, int dim1, int dim2, int dim3,
00181 double ***CC)
00182 {
00183
00184
00185
00186 double **C = *CC;
00187 double *storage;
00188 int i, j, k;
00189 double sum;
00190
00191 if (C != NULL) {
00192 storage = (double *) realloc(C[0], dim1 * dim3 * sizeof(double));
00193 *CC = C = (double **) realloc(C, dim1 * sizeof(double *));
00194 } else {
00195 storage = (double *) malloc(dim1 * dim3 * sizeof(double));
00196 *CC = C = (double **) malloc(dim1 * sizeof(double *));
00197 }
00198
00199 for (i = 0; i < dim1; i++) {
00200 C[i] = storage;
00201 storage += dim3;
00202 }
00203
00204 for (i = 0; i < dim1; i++) {
00205 for (j = 0; j < dim3; j++) {
00206 sum = 0;
00207 for (k = 0; k < dim2; k++) {
00208 sum += A[i][k] * B[k][j];
00209 }
00210 C[i][j] = sum;
00211 }
00212 }
00213 }
00214
00215 void
00216 mult_sparse_dense_mat_transpose(vtx_data * A, double **B, int dim1,
00217 int dim2, float ***CC)
00218 {
00219
00220
00221
00222
00223 float *storage;
00224 int i, j, k;
00225 double sum;
00226 float *ewgts;
00227 int *edges;
00228 int nedges;
00229 float **C = *CC;
00230 if (C != NULL) {
00231 storage = (float *) realloc(C[0], dim1 * dim2 * sizeof(A[0]));
00232 *CC = C = (float **) realloc(C, dim1 * sizeof(A));
00233 } else {
00234 storage = (float *) malloc(dim1 * dim2 * sizeof(A[0]));
00235 *CC = C = (float **) malloc(dim1 * sizeof(A));
00236 }
00237
00238 for (i = 0; i < dim1; i++) {
00239 C[i] = storage;
00240 storage += dim2;
00241 }
00242
00243 for (i = 0; i < dim1; i++) {
00244 edges = A[i].edges;
00245 ewgts = A[i].ewgts;
00246 nedges = A[i].nedges;
00247 for (j = 0; j < dim2; j++) {
00248 sum = 0;
00249 for (k = 0; k < nedges; k++) {
00250 sum += ewgts[k] * B[j][edges[k]];
00251 }
00252 C[i][j] = (float) (sum);
00253 }
00254 }
00255 }
00256
00257
00258
00259
00260 void cpvec(double *copy, int beg, int end, double *vec)
00261 {
00262 int i;
00263
00264 copy = copy + beg;
00265 vec = vec + beg;
00266 for (i = end - beg + 1; i; i--) {
00267 *copy++ = *vec++;
00268 }
00269 }
00270
00271
00272 double dot(double *vec1, int beg, int end, double *vec2)
00273 {
00274 int i;
00275 double sum;
00276
00277 sum = 0.0;
00278 vec1 = vec1 + beg;
00279 vec2 = vec2 + beg;
00280 for (i = end - beg + 1; i; i--) {
00281 sum += (*vec1++) * (*vec2++);
00282 }
00283 return (sum);
00284 }
00285
00286
00287
00288 void scadd(double *vec1, int beg, int end, double fac, double *vec2)
00289 {
00290 int i;
00291
00292 vec1 = vec1 + beg;
00293 vec2 = vec2 + beg;
00294 for (i = end - beg + 1; i; i--) {
00295 (*vec1++) += fac * (*vec2++);
00296 }
00297 }
00298
00299
00300 void vecscale(double *vec1, int beg, int end, double alpha, double *vec2)
00301 {
00302 int i;
00303
00304 vec1 += beg;
00305 vec2 += beg;
00306 for (i = end - beg + 1; i; i--) {
00307 (*vec1++) = alpha * (*vec2++);
00308 }
00309 }
00310
00311
00312 double norm(double *vec, int beg, int end)
00313 {
00314 return (sqrt(dot(vec, beg, end, vec)));
00315 }
00316
00317
00318 #ifndef __cplusplus
00319
00320
00321 void orthog1(int n, double *vec
00322 )
00323 {
00324 int i;
00325 double *pntr;
00326 double sum;
00327
00328 sum = 0.0;
00329 pntr = vec;
00330 for (i = n; i; i--) {
00331 sum += *pntr++;
00332 }
00333 sum /= n;
00334 pntr = vec;
00335 for (i = n; i; i--) {
00336 *pntr++ -= sum;
00337 }
00338 }
00339
00340 #define RANGE 500
00341
00342
00343 void init_vec_orth1(int n, double *vec)
00344 {
00345
00346 int i;
00347
00348 for (i = 0; i < n; i++)
00349 vec[i] = rand() % RANGE;
00350
00351 orthog1(n, vec);
00352 }
00353
00354
00355 void
00356 right_mult_with_vector(vtx_data * matrix, int n, double *vector,
00357 double *result)
00358 {
00359 int i, j;
00360
00361 double res;
00362 for (i = 0; i < n; i++) {
00363 res = 0;
00364 for (j = 0; j < matrix[i].nedges; j++)
00365 res += matrix[i].ewgts[j] * vector[matrix[i].edges[j]];
00366 result[i] = res;
00367 }
00368
00369 }
00370
00371
00372 void
00373 right_mult_with_vector_f(float **matrix, int n, double *vector,
00374 double *result)
00375 {
00376 int i, j;
00377
00378 double res;
00379 for (i = 0; i < n; i++) {
00380 res = 0;
00381 for (j = 0; j < n; j++)
00382 res += matrix[i][j] * vector[j];
00383 result[i] = res;
00384 }
00385
00386 }
00387
00388
00389 void
00390 vectors_subtraction(int n, double *vector1, double *vector2,
00391 double *result)
00392 {
00393 int i;
00394 for (i = 0; i < n; i++) {
00395 result[i] = vector1[i] - vector2[i];
00396 }
00397 }
00398
00399
00400 void
00401 vectors_addition(int n, double *vector1, double *vector2, double *result)
00402 {
00403 int i;
00404 for (i = 0; i < n; i++) {
00405 result[i] = vector1[i] + vector2[i];
00406 }
00407 }
00408
00409 #ifdef UNUSED
00410
00411 void
00412 vectors_mult_addition(int n, double *vector1, double alpha,
00413 double *vector2)
00414 {
00415 int i;
00416 for (i = 0; i < n; i++) {
00417 vector1[i] = vector1[i] + alpha * vector2[i];
00418 }
00419 }
00420 #endif
00421
00422
00423 void
00424 vectors_scalar_mult(int n, double *vector, double alpha, double *result)
00425 {
00426 int i;
00427 for (i = 0; i < n; i++) {
00428 result[i] = vector[i] * alpha;
00429 }
00430 }
00431
00432
00433 void copy_vector(int n, double *source, double *dest)
00434 {
00435 int i;
00436 for (i = 0; i < n; i++)
00437 dest[i] = source[i];
00438 }
00439
00440
00441 double vectors_inner_product(int n, double *vector1, double *vector2)
00442 {
00443 int i;
00444 double result = 0;
00445 for (i = 0; i < n; i++) {
00446 result += vector1[i] * vector2[i];
00447 }
00448
00449 return result;
00450 }
00451
00452
00453 double max_abs(int n, double *vector)
00454 {
00455 double max_val = -1e50;
00456 int i;
00457 for (i = 0; i < n; i++)
00458 if (fabs(vector[i]) > max_val)
00459 max_val = fabs(vector[i]);
00460
00461 return max_val;
00462 }
00463
00464 #ifdef UNUSED
00465
00466 void orthogvec(int n, double *vec1,
00467 double *vec2
00468 )
00469 {
00470 double alpha;
00471 if (vec2 == NULL) {
00472 return;
00473 }
00474
00475 alpha = -vectors_inner_product(n, vec1, vec2);
00476
00477 vectors_mult_addition(n, vec1, alpha, vec2);
00478 }
00479
00480
00481
00482
00483 void mat_mult_vec(vtx_data * L, int n, double *vec, double *result)
00484 {
00485
00486 int i, j;
00487 double sum;
00488 int *edges;
00489 float *ewgts;
00490
00491 for (i = 0; i < n; i++) {
00492 sum = 0;
00493 edges = L[i].edges;
00494 ewgts = L[i].ewgts;
00495 for (j = 0; j < L[i].nedges; j++) {
00496 sum -= ewgts[j] * vec[edges[j]];
00497 }
00498 result[i] = sum;
00499 }
00500 }
00501 #endif
00502
00503
00504 void
00505 right_mult_with_vector_transpose(double **matrix,
00506 int dim1, int dim2,
00507 double *vector, double *result)
00508 {
00509
00510 int i, j;
00511
00512 double res;
00513 for (i = 0; i < dim1; i++) {
00514 res = 0;
00515 for (j = 0; j < dim2; j++)
00516 res += matrix[j][i] * vector[j];
00517 result[i] = res;
00518 }
00519 }
00520
00521
00522 void
00523 right_mult_with_vector_d(double **matrix,
00524 int dim1, int dim2,
00525 double *vector, double *result)
00526 {
00527
00528 int i, j;
00529
00530 double res;
00531 for (i = 0; i < dim1; i++) {
00532 res = 0;
00533 for (j = 0; j < dim2; j++)
00534 res += matrix[i][j] * vector[j];
00535 result[i] = res;
00536 }
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546 void orthog1f(int n, float *vec)
00547 {
00548 int i;
00549 float *pntr;
00550 float sum;
00551
00552 sum = 0.0;
00553 pntr = vec;
00554 for (i = n; i; i--) {
00555 sum += *pntr++;
00556 }
00557 sum /= n;
00558 pntr = vec;
00559 for (i = n; i; i--) {
00560 *pntr++ -= sum;
00561 }
00562 }
00563
00564 #ifdef UNUSED
00565
00566 void right_mult_with_vectorf
00567 (vtx_data * matrix, int n, float *vector, float *result) {
00568 int i, j;
00569
00570 float res;
00571 for (i = 0; i < n; i++) {
00572 res = 0;
00573 for (j = 0; j < matrix[i].nedges; j++)
00574 res += matrix[i].ewgts[j] * vector[matrix[i].edges[j]];
00575 result[i] = res;
00576 }
00577 }
00578
00579
00580 void right_mult_with_vector_fd
00581 (float **matrix, int n, float *vector, double *result) {
00582 int i, j;
00583
00584 float res;
00585 for (i = 0; i < n; i++) {
00586 res = 0;
00587 for (j = 0; j < n; j++)
00588 res += matrix[i][j] * vector[j];
00589 result[i] = res;
00590 }
00591 }
00592 #endif
00593
00594
00595 void right_mult_with_vector_ff
00596 (float *packed_matrix, int n, float *vector, float *result) {
00597
00598 int i, j, index;
00599 float vector_i;
00600
00601 float res;
00602 for (i = 0; i < n; i++) {
00603 result[i] = 0;
00604 }
00605 for (index = 0, i = 0; i < n; i++) {
00606 res = 0;
00607 vector_i = vector[i];
00608
00609 res += packed_matrix[index++] * vector_i;
00610
00611 for (j = i + 1; j < n; j++, index++) {
00612 res += packed_matrix[index] * vector[j];
00613 result[j] += packed_matrix[index] * vector_i;
00614 }
00615 result[i] += res;
00616 }
00617 }
00618
00619
00620 void
00621 vectors_substractionf(int n, float *vector1, float *vector2, float *result)
00622 {
00623 int i;
00624 for (i = 0; i < n; i++) {
00625 result[i] = vector1[i] - vector2[i];
00626 }
00627 }
00628
00629
00630 void
00631 vectors_additionf(int n, float *vector1, float *vector2, float *result)
00632 {
00633 int i;
00634 for (i = 0; i < n; i++) {
00635 result[i] = vector1[i] + vector2[i];
00636 }
00637 }
00638
00639
00640 void
00641 vectors_mult_additionf(int n, float *vector1, float alpha, float *vector2)
00642 {
00643 int i;
00644 for (i = 0; i < n; i++) {
00645 vector1[i] = vector1[i] + alpha * vector2[i];
00646 }
00647 }
00648
00649
00650 void vectors_scalar_multf(int n, float *vector, float alpha, float *result)
00651 {
00652 int i;
00653 for (i = 0; i < n; i++) {
00654 result[i] = (float) vector[i] * alpha;
00655 }
00656 }
00657
00658
00659 void copy_vectorf(int n, float *source, float *dest)
00660 {
00661 int i;
00662 for (i = 0; i < n; i++)
00663 dest[i] = source[i];
00664 }
00665
00666
00667 double vectors_inner_productf(int n, float *vector1, float *vector2)
00668 {
00669 int i;
00670 double result = 0;
00671 for (i = 0; i < n; i++) {
00672 result += vector1[i] * vector2[i];
00673 }
00674
00675 return result;
00676 }
00677
00678
00679 void set_vector_val(int n, double val, double *result)
00680 {
00681 int i;
00682 for (i = 0; i < n; i++)
00683 result[i] = val;
00684 }
00685
00686
00687 void set_vector_valf(int n, float val, float * result) {
00688 int i;
00689 for (i=0; i<n; i++)
00690 result[i]=val;
00691 }
00692
00693
00694 double max_absf(int n, float *vector)
00695 {
00696 int i;
00697 float max_val = -1e30f;
00698 for (i = 0; i < n; i++)
00699 if (fabs(vector[i]) > max_val)
00700 max_val = (float) (fabs(vector[i]));
00701
00702 return max_val;
00703 }
00704
00705
00706 void square_vec(int n, float *vec)
00707 {
00708 int i;
00709 for (i = 0; i < n; i++) {
00710 vec[i] *= vec[i];
00711 }
00712 }
00713
00714
00715 void invert_vec(int n, float *vec)
00716 {
00717 int i;
00718 float v;
00719 for (i = 0; i < n; i++) {
00720 if ((v = vec[i]) != 0.0)
00721 vec[i] = 1.0f / v;
00722 }
00723 }
00724
00725
00726 void sqrt_vec(int n, float *vec)
00727 {
00728 int i;
00729 double d;
00730 for (i = 0; i < n; i++) {
00731
00732 d = sqrt(vec[i]);
00733 vec[i] = (float) d;
00734 }
00735 }
00736
00737
00738 void sqrt_vecf(int n, float *source, float *target)
00739 {
00740 int i;
00741 double d;
00742 float v;
00743 for (i = 0; i < n; i++) {
00744 if ((v = source[i]) >= 0.0) {
00745
00746 d = sqrt(v);
00747 target[i] = (float) d;
00748 }
00749 }
00750 }
00751
00752
00753 void invert_sqrt_vec(int n, float *vec)
00754 {
00755 int i;
00756 double d;
00757 float v;
00758 for (i = 0; i < n; i++) {
00759 if ((v = vec[i]) > 0.0) {
00760
00761 d = 1. / sqrt(v);
00762 vec[i] = (float) d;
00763 }
00764 }
00765 }
00766
00767 #ifdef UNUSED
00768
00769 void init_vec_orth1f(int n, float *vec)
00770 {
00771
00772 int i;
00773
00774 for (i = 0; i < n; i++)
00775 vec[i] = (float) (rand() % RANGE);
00776
00777 orthog1f(n, vec);
00778 }
00779
00780
00781
00782
00783
00784 void mat_mult_vecf(vtx_data * L, int n, float *vec, float *result)
00785 {
00786
00787 int i, j;
00788 float sum;
00789 int *edges;
00790 float *ewgts;
00791
00792 for (i = 0; i < n; i++) {
00793 sum = 0;
00794 edges = L[i].edges;
00795 ewgts = L[i].ewgts;
00796 for (j = 0; j < L[i].nedges; j++) {
00797 sum -= ewgts[j] * vec[edges[j]];
00798 }
00799 result[i] = sum;
00800 }
00801 }
00802 #endif
00803
00804 #endif