Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
pca.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <neatogen/matrix_ops.h>
12#include <neatogen/pca.h>
13#include <neatogen/closest.h>
14#include <stdbool.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <math.h>
18#include <util/alloc.h>
19
20static int num_pairs = 4;
21
22void
23PCA_alloc(DistType ** coords, int dim, int n, double **new_coords,
24 int new_dim)
25{
26 double sum;
27 int i, j, k;
28
29 double **eigs = gv_calloc(new_dim, sizeof(double *));
30 for (i = 0; i < new_dim; i++)
31 eigs[i] = gv_calloc(dim, sizeof(double));
32 double *evals = gv_calloc(new_dim, sizeof(double));
33
34 double **DD = gv_calloc(dim, sizeof(double *)); // dim×dim matrix: coords×coordsᵀ
35 double *storage_ptr = gv_calloc(dim * dim, sizeof(double));
36 for (i = 0; i < dim; i++) {
37 DD[i] = storage_ptr;
38 storage_ptr += dim;
39 }
40
41 for (i = 0; i < dim; i++) {
42 for (j = 0; j <= i; j++) {
43 /* compute coords[i]*coords[j] */
44 sum = 0;
45 for (k = 0; k < n; k++) {
46 sum += coords[i][k] * coords[j][k];
47 }
48 DD[i][j] = DD[j][i] = sum;
49 }
50 }
51
52 power_iteration(DD, dim, new_dim, eigs, evals);
53
54 for (j = 0; j < new_dim; j++) {
55 for (i = 0; i < n; i++) {
56 sum = 0;
57 for (k = 0; k < dim; k++) {
58 sum += coords[k][i] * eigs[j][k];
59 }
60 new_coords[j][i] = sum;
61 }
62 }
63
64 for (i = 0; i < new_dim; i++)
65 free(eigs[i]);
66 free(eigs);
67 free(evals);
68 free(DD[0]);
69 free(DD);
70}
71
72bool iterativePCA_1D(double **coords, int dim, int n, double *new_direction) {
73 vtx_data *laplacian;
74 float **mat1 = NULL;
75 double **mat = NULL;
76 double eval;
77
78 /* Given that first projection of 'coords' is 'coords[0]'
79 compute another projection direction 'new_direction'
80 that scatters points that are close in 'coords[0]'
81 */
82
83 /* find the nodes that were close in 'coords[0]' */
84 /* and construct appropriate Laplacian */
85 closest_pairs2graph(coords[0], n, num_pairs * n, &laplacian);
86
87 /* Compute coords*Lap*coords^T */
88 mult_sparse_dense_mat_transpose(laplacian, coords, n, dim, &mat1);
89 mult_dense_mat_d(coords, mat1, dim, n, dim, &mat);
90 free(mat1[0]);
91 free(mat1);
92
93 /* Compute direction */
94 return power_iteration(mat, dim, 1, &new_direction, &eval);
95/* ?? When is mat freed? */
96}
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
void closest_pairs2graph(double *place, int n, int num_pairs, vtx_data **graph)
Definition closest.c:315
static int eval(Agraph_t *g, int root)
Definition gc.c:270
void free(void *)
node NULL
Definition grammar.y:163
bool power_iteration(double **square_mat, int n, int neigs, double **eigs, double *evals)
Definition matrix_ops.c:20
void mult_sparse_dense_mat_transpose(vtx_data *A, double **B, int dim1, int dim2, float ***CC)
Definition matrix_ops.c:188
void mult_dense_mat_d(double **A, float **B, int dim1, int dim2, int dim3, double ***CC)
Definition matrix_ops.c:160
static const int dim
void PCA_alloc(DistType **coords, int dim, int n, double **new_coords, int new_dim)
Definition pca.c:23
bool iterativePCA_1D(double **coords, int dim, int n, double *new_direction)
Definition pca.c:72
static int num_pairs
Definition pca.c:20
int DistType
Definition sparsegraph.h:37