Graphviz 14.1.3~dev.20260126.0926
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 "config.h"
12
13#include <neatogen/matrix_ops.h>
14#include <neatogen/pca.h>
15#include <neatogen/closest.h>
16#include <stdbool.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <math.h>
20#include <util/alloc.h>
21
22static int num_pairs = 4;
23
24void
25PCA_alloc(DistType ** coords, int dim, int n, double **new_coords,
26 int new_dim)
27{
28 double sum;
29 int i, j, k;
30
31 double **eigs = gv_calloc(new_dim, sizeof(double *));
32 for (i = 0; i < new_dim; i++)
33 eigs[i] = gv_calloc(dim, sizeof(double));
34
35 double **DD = gv_calloc(dim, sizeof(double *)); // dim×dim matrix: coords×coordsᵀ
36 double *storage_ptr = gv_calloc(dim * dim, sizeof(double));
37 for (i = 0; i < dim; i++) {
38 DD[i] = storage_ptr;
39 storage_ptr += dim;
40 }
41
42 for (i = 0; i < dim; i++) {
43 for (j = 0; j <= i; j++) {
44 /* compute coords[i]*coords[j] */
45 sum = 0;
46 for (k = 0; k < n; k++) {
47 sum += coords[i][k] * coords[j][k];
48 }
49 DD[i][j] = DD[j][i] = sum;
50 }
51 }
52
53 power_iteration(DD, dim, new_dim, eigs);
54
55 for (j = 0; j < new_dim; j++) {
56 for (i = 0; i < n; i++) {
57 sum = 0;
58 for (k = 0; k < dim; k++) {
59 sum += coords[k][i] * eigs[j][k];
60 }
61 new_coords[j][i] = sum;
62 }
63 }
64
65 for (i = 0; i < new_dim; i++)
66 free(eigs[i]);
67 free(eigs);
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
77 /* Given that first projection of 'coords' is 'coords[0]'
78 compute another projection direction 'new_direction'
79 that scatters points that are close in 'coords[0]'
80 */
81
82 /* find the nodes that were close in 'coords[0]' */
83 /* and construct appropriate Laplacian */
84 closest_pairs2graph(coords[0], n, num_pairs * n, &laplacian);
85
86 /* Compute coords*Lap*coords^T */
87 mult_sparse_dense_mat_transpose(laplacian, coords, n, dim, &mat1);
88 mult_dense_mat_d(coords, mat1, dim, n, dim, &mat);
89 free(mat1[0]);
90 free(mat1);
91
92 /* Compute direction */
93 const bool result = power_iteration(mat, dim, 1, &new_direction);
94 free(mat[0]);
95 free(mat);
96 return result;
97}
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:303
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:184
bool power_iteration(double *const *square_mat, int n, int neigs, double **eigs)
Definition matrix_ops.c:22
void mult_dense_mat_d(double **A, float **B, int dim1, int dim2, int dim3, double ***CC)
Definition matrix_ops.c:156
static const int dim
void PCA_alloc(DistType **coords, int dim, int n, double **new_coords, int new_dim)
Definition pca.c:25
bool iterativePCA_1D(double **coords, int dim, int n, double *new_direction)
Definition pca.c:72
static int num_pairs
Definition pca.c:22
int DistType
Definition sparsegraph.h:39