source: CIVL/examples/cg/cg.cvl

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 2.4 KB
Line 
1/*
2 * Simple implementation of Conjugate Gradient algorithm for an
3 * arbitrary symmetric positive definite square matrix.
4 * Instead of assuming positive-definite-ness,
5 * we assume that in every division, the denominator is non-0.
6 * Based on https://en.wikipedia.org/wiki/Conjugate_gradient_method
7 */
8
9#include <stdio.h>
10
11$input int N = 5; // should be greater than 0
12$input double A[N][N]; // only use upper triangle
13$input double B[N]; // right-hand side
14
15void cg(int n, double a[n][n], double b[n], double x[n], int nsteps) {
16 double r[n];
17 double p[n];
18 double temp[n];
19 double tempp[n];
20 double rsold;
21 double rsnew;
22 double rsfrac;
23 double alpha;
24
25 // x = 0 [could make this arbitrary]
26 for (int i=0; i<nsteps; i++)
27 x[i] = 0;
28 // temp = A*x [unnecessary if x=0]
29 for (int i=0; i<n; i++) {
30 temp[i] = 0.0;
31 for (int j=0; j<n; j++)
32 temp[i] += a[i][j]*x[j];
33 }
34 // r = b-temp
35 for (int i=0; i<n; i++)
36 r[i] = b[i] - temp[i];
37 // rsold = <r,r>
38 rsold = 0.0;
39 for (int i=0; i<n; i++)
40 rsold += r[i]*r[i];
41 // p=r
42 for (int i=0; i<n; i++)
43 p[i] = r[i];
44 for (int step=0; step<nsteps; step++) {
45 for (int i=0; i<n; i++) {
46 temp[i] = 0.0;
47 for (int j=0; j<n; j++)
48 temp[i] += a[i][j]*p[j];
49 }
50 alpha = 0.0;
51 for (int i=0; i<n; i++)
52 alpha += p[i]*temp[i];
53 alpha = rsold/alpha;
54 // tempp = r-alpha*temp
55 for (int i=0; i<n; i++)
56 tempp[i] = r[i] - alpha*temp[i];
57 for (int i=0; i<n; i++)
58 r[i] = tempp[i];
59 for (int i=0; i<n; i++)
60 tempp[i] = x[i] + alpha*p[i];
61 for (int i=0; i<n; i++)
62 x[i] = tempp[i];
63 if (step < nsteps-1) {
64 // rsnew = <r,r>
65 rsnew = 0.0;
66 for (int i=0; i<n; i++)
67 rsnew += r[i]*r[i];
68 $assume(rsold !=0);
69 rsfrac = rsnew/rsold;
70 for (int i=0; i<n; i++)
71 tempp[i] = r[i] + rsfrac*p[i];
72 for (int i=0; i<n; i++)
73 p[i] = tempp[i];
74 rsold = rsnew;
75 }
76 }
77}
78
79void main() {
80 double matrix[N][N];
81 double solution[N];
82
83 for (int i=0; i<N; i++) {
84 for (int j=0; j<i; j++) {
85 matrix[i][j] = A[i][j];
86 matrix[j][i] = A[i][j];
87 }
88 matrix[i][i] = A[i][i];
89 }
90 cg(N, matrix, B, solution, N);
91 // check the solution is a solution...
92 for (int i=0; i<N; i++) {
93 double check = 0;
94
95 for (int j=0; j<N; j++)
96 check += matrix[i][j]*solution[j];
97 $assert(check == B[i]);
98 }
99}
Note: See TracBrowser for help on using the repository browser.