2
/*****************************************************************************
4
* MODULE: Grass numerical math interface
5
* AUTHOR(S): Soeren Gebbert, Berlin (GER) Dec 2006
6
* soerengebbert <at> googlemail <dot> com
8
* PURPOSE: grass blas implementation
9
* part of the gmath library
11
* COPYRIGHT: (C) 2010 by the GRASS Development Team
13
* This program is free software under the GNU General Public
14
* License (>=v2). Read the file COPYING that comes with GRASS
17
*****************************************************************************/
24
#include <grass/gmath.h>
25
#include <grass/gis.h>
27
#define EPSILON 0.00000000000000001
31
* \brief Compute the matrix - vector product
32
* of matrix A and vector x.
34
* This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
39
* \param A (double ** )
47
void G_math_d_Ax(double **A, double *x, double *y, int rows, int cols)
53
#pragma omp for schedule (static) private(i, j, tmp)
54
for (i = 0; i < rows; i++) {
56
for (j = cols - 1; j >= 0; j--) {
57
tmp += A[i][j] * x[j];
65
* \brief Compute the matrix - vector product
66
* of matrix A and vector x.
68
* This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
73
* \param A (float ** )
81
void G_math_f_Ax(float **A, float *x, float *y, int rows, int cols)
87
#pragma omp for schedule (static) private(i, j, tmp)
88
for (i = 0; i < rows; i++) {
90
for (j = cols - 1; j >= 0; j--) {
91
tmp += A[i][j] * x[j];
99
* \brief Compute the dyadic product of two vectors.
100
* The result is stored in the matrix A.
102
* This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
107
* \param x (double *)
108
* \param y (double *)
109
* \param A (float **) -- matrix of size rows*cols
110
* \param rows (int) -- length of vector x
111
* \param cols (int) -- lengt of vector y
115
void G_math_d_x_dyad_y(double *x, double *y, double **A, int rows, int cols)
119
#pragma omp for schedule (static) private(i, j)
120
for (i = 0; i < rows; i++) {
121
for (j = cols - 1; j >= 0; j--) {
122
A[i][j] = x[i] * y[j];
129
* \brief Compute the dyadic product of two vectors.
130
* The result is stored in the matrix A.
132
* This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
139
* \param A (float **= -- matrix of size rows*cols
140
* \param rows (int) -- length of vector x
141
* \param cols (int) -- lengt of vector y
145
void G_math_f_x_dyad_y(float *x, float *y, float **A, int rows, int cols)
149
#pragma omp for schedule (static) private(i, j)
150
for (i = 0; i < rows; i++) {
151
for (j = cols - 1; j >= 0; j--) {
152
A[i][j] = x[i] * y[j];
159
* \brief Compute the scaled matrix - vector product
160
* of matrix double **A and vector x and y.
162
* z = a * A * x + b * y
164
* This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
167
* \param A (double **)
168
* \param x (double *)
169
* \param y (double *)
172
* \param z (double *)
179
void G_math_d_aAx_by(double **A, double *x, double *y, double a, double b,
180
double *z, int rows, int cols)
186
/*catch specific cases */
188
#pragma omp for schedule (static) private(i, j, tmp)
189
for (i = 0; i < rows; i++) {
191
for (j = cols - 1; j >= 0; j--) {
192
tmp += A[i][j] * x[j] + y[j];
197
else if (b == -1.0) {
198
#pragma omp for schedule (static) private(i, j, tmp)
199
for (i = 0; i < rows; i++) {
201
for (j = cols - 1; j >= 0; j--) {
202
tmp += a * A[i][j] * x[j] - y[j];
208
#pragma omp for schedule (static) private(i, j, tmp)
209
for (i = 0; i < rows; i++) {
211
for (j = cols - 1; j >= 0; j--) {
212
tmp += A[i][j] * x[j];
217
else if (a == -1.0) {
218
#pragma omp for schedule (static) private(i, j, tmp)
219
for (i = 0; i < rows; i++) {
221
for (j = cols - 1; j >= 0; j--) {
222
tmp += b * y[j] - A[i][j] * x[j];
228
#pragma omp for schedule (static) private(i, j, tmp)
229
for (i = 0; i < rows; i++) {
231
for (j = cols - 1; j >= 0; j--) {
232
tmp += a * A[i][j] * x[j] + b * y[j];
241
* \brief Compute the scaled matrix - vector product
242
* of matrix A and vectors x and y.
244
* z = a * A * x + b * y
246
* This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
249
* \param A (float **)
261
void G_math_f_aAx_by(float **A, float *x, float *y, float a, float b,
262
float *z, int rows, int cols)
268
/*catch specific cases */
270
#pragma omp for schedule (static) private(i, j, tmp)
271
for (i = 0; i < rows; i++) {
273
for (j = cols - 1; j >= 0; j--) {
274
tmp += A[i][j] * x[j] + y[j];
279
else if (b == -1.0) {
280
#pragma omp for schedule (static) private(i, j, tmp)
281
for (i = 0; i < rows; i++) {
283
for (j = cols - 1; j >= 0; j--) {
284
tmp += a * A[i][j] * x[j] - y[j];
290
#pragma omp for schedule (static) private(i, j, tmp)
291
for (i = 0; i < rows; i++) {
293
for (j = cols - 1; j >= 0; j--) {
294
tmp += A[i][j] * x[j];
299
else if (a == -1.0) {
300
#pragma omp for schedule (static) private(i, j, tmp)
301
for (i = 0; i < rows; i++) {
303
for (j = cols - 1; j >= 0; j--) {
304
tmp += b * y[j] - A[i][j] * x[j];
310
#pragma omp for schedule (static) private(i, j, tmp)
311
for (i = 0; i < rows; i++) {
313
for (j = cols - 1; j >= 0; j--) {
314
tmp += a * A[i][j] * x[j] + b * y[j];
325
* \fn int G_math_d_A_T(double **A, int rows)
327
* \brief Compute the transposition of matrix A.
328
* Matrix A will be overwritten.
330
* This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
334
* \param A (double **)
339
int G_math_d_A_T(double **A, int rows)
345
#pragma omp for schedule (static) private(i, j, tmp)
346
for (i = 0; i < rows; i++)
347
for (j = 0; j < i; j++) {
358
* \fn int G_math_f_A_T(float **A, int rows)
360
* \brief Compute the transposition of matrix A.
361
* Matrix A will be overwritten.
363
* This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
367
* \param A (float **)
372
int G_math_f_A_T(float **A, int rows)
378
#pragma omp for schedule (static) private(i, j, tmp)
379
for (i = 0; i < rows; i++)
380
for (j = 0; j < i; j++) {