Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
conjgrad.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/conjgrad.h>
13#include <stdbool.h>
14#include <stdlib.h>
15#include <util/alloc.h>
16
17/*************************
18** C.G. method - SPARSE *
19*************************/
20
22 (vtx_data * A, double *x, double *b, int n, double tol,
23 int max_iterations) {
24 /* Solves Ax=b using Conjugate-Gradients method */
25 /* 'x' and 'b' are orthogonalized against 1 */
26
27 int i, rv = 0;
28
29 double alpha, beta, r_r, r_r_new, p_Ap;
30 double *r = gv_calloc(n, sizeof(double));
31 double *p = gv_calloc(n, sizeof(double));
32 double *Ap = gv_calloc(n, sizeof(double));
33 double *Ax = gv_calloc(n, sizeof(double));
34 double *alphap = gv_calloc(n, sizeof(double));
35
36 double *orth_b = gv_calloc(n, sizeof(double));
37 copy_vector(n, b, orth_b);
38 orthog1(n, orth_b);
39 orthog1(n, x);
40 right_mult_with_vector(A, n, x, Ax);
41 vectors_subtraction(n, orth_b, Ax, r);
42 copy_vector(n, r, p);
43 r_r = vectors_inner_product(n, r, r);
44
45 for (i = 0; i < max_iterations && max_abs(n, r) > tol; i++) {
46 right_mult_with_vector(A, n, p, Ap);
47 p_Ap = vectors_inner_product(n, p, Ap);
48 if (p_Ap == 0)
49 break; /*exit(1); */
50 alpha = r_r / p_Ap;
51
52 /* derive new x: */
53 vectors_scalar_mult(n, p, alpha, alphap);
54 vectors_addition(n, x, alphap, x);
55
56 /* compute values for next iteration: */
57 if (i < max_iterations - 1) { /* not last iteration */
58 vectors_scalar_mult(n, Ap, alpha, Ap);
59 vectors_subtraction(n, r, Ap, r); /* fast computation of r, the residual */
60
61 r_r_new = vectors_inner_product(n, r, r);
62 if (r_r == 0) {
63 agerrorf("conjugate_gradient: unexpected length 0 vector\n");
64 rv = 1;
65 goto cleanup0;
66 }
67 beta = r_r_new / r_r;
68 r_r = r_r_new;
69 vectors_scalar_mult(n, p, beta, p);
70 vectors_addition(n, r, p, p);
71 }
72 }
73
74cleanup0 :
75 free(r);
76 free(p);
77 free(Ap);
78 free(Ax);
79 free(alphap);
80 free(orth_b);
81
82 return rv;
83}
84
85
86/****************************
87** C.G. method - DENSE *
88****************************/
89
91 (float **A, double *x, double *b, int n, double tol,
92 int max_iterations, bool ortho1) {
93 /* Solves Ax=b using Conjugate-Gradients method */
94 /* 'x' and 'b' are orthogonalized against 1 if 'ortho1=true' */
95
96 int i, rv = 0;
97
98 double alpha, beta, r_r, r_r_new, p_Ap;
99 double *r = gv_calloc(n, sizeof(double));
100 double *p = gv_calloc(n, sizeof(double));
101 double *Ap = gv_calloc(n, sizeof(double));
102 double *Ax = gv_calloc(n, sizeof(double));
103 double *alphap = gv_calloc(n, sizeof(double));
104
105 double *orth_b = gv_calloc(n, sizeof(double));
106 copy_vector(n, b, orth_b);
107 if (ortho1) {
108 orthog1(n, orth_b);
109 orthog1(n, x);
110 }
111 right_mult_with_vector_f(A, n, x, Ax);
112 vectors_subtraction(n, orth_b, Ax, r);
113 copy_vector(n, r, p);
114 r_r = vectors_inner_product(n, r, r);
115
116 for (i = 0; i < max_iterations && max_abs(n, r) > tol; i++) {
117 right_mult_with_vector_f(A, n, p, Ap);
118 p_Ap = vectors_inner_product(n, p, Ap);
119 if (p_Ap == 0)
120 break; /*exit(1); */
121 alpha = r_r / p_Ap;
122
123 /* derive new x: */
124 vectors_scalar_mult(n, p, alpha, alphap);
125 vectors_addition(n, x, alphap, x);
126
127 /* compute values for next iteration: */
128 if (i < max_iterations - 1) { /* not last iteration */
129 vectors_scalar_mult(n, Ap, alpha, Ap);
130 vectors_subtraction(n, r, Ap, r); /* fast computation of r, the residual */
131
132 /* Alternaive accurate, but slow, computation of the residual - r */
133 /* right_mult_with_vector(A, n, x, Ax); */
134 /* vectors_subtraction(n,b,Ax,r); */
135
136 r_r_new = vectors_inner_product(n, r, r);
137 if (r_r == 0) {
138 rv = 1;
139 agerrorf("conjugate_gradient: unexpected length 0 vector\n");
140 goto cleanup1;
141 }
142 beta = r_r_new / r_r;
143 r_r = r_r_new;
144 vectors_scalar_mult(n, p, beta, p);
145 vectors_addition(n, r, p, p);
146 }
147 }
149 free(r);
150 free(p);
151 free(Ap);
152 free(Ax);
153 free(alphap);
154 free(orth_b);
155
156 return rv;
157}
158
159int
160conjugate_gradient_mkernel(float *A, float *x, float *b, int n,
161 double tol, int max_iterations)
162{
163 /* Solves Ax=b using Conjugate-Gradients method */
164 /* A is a packed symmetric matrix */
165 /* matrux A is "packed" (only upper triangular portion exists, row-major); */
166
167 int i, rv = 0;
168
169 double alpha, beta, r_r, r_r_new, p_Ap;
170 float *r = gv_calloc(n, sizeof(float));
171 float *p = gv_calloc(n, sizeof(float));
172 float *Ap = gv_calloc(n, sizeof(float));
173 float *Ax = gv_calloc(n, sizeof(float));
174
175 /* centering x and b */
176 orthog1f(n, x);
177 orthog1f(n, b);
178
179 right_mult_with_vector_ff(A, n, x, Ax);
180 /* centering Ax */
181 orthog1f(n, Ax);
182
183
184 vectors_subtractionf(n, b, Ax, r);
185 copy_vectorf(n, r, p);
186
187 r_r = vectors_inner_productf(n, r, r);
188
189 for (i = 0; i < max_iterations && max_absf(n, r) > tol; i++) {
190 orthog1f(n, p);
191 orthog1f(n, x);
192 orthog1f(n, r);
193
194 right_mult_with_vector_ff(A, n, p, Ap);
195 /* centering Ap */
196 orthog1f(n, Ap);
197
198 p_Ap = vectors_inner_productf(n, p, Ap);
199 if (p_Ap == 0)
200 break;
201 alpha = r_r / p_Ap;
202
203 /* derive new x: */
204 vectors_mult_additionf(n, x, (float) alpha, p);
205
206 /* compute values for next iteration: */
207 if (i < max_iterations - 1) { /* not last iteration */
208 vectors_mult_additionf(n, r, (float) -alpha, Ap);
209
210
211 r_r_new = vectors_inner_productf(n, r, r);
212
213 if (r_r == 0) {
214 rv = 1;
215 agerrorf("conjugate_gradient: unexpected length 0 vector\n");
216 goto cleanup2;
217 }
218 beta = r_r_new / r_r;
219 r_r = r_r_new;
220
221 for (size_t j = 0; j < (size_t)n; ++j) {
222 p[j] = (float)beta * p[j] + r[j];
223 }
224 }
225 }
226
227cleanup2 :
228 free(r);
229 free(p);
230 free(Ap);
231 free(Ax);
232 return rv;
233}
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
int conjugate_gradient(vtx_data *A, double *x, double *b, int n, double tol, int max_iterations)
Definition conjgrad.c:22
int conjugate_gradient_mkernel(float *A, float *x, float *b, int n, double tol, int max_iterations)
Definition conjgrad.c:160
int conjugate_gradient_f(float **A, double *x, double *b, int n, double tol, int max_iterations, bool ortho1)
Definition conjgrad.c:91
#define A(n, t)
Definition expr.h:76
void free(void *)
void agerrorf(const char *fmt,...)
Definition agerror.c:165
double vectors_inner_product(int n, const double *vector1, const double *vector2)
Definition matrix_ops.c:328
void orthog1f(int n, float *vec)
Definition matrix_ops.c:390
void right_mult_with_vector(vtx_data *matrix, int n, double *vector, double *result)
Definition matrix_ops.c:266
void right_mult_with_vector_f(float **matrix, int n, double *vector, double *result)
Definition matrix_ops.c:281
double max_absf(int n, float *vector)
Definition matrix_ops.c:491
void orthog1(int n, double *vec)
Definition matrix_ops.c:233
void copy_vectorf(int n, float *source, float *dest)
Definition matrix_ops.c:459
void right_mult_with_vector_ff(float *packed_matrix, int n, float *vector, float *result)
Definition matrix_ops.c:409
void vectors_mult_additionf(int n, float *vector1, float alpha, float *vector2)
Definition matrix_ops.c:451
double max_abs(int n, double *vector)
Definition matrix_ops.c:339
void vectors_subtraction(int n, double *vector1, double *vector2, double *result)
Definition matrix_ops.c:296
void vectors_addition(int n, double *vector1, double *vector2, double *result)
Definition matrix_ops.c:306
void copy_vector(int n, const double *source, double *dest)
Definition matrix_ops.c:322
void vectors_scalar_mult(int n, const double *vector, double alpha, double *result)
Definition matrix_ops.c:314
void vectors_subtractionf(int n, float *vector1, float *vector2, float *result)
Definition matrix_ops.c:433
double vectors_inner_productf(int n, float *vector1, float *vector2)
Definition matrix_ops.c:466
static void cleanup2(graph_t *g, int64_t nc)
Definition mincross.c:840
static void cleanup1(graph_t *g)
Definition rank.c:46
#define alpha
Definition shapes.c:4058
static const double tol