Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/matc/src/matrix.c
3196 views
1
/*****************************************************************************
2
*
3
* Elmer, A Finite Element Software for Multiphysical Problems
4
*
5
* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6
*
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library (in file ../LGPL-2.1); if not, write
19
* to the Free Software Foundation, Inc., 51 Franklin Street,
20
* Fifth Floor, Boston, MA 02110-1301 USA
21
*
22
*****************************************************************************/
23
24
/*******************************************************************************
25
*
26
* MATC matrix utilities.
27
*
28
*******************************************************************************
29
*
30
* Author: Juha Ruokolainen
31
*
32
* Address: CSC - IT Center for Science Ltd.
33
* Keilaranta 14, P.O. BOX 405
34
* 02101 Espoo, Finland
35
* Tel. +358 0 457 2723
36
* Telefax: +358 0 457 2302
37
* EMail: [email protected]
38
*
39
* Date: 30 May 1996
40
*
41
* Modified by:
42
*
43
* Date of modification:
44
*
45
******************************************************************************/
46
/***********************************************************************
47
|
48
| MATRIX.C - Last Edited 8. 8. 1988
49
|
50
***********************************************************************/
51
52
/*======================================================================
53
|Syntax of the manual pages:
54
|
55
|FUNCTION NAME(...) params ...
56
|
57
$ usage of the function and type of the parameters
58
? explain the effects of the function
59
= return value and the type of value if not of type int
60
@ globals effected directly by this routine
61
! current known bugs or limitations
62
& functions called by this function
63
~ these functions may interest you as an alternative function or
64
| because they control this function somehow
65
^=====================================================================*/
66
67
68
/*
69
* $Id: matrix.c,v 1.1.1.1 2005/04/14 13:29:14 vierinen Exp $
70
*
71
* $Log: matrix.c,v $
72
* Revision 1.1.1.1 2005/04/14 13:29:14 vierinen
73
* initial matc automake package
74
*
75
* Revision 1.2 1998/08/01 12:34:50 jpr
76
*
77
* Added Id, started Log.
78
*
79
*
80
*/
81
82
#include "elmer/matc.h"
83
84
#define MA(i,j) a[(i) * ncola + (j)]
85
#define MB(i,j) b[(i) * ncolb + (j)]
86
#define MC(i,j) c[(i) * ncolc + (j)]
87
88
double func_abs(double arg)
89
{
90
return abs(arg);
91
}
92
93
double func_mod(double x, double y)
94
{
95
int ix, iy;
96
97
ix = x + 0.5;
98
iy = y + 0.5;
99
return (double)(ix % iy);
100
}
101
102
VARIABLE *mtr_sum(VARIABLE *A)
103
{
104
VARIABLE *C;
105
106
int i, j;
107
108
int nrowa = NROW(A), ncola = NCOL(A);
109
110
double *a = MATR(A), *c;
111
112
113
if (nrowa == 1 || ncola == 1)
114
{
115
C = var_temp_new(TYPE_DOUBLE, 1, 1); c = MATR(C);
116
nrowa = (nrowa == 1) ? ncola : nrowa;
117
for(i = 0; i < nrowa; i++) *c += *a++;
118
}
119
else
120
{
121
C = var_temp_new(TYPE_DOUBLE, 1, ncola); c = MATR(C);
122
for(i = 0; i < ncola; i++)
123
for(j = 0; j < nrowa; j++) c[i] += MA(j, i);
124
}
125
126
return C;
127
}
128
129
VARIABLE *mtr_trace(VARIABLE *A)
130
{
131
VARIABLE *C;
132
133
double temp = 0.0;
134
int i;
135
136
int nrowa = NROW(A), ncola = NCOL(A);
137
double *a = MATR(A);
138
139
if (nrowa != ncola) error("trace: not square.\n");
140
141
for(i = 0; i < nrowa; i++) temp += MA(i,i);
142
143
C = var_temp_new(TYPE(A), 1, 1); *MATR(C) = temp;
144
145
return C;
146
}
147
148
VARIABLE *mtr_zeros(VARIABLE *A)
149
{
150
VARIABLE *C;
151
152
int ind1 = 1, ind2 = 1;
153
154
if (NEXT(A) != NULL)
155
{
156
ind1 = (int)*MATR(A); ind2 = (int)*MATR(NEXT(A));
157
}
158
else
159
{
160
ind2 = (int)*MATR(A);
161
}
162
163
if (ind1 < 1 || ind2 < 1)
164
error("Zeros: invalid size for and array");
165
166
C = var_temp_new(TYPE_DOUBLE, ind1, ind2);
167
168
return C;
169
}
170
171
VARIABLE *mtr_ones(VARIABLE *A)
172
{
173
VARIABLE *C;
174
double *c;
175
int i, n;
176
177
C = mtr_zeros(A); c = MATR(C);
178
n = NROW(C) * NCOL(C);
179
180
for(i = 0; i < n; i++) *c++ = 1.0;
181
182
return C;
183
}
184
185
VARIABLE *mtr_rand(VARIABLE *A)
186
{
187
VARIABLE *C;
188
189
static int seed = 0;
190
#pragma omp threadprivate (seed)
191
int i, n;
192
193
double *c;
194
195
C = mtr_zeros(A); c = MATR(C);
196
n = NROW(C) * NCOL(C);
197
198
if (seed == 0) seed = time(NULL);
199
for(i = 0; i < n; i++) *c++ = urand(&seed);
200
201
return C;
202
}
203
204
VARIABLE *mtr_resize(VARIABLE *A)
205
{
206
VARIABLE *C;
207
208
int i, j, n, m, ind1 = 1, ind2;
209
210
double *a = MATR(A), *c;
211
212
if (NEXT(NEXT(A)) != NULL)
213
{
214
ind1 = *MATR(NEXT(A)); ind2 = *MATR(NEXT(NEXT(A)));
215
}
216
else
217
{
218
ind2 = (int)*MATR(NEXT(A));;
219
}
220
221
if (ind1 < 1 || ind2 < 1)
222
error("resize: invalid size for and array");
223
224
C = var_temp_new(TYPE(A), ind1, ind2); c = MATR(C);
225
a = MATR(A); n = ind1 * ind2; m = NROW(A) * NCOL(A);
226
227
for(i = j = 0; i < n; i++)
228
{
229
*c++ = a[j++]; if (j == m) j = 0;
230
}
231
232
return C;
233
}
234
235
VARIABLE *mtr_vector(VARIABLE *A)
236
{
237
VARIABLE *C;
238
239
double start, stop, incr, x, *c;
240
241
int i, eval;
242
243
start = *MATR(A); stop = *MATR(NEXT(A));
244
245
if (NEXT(NEXT(A)) != (VARIABLE *)NULL)
246
incr = *MATR(NEXT(NEXT(A)));
247
else
248
incr = (start < stop) ? (1) : (-1);
249
250
if (incr == 0)
251
incr = (start < stop) ? (1) : (-1);
252
253
eval = (int)(abs(stop-start) / abs(incr)) + 1;
254
if (eval < 1) return NULL;
255
256
C = var_temp_new(TYPE_DOUBLE, 1, eval); c = MATR(C);
257
258
x = start;
259
for(i = 0; i < eval; i++)
260
{
261
*c++ = x; x += incr;
262
}
263
264
return C;
265
}
266
267
VARIABLE *mtr_eye(VARIABLE *A)
268
{
269
VARIABLE *C;
270
double *c;
271
int i, ind, ncolc;
272
273
if (*MATR(A) < 1)
274
{
275
error("eye: Invalid size for an array.\n");
276
}
277
278
ind = (int)*MATR(A);
279
280
C = var_temp_new(TYPE_DOUBLE, ind, ind);
281
c = MATR(C); ncolc = ind;
282
283
for (i = 0; i < ind; i++) MC(i,i) = 1.0;
284
285
return C;
286
}
287
288
VARIABLE *mtr_size(VARIABLE *A)
289
{
290
VARIABLE *C;
291
double *c;
292
293
C = var_temp_new(TYPE_DOUBLE, 1, 2); c = MATR(C);
294
*c++ = NROW(A); *c = NCOL(A);
295
296
return C;
297
}
298
299
VARIABLE *mtr_min(VARIABLE *A)
300
{
301
VARIABLE *C;
302
303
double *a = MATR(A), *c;
304
305
int nrowa = NROW(A), ncola = NCOL(A);
306
int i, j;
307
308
if (nrowa == 1 || ncola == 1)
309
{
310
C = var_temp_new(TYPE_DOUBLE, 1, 1); c = MATR(C);
311
*c = *a++; nrowa = max(ncola, nrowa);
312
for(i = 1; i < nrowa; i++, a++) *c = min(*c, *a);
313
}
314
else
315
{
316
C = var_temp_new(TYPE_DOUBLE, 1, ncola); c = MATR(C);
317
for(i = 0; i < ncola; i++, c++)
318
{
319
*c = MA(0, i);
320
for(j = 1; j < nrowa; j++) *c = min(*c, MA(j, i));
321
}
322
}
323
324
return C;
325
}
326
327
VARIABLE *mtr_max(VARIABLE *A)
328
{
329
VARIABLE *C;
330
331
double *a = MATR(A), *c;
332
333
int nrowa = NROW(A), ncola = NCOL(A);
334
int i, j;
335
336
if (nrowa == 1 || ncola == 1)
337
{
338
C = var_temp_new(TYPE_DOUBLE, 1, 1); c = MATR(C);
339
*c = *a++; nrowa = max(ncola, nrowa);
340
for(i = 1; i < nrowa; i++, a++) *c = max(*c, *a);
341
}
342
else
343
{
344
C = var_temp_new(TYPE_DOUBLE, 1, ncola); c = MATR(C);
345
for(i = 0; i < ncola; i++, c++)
346
{
347
*c = MA(0, i);
348
for(j = 1; j < nrowa; j++) *c = max(*c, MA(j, i));
349
}
350
}
351
352
return C;
353
}
354
355
VARIABLE *mtr_diag(VARIABLE *A)
356
{
357
VARIABLE *C;
358
359
double *a = MATR(A), *c;
360
361
int nrowa = NROW(A), ncola = NCOL(A);
362
int ncolc;
363
364
int i;
365
366
if (nrowa == 1 || ncola == 1)
367
{
368
nrowa = max(nrowa, ncola); ncolc = nrowa;
369
C = var_temp_new(TYPE_DOUBLE, nrowa, nrowa); c = MATR(C);
370
for(i = 0; i < nrowa; i++) MC(i, i) = *a++;
371
}
372
else
373
{
374
C = var_temp_new(TYPE_DOUBLE, 1, nrowa); c = MATR(C);
375
for(i = 0; i < min(nrowa,ncola); i++) *c++ = MA(i, i);
376
}
377
378
return C;
379
}
380
381
VARIABLE *mtr_pow(VARIABLE *A)
382
{
383
VARIABLE *B = NEXT(A), *C;
384
double *a = MATR(A), b = M(B,0,0), *c;
385
386
int nrowa = NROW(A), ncola = NCOL(A);
387
388
int i;
389
390
C = var_temp_new(TYPE_DOUBLE, nrowa,ncola );
391
c = MATR( C );
392
for(i = 0; i < nrowa*ncola; i++) *c++ = pow(*a++,b);
393
394
return C;
395
}
396
397
VARIABLE *mtr_where(VARIABLE *A)
398
{
399
VARIABLE *C;
400
401
double *a = MATR(A), *c;
402
403
int nrowa = NROW(A), ncola = NCOL(A);
404
405
int i,n=0;
406
407
for( i=0; i < nrowa*ncola; i++) if ( a[i] ) n++;
408
409
C = var_temp_new( TYPE_DOUBLE,1,n );
410
c = MATR(C);
411
412
for( i=0; i < nrowa*ncola; i++ ) if ( a[i] ) { *c++ = i; }
413
414
return C;
415
}
416
417
void mtr_com_init(void)
418
{
419
static char *minHelp =
420
{
421
"r = min(matrix)\n"
422
"Return value is a vector containing smallest element in columns of given matrix.\n"
423
"r=min(min(matrix) gives smallest element of the matrix.\n\n"
424
};
425
426
static char *maxHelp =
427
{
428
"r = max(matrix)\n"
429
"Return value is a vector containing largest element in columns of given matrix.\n"
430
"r=max(max(matrix)) gives largest element of the matrix.\n\n"
431
};
432
433
static char *sumHelp =
434
{
435
"r = sum(matrix)\n"
436
"Return vector is column sums of given matrix. r=sum(sum(matrix)) gives\n"
437
"the total sum of elements of the matrix.\n\n"
438
};
439
440
static char *traceHelp =
441
{
442
"r = trace(matrix)\n"
443
"Return value is sum of matrix diagonal elements.\n\n"
444
};
445
446
static char *detHelp =
447
{
448
"r = det(matrix)\n"
449
"Return value is determinant of given square matrix.\n\n"
450
};
451
452
static char *invHelp =
453
{
454
"r = inv(matrix)\n"
455
"Invert given square matrix. Computed also by r=matrix^(-1).\n\n"
456
};
457
458
static char *eigHelp =
459
{
460
"r = eig(matrix)\n"
461
"Return eigenvalues of given square matrix. r(n,0) is real part of the\n"
462
"n:th eigenvalue, r(n,1) is the imaginary part respectively\n\n"
463
};
464
465
static char *jacobHelp =
466
{
467
"r = jacob(a,b,eps)\n"
468
"Solve symmetric positive definite eigenvalue problem by Jacob iteration.\n"
469
"Return values are the eigenvalues. Also a variable eigv is created containing\n"
470
"eigenvectors.\n\n"
471
};
472
473
static char *ludHelp =
474
{
475
"r = lud(matrix)\n"
476
"Return value is lud decomposition of given matrix.\n\n"
477
};
478
479
static char *hesseHelp =
480
{
481
"r = hesse(matrix)\n"
482
"Return the upper hessenberg form of given matrix.\n\n"
483
};
484
485
static char *eyeHelp =
486
{
487
"r = eye(n)\n"
488
"Return n by n identity matrix.\n\n"
489
};
490
491
static char *zerosHelp =
492
{
493
"r = zeros(n,m)\n"
494
"Return n by m matrix with elements initialized to zero.\n"
495
};
496
497
static char *onesHelp =
498
{
499
"r = ones(n,m)\n"
500
"Return n by m matrix with elements initialized to one.\n"
501
};
502
503
static char *randHelp =
504
{
505
"r = rand(n,m)\n"
506
"Return n by m matrix with elements initialized to with random number from\n"
507
"zero to one.\n\n"
508
};
509
510
static char *diagHelp =
511
{
512
"r=diag(matrix) or r=diag(vector)\n"
513
"Given matrix return diagonal entries as a vector. Given vector return matrix\n"
514
"with diagonal elements from vector. r=diag(diag(a)) gives matrix with diagonal\n"
515
"elements from matrix a otherwise elements are zero.\n\n"
516
};
517
518
static char *vectorHelp =
519
{
520
"r=vector(start,end,inc)\n"
521
"Return vector of values going from start to end by inc.\n\n"
522
};
523
524
static char *sizeHelp =
525
{
526
"r = size(matrix)\n"
527
"Return size of given matrix.\n"
528
};
529
530
static char *resizeHelp =
531
{
532
"r = resize(matrix,n,m)\n"
533
"Make a matrix to look as a n by m matrix.\n\n"
534
};
535
536
static char *whereHelp =
537
{
538
"r = where(l)\n"
539
"Return linear indexes of where l is true.\n\n"
540
};
541
542
com_init( "sin" , TRUE, TRUE, (VARIABLE *(*)())sin , 1, 1, "r=sin(x)" );
543
com_init( "cos" , TRUE, TRUE, (VARIABLE *(*)())cos , 1, 1, "r=cos(x)" );
544
com_init( "tan" , TRUE, TRUE, (VARIABLE *(*)())tan , 1, 1, "r=tan(x)" );
545
com_init( "asin" , TRUE, TRUE, (VARIABLE *(*)())asin , 1, 1, "r=asin(x)" );
546
com_init( "acos" , TRUE, TRUE, (VARIABLE *(*)())acos , 1, 1, "r=acos(x)" );
547
com_init( "atan" , TRUE, TRUE, (VARIABLE *(*)())atan , 1, 1, "r=atan(x)" );
548
com_init( "atan2" , TRUE, TRUE, (VARIABLE *(*)())atan2 , 2, 2, "r=atan2(y,x)" );
549
com_init( "sinh" , TRUE, TRUE, (VARIABLE *(*)())sinh , 1, 1, "r=sinh(x)" );
550
com_init( "cosh" , TRUE, TRUE, (VARIABLE *(*)())cosh , 1, 1, "r=cosh(x)" );
551
com_init( "tanh" , TRUE, TRUE, (VARIABLE *(*)())tanh , 1, 1, "r=tanh(x)" );
552
com_init( "exp" , TRUE, TRUE, (VARIABLE *(*)())exp , 1, 1, "r=exp(x)" );
553
com_init( "ln" , TRUE, TRUE, (VARIABLE *(*)())log , 1, 1, "r=ln(x)\nNatural logarithm." );
554
com_init( "log" , TRUE, TRUE, (VARIABLE *(*)())log10 , 1, 1, "r=log(x)\nBase 10 logarithm." );
555
com_init( "sqrt" , TRUE, TRUE, (VARIABLE *(*)())sqrt , 1, 1, "r=sqrt(x)" );
556
com_init( "ceil" , TRUE, TRUE, (VARIABLE *(*)())ceil , 1, 1, "r=ceil(x)\nSmallest integer not less than x." );
557
com_init( "floor" , TRUE, TRUE, (VARIABLE *(*)())floor , 1, 1, "r=floor(x)\nLargest integer not more than x." );
558
com_init( "abs" , TRUE, TRUE, (VARIABLE *(*)())func_abs , 1, 1,"r=abs(x)");
559
com_init( "mod" , TRUE, TRUE, (VARIABLE *(*)())func_mod , 2, 2,"r=mod(x,y)");
560
com_init( "pow" , FALSE, TRUE, mtr_pow, 2, 2, "r=pow(x,y)" );
561
com_init( "min" , FALSE, TRUE, mtr_min, 1, 1, minHelp );
562
com_init( "max" , FALSE, TRUE, mtr_max, 1, 1, maxHelp );
563
com_init( "sum" , FALSE, TRUE, mtr_sum, 1, 1, sumHelp );
564
com_init( "trace" , FALSE, TRUE, mtr_trace, 1, 1, traceHelp );
565
com_init( "det" , FALSE, TRUE, mtr_det, 1, 1, detHelp );
566
com_init( "inv" , FALSE, TRUE, mtr_inv, 1, 1, invHelp );
567
com_init( "eig" , FALSE, TRUE, mtr_eig, 1, 1, eigHelp );
568
com_init( "jacob" , FALSE, TRUE, mtr_jacob, 3, 3, jacobHelp );
569
com_init( "lud" , FALSE, TRUE, mtr_LUD, 1, 1, ludHelp );
570
com_init( "hesse" , FALSE, TRUE, mtr_hesse, 1, 1, hesseHelp );
571
com_init( "eye" , FALSE, TRUE, mtr_eye, 1, 1, eyeHelp );
572
com_init( "zeros" , FALSE, TRUE, mtr_zeros, 1, 2, zerosHelp );
573
com_init( "ones" , FALSE, TRUE, mtr_ones, 1, 2, onesHelp );
574
com_init( "rand" , FALSE, FALSE, mtr_rand, 1, 2, randHelp );
575
com_init( "diag" , FALSE, TRUE, mtr_diag, 1, 1, diagHelp );
576
com_init( "vector" , FALSE, TRUE, mtr_vector, 2, 3, vectorHelp );
577
com_init( "size" , FALSE, TRUE, mtr_size, 1, 1, sizeHelp );
578
com_init( "resize" , FALSE, TRUE, mtr_resize, 2, 3, resizeHelp );
579
com_init( "where" , FALSE, FALSE, mtr_where, 1, 1, whereHelp );
580
}
581
582