-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtestGramSchmidtReal.c
More file actions
200 lines (175 loc) · 6.35 KB
/
testGramSchmidtReal.c
File metadata and controls
200 lines (175 loc) · 6.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/* -----------------------------------------------------------------
* Programmer(s): Sylvia Amihere @ SMU
* -----------------------------------------------------------------
* SUNDIALS Copyright Start
* Copyright (c) 2002-2024, Lawrence Livermore National Security
* and Southern Methodist University.
* All rights reserved.
*
* See the top-level LICENSE and NOTICE files for details.
*
* SPDX-License-Identifier: BSD-3-Clause
* SUNDIALS Copyright End
* ------------------------------------------------------------------------
* These test functions check some components of a complex-valued
* SUNLINEARSOLVER module implementation (for more thorough tests,
* see the main SUNDIALS repository, inside examples/sunlinsol/).
* The solvers tested are the Classical Gram-Schmidt,
* Modified Gram-Schmidt and QR factorization (using Givens Rotation).
* ------------------------------------------------------------------------
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nvector_serialcomplex.h"
#include "sundials_iterativecomplex.h"
#include "sundials_iterativecomplex_impl.h" //Amihere
#if defined(SUNDIALS_EXTENDED_PRECISION)
#define GSYM "Lg"
#define ESYM "Le"
#define FSYM "Lf"
#else
#define GSYM "g"
#define ESYM "e"
#define FSYM "f"
#endif
SUNErrCode SUNClassicalGSComplex(N_Vector*, suncomplextype**, int k, int p,
suncomplextype* new_vk_norm, suncomplextype* stemp,
N_Vector* vtemp);
SUNErrCode SUNModifiedGSComplex(N_Vector* v, suncomplextype** h, int k, int p,
suncomplextype* new_vk_norm);
int SUNQRfactComplex(int n, suncomplextype** h, suncomplextype* q, int job);
int main(int argc, char* argv[])
{
N_Vector* V;
N_Vector x;
N_Vector* vtemp;
suncomplextype* stemp;
suncomplextype* vdata;
suncomplextype* givens;
SUNContext sunctx;
suncomplextype** H;
int k, l, job, n, krydim;
int comp1, comp2;
suncomplextype vnorm, ssnorm;
if (SUNContext_Create(SUN_COMM_NULL, &sunctx))
{
printf("ERROR: SUNContext_Create failed\n");
return (-1);
}
/* Create vectors */
x = N_VNew_SComplex(3, sunctx);
V = N_VCloneVectorArray(3, x);
N_Vector CheckV = N_VClone(x);
H = (suncomplextype**)malloc((3+1) * sizeof(suncomplextype*)); //Amihere
for (k = 0; k <= 3; k++)
{
H[k] = NULL;
H[k] = (suncomplextype*)malloc((3) * sizeof(suncomplextype)); //Amihere
}
// givens = (suncomplextype*)malloc(2 * 3 * sizeof(suncomplextype));
vtemp = (N_Vector*)malloc((3) * sizeof(N_Vector)); //Amihere
stemp = (suncomplextype*)malloc((3) * sizeof(suncomplextype)); //Amihere
/* set up matrix */
vdata = N_VGetArrayPointer_SComplex(V[0]);
vdata[0] = SUN_RCONST(12.0) + 0.0*I;
vdata[1] = 6.0 + 0.0*I;
vdata[2] = -4.0 + 0.0*I;
vdata = N_VGetArrayPointer_SComplex(V[1]);
vdata[0] = -51.0 + 0.0*I;
vdata[1] = 167.0 + 0.0*I;
vdata[2] = 24.0 + 0.0*I;
vdata = N_VGetArrayPointer_SComplex(V[2]);
vdata[0] = 4.0 + 0.0*I;
vdata[1] = -68.0 + 0.0*I;
vdata[2] = -41.0 + 0.0*I;
/* perform Gram-Schmidt process for all vectors in V */
char functionName[100] = "ClassicalGS"; // default function name
if (argc > 1) {
strcpy(functionName, argv[1]); //if a function name (2nd argument) is provided after executable name
}
if (strcmp(functionName, "ClassicalGS") == 0) {
printf("Using Classical Gram Schmidt \n");
for (k=0; k<3; k++){
SUNClassicalGSComplex(V, H, k, 3, &vnorm, stemp, vtemp);
N_VScale_SComplex(1.0/vnorm, V[k], V[k]);
}
}
else if (strcmp(functionName, "ModifiedGS") == 0) {
printf("Using Modified Gram Schmidt \n");
for (k=0; k<3; k++){
SUNModifiedGSComplex(V, H, k, 3, &vnorm);
N_VScale_SComplex(1.0/vnorm, V[k], V[k]);
}
}
else {
printf("Incorrect function name, use: ClassicalGS or ModifiedGS. \nUsing default: ClassicalGS\n");
for (k=0; k<3; k++){
SUNClassicalGSComplex(V, H, k, 3, &vnorm, stemp, vtemp);// Default function
N_VScale_SComplex(1.0/vnorm, V[k], V[k]);
}
}
/* Threshold for orthogonal vectors in matrix Q and imaginary component for the norm of a column vector in Q */
sunrealtype tolerance = 1e-14;
/* check dot product results */
int unit_vectorsReal = 0;
int unit_vectorsImag = 0;
int orthogonalReal = 0;
int orthogonalImag = 0;
/* check dot product results */
for (k=0; k<3; k++)
{
for (l=0; l<3; l++)
{
float vnorm = N_VDotProd_SComplex(V[k],V[l]);
// printf("<V[%i],V[%i]> = %e + %e I\n", l, k, creal(vnorm), cimag(vnorm));
if ((k==l) && (fabs(fabs(creal(vnorm))-SUN_RCONST(1.0)))>tolerance){unit_vectorsReal = 1;} //unit vectors
if ((k==l) && (fabs(cimag(vnorm))>tolerance)){unit_vectorsImag = 1;}
if ((k!=l) && (fabs(creal(vnorm))>tolerance)) {orthogonalReal = 1;}//orthogonal vectors
if ((k!=l) && (fabs(cimag(vnorm))>tolerance)) {orthogonalImag = 1;}
}
}
/* Check if the columns of Q are unit vectors. */
if ((unit_vectorsReal==0) && (unit_vectorsImag==0)) {
printf("The columns of Q are unit vectors!\n");
}
else if ((unit_vectorsReal==1) && (unit_vectorsImag==0)){
printf("The columns of Q are not unit vectors!\n");
// return 1;
}
else if ((unit_vectorsReal==0) && (unit_vectorsImag==1)){
printf("The columns of Q are not unit vectors!\n");
// return 1;
}
else if ((unit_vectorsReal==1) && (unit_vectorsImag==1)){
printf("The columns of Q are not unit vectors!\n");
// return 1;
}
/* Check if the columns of Q are orthogonal. */
if ((orthogonalReal==0) && (orthogonalImag==0)) {
printf("The columns of Q are orthogonal!\n");
}
else if ((orthogonalReal==1) && (orthogonalImag==0)){
printf("The columns of Q are not orthogonal!\n");
// return 1;
}
else if ((orthogonalReal==0) && (orthogonalImag==1)){
printf("The columns of Q are not orthogonal!\n");
// return 1;
}
else if ((orthogonalReal==1) && (orthogonalImag==1)){
printf("The columns of Q are not orthogonal!\n");
// return 1;
}
/* Check if the columns of Q are orthonormal. */
if ((orthogonalReal==0) && (orthogonalImag==0) && (unit_vectorsReal==0) && (unit_vectorsImag==0)){
printf("The columns of Q are orthonormal!\nTest Passed!\n");
}
else {
printf("The columns of Q are not orthonormal!\nTest failed!\n");
// return 1;
}
/* return with success */
return 0;
}