summaryrefslogtreecommitdiffstats
path: root/dis/Matrix/ver1/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'dis/Matrix/ver1/matrix.c')
-rwxr-xr-xdis/Matrix/ver1/matrix.c600
1 files changed, 600 insertions, 0 deletions
diff --git a/dis/Matrix/ver1/matrix.c b/dis/Matrix/ver1/matrix.c
new file mode 100755
index 0000000..518a638
--- /dev/null
+++ b/dis/Matrix/ver1/matrix.c
@@ -0,0 +1,600 @@
1/*
2 * Sample code for the DIS Matrix Stressmark
3 *
4 * This source code is the completely correct source code based on
5 * the example codes provided by Atlantic Aerospace Division, Titan
6 * Systems Corporation, 2000.
7 *
8 * If you just compile and generate the executables from this source
9 * code, this code would be enough. However, if you wish to get a complete
10 * understanding of this stressmark, it is strongly suggested that you
11 * read the Benchmark Analysis and Specifications Document Version 1.0
12 * before going on since the detailed comments are given in this documents.
13 * the comments are not repeated here.
14 */
15
16/*
17 * The Sparse Matrix Storage is implemented by Compact Row Storage Scheme
18 * In the code, the data is first generated by randomNonzeroFloat()
19 * the data is first stored in a full-space matrix with size of dim*dim
20 * then the data is transfered to the Compact Row Matrix,
21 * the data value is kept in *value,
22 * the columns corresponding to the value are stored in *col_ind,
23 * the start element of each row is stored in *row_start.
24 */
25
26/*
27 * Please note:
28 * the total number of data is numberNonzero +dim
29 * among which, NumberNonzero because this is symmetric matrix
30 * dim because the diagonal elements
31 */
32
33#include <stdio.h>
34#include <math.h>
35#include <stdlib.h>
36#include <time.h>
37#include <assert.h>
38#include "DISstressmarkRNG.h"
39
40#define MIN_SEED -2147483647
41#define MAX_SEED -1
42#define MIN_DIM 1
43#define MAX_DIM 32768
44#define MAX_ITERATIONS 65536
45#define MIN_TOLERANCE 0.000007
46#define MAX_TOLERANCE 0.5
47#define MIN_NUMBER -3.4e10/dim
48#define MAX_NUMBER 3.4e10/dim
49#define EPSI 1.0e-10
50#define MIN_DIG_NUMBER 1.0e-10
51#define MAX_DIG_NUMBER 3.4e10
52
53/*
54 * External variable, dimension
55 */
56
57static int dim;
58
59/*
60 * matrix * vector
61 */
62
63double *matrixMulvector(double *value,
64 int *col_ind,
65 int *row_start,
66 double *vector)
67{
68 int l, ll;
69 double *out;
70 double sum;
71 int tmp_rs, tmp_re;
72
73 out = (double *)malloc(dim*sizeof(double));
74
75 for (l=0; l<dim; l++){
76 *(out + l) = 0;
77 tmp_rs = row_start[l];
78
79 if (tmp_rs != -1){
80 tmp_re = row_start[l+1]; /*
81 *get the start and ending elements of
82 * each row
83 */
84 for (ll=tmp_rs; ll<tmp_re; ll++){
85 *(out + l) += value[ll]*vector[col_ind[ll]];
86 }
87 }
88 }
89 return out;
90}
91
92
93/*
94 * vector1 - vector2
95 */
96
97double *vectorSub(double *vector1, double *vector2){
98
99 int l;
100 double *vector;
101 vector = (double *)malloc(dim*sizeof(double ));
102 for (l=0; l<dim; l++){
103 *(vector + l) = *(vector1 + l) - *(vector2 + l);
104 }
105 return vector;
106}
107
108
109/*
110 * vector1 + vector2
111 */
112
113double *vectorAdd(double *vector1, double *vector2){
114
115 int l;
116 double *vector;
117
118 vector = (double *)malloc(dim*sizeof(double ));
119
120 for (l=0; l<dim; l++){
121 *(vector + l) = *(vector1 + l) + *(vector2 + l);
122 }
123 return vector;
124}
125
126/*
127 * vector1 * vector2
128 */
129
130double vectorMul(double *vector1, double *vector2){
131
132 int l;
133 double product;
134
135 product = 0;
136
137 for (l=0; l<dim; l++){
138 product += (*(vector1 + l))*(*(vector2 + l));
139
140 }
141 return product;
142}
143
144/*
145 * /vector/
146 */
147
148double vectorValue(double *vector){
149
150 double value;
151 int l;
152
153 value = 0;
154
155 for (l=0; l<dim; l++){
156 value += (*(vector + l)) * (*(vector + l));
157 }
158
159 return (sqrt(value));
160}
161
162/*
163 * transpose(vector)
164 * In fact, we return the original vector here
165 */
166
167double *transpose(double *vector){
168
169 double *vect;
170 int l;
171
172 vect = (double *)malloc(dim*sizeof(double ));
173
174 for (l=0; l<dim; l++){
175 *(vect+l) = *(vector+l);
176 }
177 return vect;
178}
179
180/*
181 * value * <vector>
182 */
183double *valueMulvector(double value, double *vector){
184
185 int l;
186 double *vect;
187 int lll;
188 double sum;
189
190 vect = (double *) malloc(dim * sizeof(double ));
191
192 for (l=0; l<dim; l++){
193 *(vect + l) = (*(vector + l)) * value;
194 }
195
196 return vect;
197}
198
199/*
200 * generate the data distributed sparsely in matrix
201 */
202
203void initMatrix(double *matrix, int dim, int numberNonzero){
204
205 int k, l, ll;
206 int i, j;
207
208 int lll;
209 double sum;
210
211 for (k=0; k< dim*dim; k++){
212 *(matrix + k) = 0;
213 }
214
215 for (l=0; l<numberNonzero/2; l++){
216
217 i = randomUInt(1, dim-1);
218 j = randomUInt(0, i-1);
219
220 while (*(matrix + i*dim + j) != 0){
221
222 i++;
223 if (i == dim){
224 j++;
225 if (j == dim-1){
226 j = 0;
227 i = 1;
228 }
229 else{
230 i = j+1;
231 }
232 }
233 }
234
235 if (*(matrix + i*dim + j) == 0){
236 *(matrix + i*dim + j) = (double )randomNonZeroFloat(MIN_NUMBER,
237 MAX_NUMBER,
238 EPSI);
239 *(matrix + j*dim + i) = *(matrix + i*dim + j);
240 }
241 }
242
243 for (ll=0; ll<dim; ll++){
244
245
246
247 *(matrix + ll*dim + ll) = (double )randomNonZeroFloat(-MAX_DIG_NUMBER,
248 MAX_DIG_NUMBER,
249 MIN_DIG_NUMBER);
250
251 sum = 0;
252
253 for (lll=0; lll<dim; lll++){
254 if (lll != ll){
255 sum += *(matrix + lll*dim + ll);
256 }
257 }
258
259 if (*(matrix + ll*dim + ll) < sum ){
260 *(matrix + ll*dim + ll) += sum;
261 }
262 }
263
264 return;
265}
266
267/*
268 * generate the data value in the vectors
269 */
270
271void initVector(double *vector, int dim){
272
273 int l;
274
275 for (l=0; l<dim; l++){
276 *(vector + l) = (double )randomFloat (MIN_NUMBER, MAX_NUMBER);
277 }
278
279 return;
280}
281
282/*
283 * make a vector contains value of zero
284 */
285
286void zeroVector(double *vector, int dim){
287 int l;
288
289 for (l=0; l<dim; l++){
290 *(vector + l) = 0;
291 }
292 return;
293}
294
295/*
296 * return a vector which is the copy of the vect
297 */
298
299double *equalVector(double *vect){
300
301 int l;
302 double *vect1;
303
304 vect1 = (double *)malloc(dim*sizeof(double ));
305
306 for (l=0; l<dim; l++){
307 *(vect1+l) = *(vect+l);
308 }
309 return vect1;
310}
311
312
313
314void biConjugateGradient(double *value,
315 int *col_ind,
316 int *row_start,
317 double *vectorB,
318 double *vectorX,
319 double errorTolerance,
320 int maxIterations,
321 double *actualError,
322 int *actualIteration,
323 int dim)
324 /*
325 * in the code, we use a lot of temparary vectors and variables
326 * this is just for simple and clear
327 * you can optimize these temporary variables and vectors
328 * based on your need
329 *
330 */
331{
332 double *vectorR;
333 double *vectorP, *matrixAvectorP, *nextVectorR;
334 double error;
335 int iteration;
336 double alpha, beta;
337
338 double *temp0, *temp1,*temp2, *temp3;
339 double *temp4, temp5, temp6, *temp7 ;
340 double *temp8, *temp9, temp10, *temp11;
341 double temp12, *temp13, *temp14;
342 double *temp15, *temp16, *temp17;
343
344 int l;
345 int ll;
346
347 alpha = 0;
348 beta = 0;
349
350 /*
351 * vectorR = vectorB - matrixA*vectorX
352 */
353 temp0 = matrixMulvector(value,col_ind, row_start, vectorX);
354 vectorR = vectorSub(vectorB, temp0);
355
356 /*
357 * vectorP = vectorR
358 */
359 vectorP = equalVector(vectorR);
360
361 /*
362 * error = |matrixA * vectorX - vectorB| / |vectorB|
363 */
364 temp2 = vectorSub(temp0, vectorB);
365 error = vectorValue(temp2)/vectorValue(vectorB);
366
367 free(temp0);
368 free (temp2);
369
370 iteration = 0;
371
372
373 while ((iteration < maxIterations) && (error > errorTolerance)){
374
375 /*
376 * alpha = (transpose(vectorR) * vectorR) /
377 * (transpose(vectorP) * (matrixA * vectorP)
378 */
379 temp1 = matrixMulvector(value, col_ind, row_start, vectorP);
380 temp3 = transpose(vectorR);
381 temp4 = transpose(vectorP);
382 temp5 = vectorMul(temp4, temp1);
383 temp6 = vectorMul(temp3, vectorR);
384 alpha = temp6/temp5;
385
386 /*
387 * nextVectorR = vectorR - alpha*(matrixA * vectorP)
388 */
389
390 temp7 = valueMulvector(alpha, temp1);
391 temp8 = vectorSub(vectorR, temp7);
392 nextVectorR = equalVector(temp8);
393
394 /*
395 * beta = (transpose(nextVectorR) * nextVectorR) /
396 * (transpose(vectorR) * vectorR)
397 */
398 temp9 = transpose(nextVectorR);
399 temp10 = vectorMul(temp9, nextVectorR);
400 temp11 = transpose(vectorR);
401 temp12 = vectorMul(temp11, vectorR);
402 beta = temp10/temp12;
403
404 /*
405 * vectorX = vectorX + alpha * vectorP
406 */
407 temp13 = valueMulvector(alpha, vectorP);
408 vectorX = vectorAdd(vectorX,temp13);
409
410 /*
411 *vectorP = nextVectorR + beta*vectorP
412 */
413 temp14 = valueMulvector(beta, vectorP);
414 temp17 = vectorAdd(nextVectorR, temp14);
415
416 for (ll=0; ll<dim; ll++){
417 *(vectorP + ll) = *(temp17 + ll);
418 }
419
420 /*
421 * vectorR = nextVectorR
422 */
423
424 for (l=0; l<dim; l++){
425 *(vectorR+l) = *(nextVectorR+l);
426 }
427
428 /*
429 * error = |matrixA * vectorX - vectorB| / |vectorB|
430 */
431 temp15 = matrixMulvector(value, col_ind,row_start, vectorX);
432 temp16 = vectorSub(temp15,vectorB);
433 error = vectorValue(temp16)/vectorValue(vectorB);
434
435 free(temp1);
436 free(temp3);
437 free(temp4);
438 free(temp7);
439 free(temp8);
440 free(temp9);
441 free(temp11);
442 free(nextVectorR);
443 free(temp13);
444 free(temp14);
445 free(temp15);
446 free(temp16);
447 free(temp17);
448
449 iteration++;
450 }
451
452 *actualError = error;
453 *actualIteration = iteration;
454
455 free(vectorR);
456 free(vectorP);
457
458 return;
459}
460
461/*
462 * This is the function to transfer the data from the matrix of dense storage
463 * to Compact Row Storage
464 */
465void create_CRS(double *matrixA,
466 double *value,
467 int *col_ind,
468 int *row_start,
469 int dim,
470 int numberNonzero)
471{
472
473 int i, j, k;
474 int cnt;
475 double tmp;
476
477 /*
478 *initialize the row_start
479 */
480
481 for(k=0; k<dim; k++){
482 row_start[k] = -1;
483 }
484
485 /*
486 * make the end of the last row to be numberNonzero + dim.
487 */
488
489 row_start[dim] = numberNonzero+dim;
490
491 /*
492 * initialize the col_ind
493 */
494
495 for (k=0; k<numberNonzero+dim; k++){
496 col_ind[k] = -1;
497 }
498
499
500 cnt = 0;
501
502 for (i=0; (cnt<numberNonzero+dim)&&(i<dim); i++){
503 for (j=0; (cnt<numberNonzero+dim)&&(j<dim); j++){
504
505 tmp = *(matrixA + i*dim + j);
506
507 if (tmp!=0){
508
509 value[cnt] = tmp;
510 col_ind[cnt] = j;
511
512 if (row_start[i] == -1)
513 row_start[i] = cnt;
514
515 cnt += 1;
516 }
517 }
518 }
519 row_start[i] = cnt;
520
521 return;
522}
523
524
525
526int main()
527{
528 int seed;
529 int numberNonzero;
530 int maxIterations;
531 float errorTolerance;
532 double actualError;
533 int actualIteration;
534
535 time_t beginTime;
536 time_t endTime;
537
538 double *matrixA;
539 double *vectorB;
540 double *vectorX;
541
542 double *value;
543 int *col_ind;
544 int *row_start;
545 int sum;
546 int k;
547
548 fscanf(stdin, "%d %d %d %d %f",
549 &seed, &dim, &numberNonzero,&maxIterations,&errorTolerance);
550 assert((seed > MIN_SEED) && (seed < MAX_SEED));
551 assert((dim > MIN_DIM) && (dim < MAX_DIM));
552 assert((numberNonzero > dim) && (numberNonzero < dim*dim));
553 assert((maxIterations > 0) && (maxIterations < MAX_ITERATIONS));
554 assert((errorTolerance > MIN_TOLERANCE) && (errorTolerance < MAX_TOLERANCE));
555
556 matrixA = (double *)malloc(dim*dim*sizeof(double ));
557 vectorB = (double *)malloc(dim*sizeof(double));
558 vectorX = (double *)malloc(dim*sizeof(double));
559
560 value = (double *)malloc((numberNonzero+dim)*sizeof(double));
561 col_ind = (int *)malloc((numberNonzero+dim)*sizeof(int));
562 row_start = (int *)malloc((dim+1)*sizeof(int));
563
564 randInit(seed);
565
566 initMatrix(matrixA, dim, numberNonzero);
567
568 create_CRS(matrixA, value, col_ind, row_start, dim, numberNonzero);
569
570 initVector(vectorB, dim);
571 zeroVector(vectorX, dim);
572 printf(" after init\n");
573
574 beginTime = time(NULL);
575
576 actualError = 0;
577 actualIteration = 0;
578
579 biConjugateGradient(value, col_ind, row_start, vectorB, vectorX, errorTolerance,
580 maxIterations,
581 &actualError, &actualIteration, dim);
582
583
584
585 endTime = time(NULL) - beginTime;
586
587
588
589 sum = 0;
590 for (k=1; k<dim; k++){
591 sum += sum + *(vectorX + k);
592 }
593
594 fprintf(stdout, "sum = %d, actualError = %e, actualIteration = %d\n", sum, actualError, actualIteration);
595 fprintf(stdout, "total time = %u sec. \n", (unsigned int)endTime);
596
597 return(0);
598 }
599
600