00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "matrix_ops.h"
00019 #include "pca.h"
00020 #include "closest.h"
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <math.h>
00024
00025 static int num_pairs = 4;
00026
00027 void
00028 PCA_alloc(DistType ** coords, int dim, int n, double **new_coords,
00029 int new_dim)
00030 {
00031 double **DD = NULL;
00032 double sum;
00033 int i, j, k;
00034 double **eigs = NULL;
00035 double *evals = NULL;
00036 double *storage_ptr;
00037
00038 eigs = N_GNEW(new_dim, double *);
00039 for (i = 0; i < new_dim; i++)
00040 eigs[i] = N_GNEW(dim, double);
00041 evals = N_GNEW(new_dim, double);
00042
00043 DD = N_GNEW(dim, double *);
00044 storage_ptr = N_GNEW(dim * dim, double);
00045 for (i = 0; i < dim; i++) {
00046 DD[i] = storage_ptr;
00047 storage_ptr += dim;
00048 }
00049
00050 for (i = 0; i < dim; i++) {
00051 for (j = 0; j <= i; j++) {
00052
00053 sum = 0;
00054 for (k = 0; k < n; k++) {
00055 sum += coords[i][k] * coords[j][k];
00056 }
00057 DD[i][j] = DD[j][i] = sum;
00058 }
00059 }
00060
00061 power_iteration(DD, dim, new_dim, eigs, evals, TRUE);
00062
00063 for (j = 0; j < new_dim; j++) {
00064 for (i = 0; i < n; i++) {
00065 sum = 0;
00066 for (k = 0; k < dim; k++) {
00067 sum += coords[k][i] * eigs[j][k];
00068 }
00069 new_coords[j][i] = sum;
00070 }
00071 }
00072
00073 for (i = 0; i < new_dim; i++)
00074 free(eigs[i]);
00075 free(eigs);
00076 free(evals);
00077 free(DD[0]);
00078 free(DD);
00079 }
00080
00081 boolean
00082 iterativePCA_1D(double **coords, int dim, int n, double *new_direction)
00083 {
00084 vtx_data *laplacian;
00085 float **mat1 = NULL;
00086 double **mat = NULL;
00087 double eval;
00088
00089
00090
00091
00092
00093
00094
00095
00096 closest_pairs2graph(coords[0], n, num_pairs * n, &laplacian);
00097
00098
00099 mult_sparse_dense_mat_transpose(laplacian, coords, n, dim, &mat1);
00100 mult_dense_mat_d(coords, mat1, dim, n, dim, &mat);
00101 free(mat1[0]);
00102 free(mat1);
00103
00104
00105 return power_iteration(mat, dim, 1, &new_direction, &eval, TRUE);
00106
00107 }
00108
00109 #ifdef UNUSED
00110
00111 double dist(double **coords, int dim, int p1, int p2)
00112 {
00113 int i;
00114 double sum = 0;
00115
00116 for (i = 0; i < dim; i++) {
00117 sum +=
00118 (coords[i][p1] - coords[i][p2]) * (coords[i][p1] -
00119 coords[i][p2]);
00120 }
00121 return sqrt(sum);
00122 }
00123
00124
00125 void weight_laplacian(double **X, int n, int dim, vtx_data * laplacian)
00126 {
00127 int i, j, neighbor;
00128
00129 int *edges;
00130 float *ewgts;
00131 for (i = 0; i < n; i++) {
00132 edges = laplacian[i].edges;
00133 ewgts = laplacian[i].ewgts;
00134 *ewgts = 0;
00135 for (j = 1; j < laplacian[i].nedges; j++) {
00136 neighbor = edges[j];
00137 *ewgts -= ewgts[j] =
00138 float (-1.0 / (dist(X, dim, i, neighbor) + 1e-10));
00139 }
00140 }
00141 }
00142
00143 #endif