source: CIVL/examples/cg/cg3_sylvester.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.9 KB
Line 
1/*
2 * CG 3x3 case with positive definite assumption based on Sylvester's criteria.
3 * From wiki:
4 * Sylvester's criterion states that a Hermitian matrix M is positive-definite
5 * if and only if all the following matrices have a positive determinant:
6 * the upper left 1-by-1 corner of M,
7 * the upper left 2-by-2 corner of M,
8 * the upper left 3-by-3 corner of M,
9 * M itself.
10 * In other words, all of the leading principal minors must be positive.
11 */
12#include <civlc.cvh>
13#include <stdio.h>
14#define n 3
15
16$input double diag1,diag2,diag3,off1,off2,off3;
17$input double b[n];
18double x[n];
19double xcg[n];
20
21void cg(double A[n][n], double b[n], double x[n], int steps) {
22 double r[n];
23 double p[n];
24 double temp[n];
25 double tempp[n];
26 double rsold;
27 double rsnew;
28 double rsfrac;
29 double alpha;
30
31 // x = 0
32 for(int i=0; i<n; i++) x[i] = 0;
33
34 // temp = A*x
35 for(int i=0; i<n; i++) {
36 temp[i] = 0.0;
37 for(int j=0; j<n; j++) {
38 temp[i] += A[i][j]*x[j];
39 }
40 }
41
42 // r = b-temp
43 for(int i=0; i<n; i++) {
44 r[i] = b[i] -temp[i];
45 }
46
47 // rsold = <r,r>
48 rsold = 0.0;
49 for(int i=0; i<n; i++) {
50 rsold += r[i]*r[i];
51 }
52
53 // p=r
54 for(int i=0; i<n; i++) {
55 p[i] = r[i];
56 }
57
58 for(int i=0; i<steps; i++) {
59 // temp = A*p
60 for(int i=0; i<n; i++) {
61 temp[i] = 0.0;
62 for(int j=0; j<n; j++) {
63 temp[i] += A[i][j]*p[j];
64 }
65 }
66 alpha = 0.0;
67 for(int i=0; i<n; i++) {
68 alpha += p[i]*temp[i];
69 }
70
71 $assume(alpha !=0);
72
73 alpha = rsold/alpha;
74 // tempp = r-alpha*temp
75 for(int i=0; i<n; i++) {
76 tempp[i] = r[i] -alpha*temp[i];
77 }
78 for(int i=0; i<n; i++) {
79 r[i] = tempp[i];
80 }
81 for(int i=0; i<n; i++) {
82 tempp[i] = x[i] +alpha*p[i];
83 }
84 for(int i=0; i<n; i++) {
85 x[i] = tempp[i];
86 }
87 if(i<steps-1) {
88 // rsnew = <r,r>
89 rsnew = 0.0;
90 for(int i=0; i<n; i++) {
91 rsnew += r[i]*r[i];
92 }
93
94 $assume(rsold !=0);
95
96 rsfrac = rsnew/rsold;
97 for(int i=0; i<n; i++) {
98 tempp[i] = r[i] +rsfrac*p[i];
99 }
100 for(int i=0; i<n; i++) {
101 p[i] = tempp[i];
102 }
103 rsold = rsnew;
104 }
105 }
106}
107
108void main() {
109 double bncg[n];
110 double A[n][n];
111
112 A[0][0] = diag1;
113 A[1][1] = diag2;
114 A[2][2] = diag3;
115 A[0][1] = off1;
116 A[1][0] = off1;
117 A[0][2] = off2;
118 A[2][0] = off2;
119 A[1][2] = off3;
120 A[2][1] = off3;
121
122 $assume(b[0]!=0 || b[1]!=0 || b[2]!=0);
123 $assume(diag1 > 0); //assumption of Sylvester's criterion
124 $assume((diag1*diag2 - off1*off1) > 0);//all principal minors are positive.
125 $assume((diag1*diag2*diag3 + 2*off1*off2*off3 - diag1*off3*off3 - diag2*off2*off2 - diag3*off1*off1) > 0);
126
127 cg(A,b,xcg,n);
128 printf("\n================Solution x:================\n");
129 for(int i=0; i<n; i++) {
130 printf("x[%d] = %f\n\n",i, xcg[i]);
131 }
132 for(int i=0; i<n; i++) {
133 bncg[i] = 0;
134 for(int j=0; j<n; j++) {
135 bncg[i] += A[i][j]*xcg[j];
136 }
137 $assert(bncg[i] == b[i]);
138 }
139}
Note: See TracBrowser for help on using the repository browser.