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