00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "matrix_ops.h"
00019 #include "conjgrad.h"
00020
00021 #include <stdlib.h>
00022
00023
00024
00025
00026
00027
00028 void conjugate_gradient
00029 (vtx_data * A, double *x, double *b, int n, double tol,
00030 int max_iterations) {
00031
00032
00033
00034 int i;
00035
00036 double alpha, beta, r_r, r_r_new, p_Ap;
00037 double *r = N_GNEW(n, double);
00038 double *p = N_GNEW(n, double);
00039 double *Ap = N_GNEW(n, double);
00040 double *Ax = N_GNEW(n, double);
00041 double *alphap = N_GNEW(n, double);
00042
00043 double *orth_b = N_GNEW(n, double);
00044 copy_vector(n, b, orth_b);
00045 orthog1(n, orth_b);
00046 orthog1(n, x);
00047 right_mult_with_vector(A, n, x, Ax);
00048 vectors_subtraction(n, orth_b, Ax, r);
00049 copy_vector(n, r, p);
00050 r_r = vectors_inner_product(n, r, r);
00051
00052 for (i = 0; i < max_iterations && max_abs(n, r) > tol; i++) {
00053 right_mult_with_vector(A, n, p, Ap);
00054 p_Ap = vectors_inner_product(n, p, Ap);
00055 if (p_Ap == 0)
00056 break;
00057 alpha = r_r / p_Ap;
00058
00059
00060 vectors_scalar_mult(n, p, alpha, alphap);
00061 vectors_addition(n, x, alphap, x);
00062
00063
00064 if (i < max_iterations - 1) {
00065 vectors_scalar_mult(n, Ap, alpha, Ap);
00066 vectors_subtraction(n, r, Ap, r);
00067
00068
00069
00070
00071
00072 r_r_new = vectors_inner_product(n, r, r);
00073 if (r_r == 0)
00074 exit(1);
00075 beta = r_r_new / r_r;
00076 r_r = r_r_new;
00077 vectors_scalar_mult(n, p, beta, p);
00078 vectors_addition(n, r, p, p);
00079 }
00080 }
00081
00082 free(r);
00083 free(p);
00084 free(Ap);
00085 free(Ax);
00086 free(alphap);
00087 free(orth_b);
00088
00089 }
00090
00091
00092
00093
00094
00095
00096 void conjugate_gradient_f
00097 (float **A, double *x, double *b, int n, double tol,
00098 int max_iterations, boolean ortho1) {
00099
00100
00101
00102 int i;
00103
00104 double alpha, beta, r_r, r_r_new, p_Ap;
00105 double *r = N_GNEW(n, double);
00106 double *p = N_GNEW(n, double);
00107 double *Ap = N_GNEW(n, double);
00108 double *Ax = N_GNEW(n, double);
00109 double *alphap = N_GNEW(n, double);
00110
00111 double *orth_b = N_GNEW(n, double);
00112 copy_vector(n, b, orth_b);
00113 if (ortho1) {
00114 orthog1(n, orth_b);
00115 orthog1(n, x);
00116 }
00117 right_mult_with_vector_f(A, n, x, Ax);
00118 vectors_subtraction(n, orth_b, Ax, r);
00119 copy_vector(n, r, p);
00120 r_r = vectors_inner_product(n, r, r);
00121
00122 for (i = 0; i < max_iterations && max_abs(n, r) > tol; i++) {
00123 right_mult_with_vector_f(A, n, p, Ap);
00124 p_Ap = vectors_inner_product(n, p, Ap);
00125 if (p_Ap == 0)
00126 break;
00127 alpha = r_r / p_Ap;
00128
00129
00130 vectors_scalar_mult(n, p, alpha, alphap);
00131 vectors_addition(n, x, alphap, x);
00132
00133
00134 if (i < max_iterations - 1) {
00135 vectors_scalar_mult(n, Ap, alpha, Ap);
00136 vectors_subtraction(n, r, Ap, r);
00137
00138
00139
00140
00141
00142 r_r_new = vectors_inner_product(n, r, r);
00143 if (r_r == 0)
00144 exit(1);
00145 beta = r_r_new / r_r;
00146 r_r = r_r_new;
00147 vectors_scalar_mult(n, p, beta, p);
00148 vectors_addition(n, r, p, p);
00149 }
00150 }
00151
00152 free(r);
00153 free(p);
00154 free(Ap);
00155 free(Ax);
00156 free(alphap);
00157 free(orth_b);
00158
00159 }
00160
00161 void
00162 conjugate_gradient_mkernel(float *A, float *x, float *b, int n,
00163 double tol, int max_iterations)
00164 {
00165
00166
00167
00168
00169 int i;
00170
00171 double alpha, beta, r_r, r_r_new, p_Ap;
00172 float *r = N_NEW(n, float);
00173 float *p = N_NEW(n, float);
00174 float *Ap = N_NEW(n, float);
00175 float *Ax = N_NEW(n, float);
00176
00177
00178 orthog1f(n, x);
00179 orthog1f(n, b);
00180
00181 right_mult_with_vector_ff(A, n, x, Ax);
00182
00183 orthog1f(n, Ax);
00184
00185
00186 vectors_substractionf(n, b, Ax, r);
00187 copy_vectorf(n, r, p);
00188
00189 r_r = vectors_inner_productf(n, r, r);
00190
00191 for (i = 0; i < max_iterations && max_absf(n, r) > tol; i++) {
00192 orthog1f(n, p);
00193 orthog1f(n, x);
00194 orthog1f(n, r);
00195
00196 right_mult_with_vector_ff(A, n, p, Ap);
00197
00198 orthog1f(n, Ap);
00199
00200 p_Ap = vectors_inner_productf(n, p, Ap);
00201 if (p_Ap == 0)
00202 break;
00203 alpha = r_r / p_Ap;
00204
00205
00206 vectors_mult_additionf(n, x, (float) alpha, p);
00207
00208
00209 if (i < max_iterations - 1) {
00210 vectors_mult_additionf(n, r, (float) -alpha, Ap);
00211
00212
00213 r_r_new = vectors_inner_productf(n, r, r);
00214
00215 if (r_r == 0)
00216 exit(1);
00217 beta = r_r_new / r_r;
00218 r_r = r_r_new;
00219
00220 vectors_scalar_multf(n, p, (float) beta, p);
00221
00222 vectors_additionf(n, r, p, p);
00223 }
00224 }
00225
00226 free(r);
00227 free(p);
00228 free(Ap);
00229 free(Ax);
00230 }