Graphviz 14.0.5~dev.20251126.0104
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
33 double **DD = gv_calloc(dim, sizeof(double *)); // dim×dim matrix: coords×coordsᵀ
34 double *storage_ptr = gv_calloc(dim * dim, sizeof(double));
35 for (i = 0; i < dim; i++) {
36 DD[i] = storage_ptr;
37 storage_ptr += dim;
38 }
39
40 for (i = 0; i < dim; i++) {
41 for (j = 0; j <= i; j++) {
42 /* compute coords[i]*coords[j] */
43 sum = 0;
44 for (k = 0; k < n; k++) {
45 sum += coords[i][k] * coords[j][k];
46 }
47 DD[i][j] = DD[j][i] = sum;
48 }
49 }
50
51 power_iteration(DD, dim, new_dim, eigs);
52
53 for (j = 0; j < new_dim; j++) {
54 for (i = 0; i < n; i++) {
55 sum = 0;
56 for (k = 0; k < dim; k++) {
57 sum += coords[k][i] * eigs[j][k];
58 }
59 new_coords[j][i] = sum;
60 }
61 }
62
63 for (i = 0; i < new_dim; i++)
64 free(eigs[i]);
65 free(eigs);
66 free(DD[0]);
67 free(DD);
68}
69
70bool iterativePCA_1D(double **coords, int dim, int n, double *new_direction) {
71 vtx_data *laplacian;
72 float **mat1 = NULL;
73 double **mat = NULL;
74
75 /* Given that first projection of 'coords' is 'coords[0]'
76 compute another projection direction 'new_direction'
77 that scatters points that are close in 'coords[0]'
78 */
79
80 /* find the nodes that were close in 'coords[0]' */
81 /* and construct appropriate Laplacian */
82 closest_pairs2graph(coords[0], n, num_pairs * n, &laplacian);
83
84 /* Compute coords*Lap*coords^T */
85 mult_sparse_dense_mat_transpose(laplacian, coords, n, dim, &mat1);
86 mult_dense_mat_d(coords, mat1, dim, n, dim, &mat);
87 free(mat1[0]);
88 free(mat1);
89
90 /* Compute direction */
91 const bool result = power_iteration(mat, dim, 1, &new_direction);
92 free(mat[0]);
93 free(mat);
94 return result;
95}
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:301
void free(void *)
node NULL
Definition grammar.y:181
void mult_sparse_dense_mat_transpose(vtx_data *A, double **B, int dim1, int dim2, float ***CC)
Definition matrix_ops.c:182
bool power_iteration(double *const *square_mat, int n, int neigs, double **eigs)
Definition matrix_ops.c:20
void mult_dense_mat_d(double **A, float **B, int dim1, int dim2, int dim3, double ***CC)
Definition matrix_ops.c:154
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:70
static int num_pairs
Definition pca.c:20
int DistType
Definition sparsegraph.h:38