|
Graphviz
2.29.20120524.0446
|
00001 /* $Id$ $Revision$ */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /************************************************************************* 00005 * Copyright (c) 2011 AT&T Intellectual Property 00006 * All rights reserved. This program and the accompanying materials 00007 * are made available under the terms of the Eclipse Public License v1.0 00008 * which accompanies this distribution, and is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * 00011 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00012 *************************************************************************/ 00013 00014 00015 #include "matrix_ops.h" 00016 #include "pca.h" 00017 #include "closest.h" 00018 #include <stdio.h> 00019 #include <stdlib.h> 00020 #include <math.h> 00021 00022 static int num_pairs = 4; 00023 00024 void 00025 PCA_alloc(DistType ** coords, int dim, int n, double **new_coords, 00026 int new_dim) 00027 { 00028 double **DD = NULL; /* dim*dim matrix: coords*coords^T */ 00029 double sum; 00030 int i, j, k; 00031 double **eigs = NULL; 00032 double *evals = NULL; 00033 double *storage_ptr; 00034 00035 eigs = N_GNEW(new_dim, double *); 00036 for (i = 0; i < new_dim; i++) 00037 eigs[i] = N_GNEW(dim, double); 00038 evals = N_GNEW(new_dim, double); 00039 00040 DD = N_GNEW(dim, double *); 00041 storage_ptr = N_GNEW(dim * dim, double); 00042 for (i = 0; i < dim; i++) { 00043 DD[i] = storage_ptr; 00044 storage_ptr += dim; 00045 } 00046 00047 for (i = 0; i < dim; i++) { 00048 for (j = 0; j <= i; j++) { 00049 /* compute coords[i]*coords[j] */ 00050 sum = 0; 00051 for (k = 0; k < n; k++) { 00052 sum += coords[i][k] * coords[j][k]; 00053 } 00054 DD[i][j] = DD[j][i] = sum; 00055 } 00056 } 00057 00058 power_iteration(DD, dim, new_dim, eigs, evals, TRUE); 00059 00060 for (j = 0; j < new_dim; j++) { 00061 for (i = 0; i < n; i++) { 00062 sum = 0; 00063 for (k = 0; k < dim; k++) { 00064 sum += coords[k][i] * eigs[j][k]; 00065 } 00066 new_coords[j][i] = sum; 00067 } 00068 } 00069 00070 for (i = 0; i < new_dim; i++) 00071 free(eigs[i]); 00072 free(eigs); 00073 free(evals); 00074 free(DD[0]); 00075 free(DD); 00076 } 00077 00078 boolean 00079 iterativePCA_1D(double **coords, int dim, int n, double *new_direction) 00080 { 00081 vtx_data *laplacian; 00082 float **mat1 = NULL; 00083 double **mat = NULL; 00084 double eval; 00085 00086 /* Given that first projection of 'coords' is 'coords[0]' 00087 compute another projection direction 'new_direction' 00088 that scatters points that are close in 'coords[0]' 00089 */ 00090 00091 /* find the nodes that were close in 'coords[0]' */ 00092 /* and construct appropriate Laplacian */ 00093 closest_pairs2graph(coords[0], n, num_pairs * n, &laplacian); 00094 00095 /* Compute coords*Lap*coords^T */ 00096 mult_sparse_dense_mat_transpose(laplacian, coords, n, dim, &mat1); 00097 mult_dense_mat_d(coords, mat1, dim, n, dim, &mat); 00098 free(mat1[0]); 00099 free(mat1); 00100 00101 /* Compute direction */ 00102 return power_iteration(mat, dim, 1, &new_direction, &eval, TRUE); 00103 /* ?? When is mat freed? */ 00104 } 00105 00106 #ifdef UNUSED 00107 00108 double dist(double **coords, int dim, int p1, int p2) 00109 { 00110 int i; 00111 double sum = 0; 00112 00113 for (i = 0; i < dim; i++) { 00114 sum += 00115 (coords[i][p1] - coords[i][p2]) * (coords[i][p1] - 00116 coords[i][p2]); 00117 } 00118 return sqrt(sum); 00119 } 00120 00121 00122 void weight_laplacian(double **X, int n, int dim, vtx_data * laplacian) 00123 { 00124 int i, j, neighbor; 00125 00126 int *edges; 00127 float *ewgts; 00128 for (i = 0; i < n; i++) { 00129 edges = laplacian[i].edges; 00130 ewgts = laplacian[i].ewgts; 00131 *ewgts = 0; 00132 for (j = 1; j < laplacian[i].nedges; j++) { 00133 neighbor = edges[j]; 00134 *ewgts -= ewgts[j] = 00135 float (-1.0 / (dist(X, dim, i, neighbor) + 1e-10)); 00136 } 00137 } 00138 } 00139 00140 #endif
1.7.5