Graphviz 14.1.2~dev.20260123.1158
Loading...
Searching...
No Matches
power.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 <util/alloc.h>
14#include "power.h"
15#include <sparse/SparseMatrix.h>
16
17// Maxium of iterations that will be done in power_method
18static const int maxit = 100;
19
20// Accuracy control (convergence criterion) for power_method
21static const double tolerance = 0.00001;
22
23double *power_method(void *A, int n, int random_seed) {
24 /* find largest eigenvector of a matrix A.
25
26 This converges only if the largest eigenvector/value is real (e.g., if A is symmetric) and the
27 next largest eigenvalues separate from the largest ones
28
29 input:
30 A: the matrix
31 n: dimension of matrix A
32 random_seed: seed for eigenvector initialization
33 matrix: max number f iterations
34
35 output:
36 eigv: eigenvectors. The i-th is at eigvs[i*n, i*(n+1) - 1]
37
38 Function PowerIteration (A – m × m matrix )
39 % This function computes u1, u2, . . . , uk, the first k eigenvectors of S.
40 const tolerance ← 0.001
41 ui ← random
42 ui ← ui/||ui||
43 do
44 vi ← ui
45 ui ← A vi/||A vi||
46 while (ui^T vi < 1-tolerance) (halt when direction change is small)
47 vi = ui
48 return v1,v2,...
49 */
50 double *v, *u, *vv;
51 int iter = 0;
52 double res, unorm;
53 int i;
54
55 double *eigv = gv_calloc(n, sizeof(double));
56
57 vv = gv_calloc(n, sizeof(double));
58 u = gv_calloc(n, sizeof(double));
59
60 srand((unsigned)random_seed);
61
62 v = eigv;
63 for (i = 0; i < n; i++) u[i] = drand();
64 res = sqrt(vector_product(n, u, u));
65 if (res > 0) res = 1/res;
66 for (i = 0; i < n; i++) {
67 u[i] = u[i]*res;
68 v[i] = u[i];
69 }
70 iter = 0;
71 do {
73
74 unorm = vector_product(n, vv, vv);/* ||u||^2 */
75 unorm = sqrt(unorm);
76 if (unorm > 0) {
77 unorm = 1/unorm;
78 } else {
79 // ||A.v||=0, so v must be an eigenvec correspond to eigenvalue zero
80 for (i = 0; i < n; i++) vv[i] = u[i];
81 unorm = sqrt(vector_product(n, vv, vv));
82 if (unorm > 0) unorm = 1/unorm;
83 }
84 res = 0.;
85
86 for (i = 0; i < n; i++) {
87 u[i] = vv[i]*unorm;
88 res = res + u[i]*v[i];
89 v[i] = u[i];
90 }
91 } while (res < 1 - tolerance && iter++ < maxit);
92 free(u);
93 free(vv);
94
95 return eigv;
96}
void SparseMatrix_multiply_vector(SparseMatrix A, double *v, double **res)
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
#define A(n, t)
Definition expr.h:76
double drand(void)
Definition general.c:24
double vector_product(int n, double *x, double *y)
Definition general.c:34
void free(void *)
static const double tolerance
Definition power.c:21
double * power_method(void *A, int n, int random_seed)
Definition power.c:23
static const int maxit
Definition power.c:18