GRASS 8 Programmer's Manual 8.6.0dev(2026)-4bb960b182
Loading...
Searching...
No Matches
blas_level_2.c
Go to the documentation of this file.
1/*****************************************************************************
2 *
3 * MODULE: Grass numerical math interface
4 * AUTHOR(S): Soeren Gebbert, Berlin (GER) Dec 2006
5 * soerengebbert <at> googlemail <dot> com
6 *
7 * PURPOSE: grass blas implementation
8 * part of the gmath library
9 *
10 * SPDX-FileCopyrightText: 2010 GRASS Development Team
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 *
13 *****************************************************************************/
14
15#include <math.h>
16#include <unistd.h>
17#include <stdio.h>
18#include <string.h>
19#include <stdlib.h>
20#include <grass/gmath.h>
21#include <grass/gis.h>
22
23#define EPSILON 0.00000000000000001
24
25/*!
26 * \brief Compute the matrix - vector product
27 * of matrix A and vector x.
28 *
29 * This function is multi-threaded with OpenMP and can be called within a
30 * parallel OpenMP region.
31 *
32 * y = A * x
33 *
34 *
35 * \param A (double ** )
36 * \param x (double *)
37 * \param y (double *)
38 * \param rows (int)
39 * \param cols (int)
40 * \return (void)
41 *
42 * */
43void G_math_d_Ax(double **A, double *x, double *y, int rows, int cols)
44{
45 int i, j;
46
47 double tmp;
48
49#pragma omp for schedule(static) private(i, j, tmp)
50 for (i = 0; i < rows; i++) {
51 tmp = 0;
52 for (j = cols - 1; j >= 0; j--) {
53 tmp += A[i][j] * x[j];
54 }
55 y[i] = tmp;
56 }
57 return;
58}
59
60/*!
61 * \brief Compute the matrix - vector product
62 * of matrix A and vector x.
63 *
64 * This function is multi-threaded with OpenMP and can be called within a
65 * parallel OpenMP region.
66 *
67 * y = A * x
68 *
69 *
70 * \param A (float ** )
71 * \param x (float *)
72 * \param y (float *)
73 * \param rows (int)
74 * \param cols (int)
75 * \return (void)
76 *
77 * */
78void G_math_f_Ax(float **A, float *x, float *y, int rows, int cols)
79{
80 int i, j;
81
82 float tmp;
83
84#pragma omp for schedule(static) private(i, j, tmp)
85 for (i = 0; i < rows; i++) {
86 tmp = 0;
87 for (j = cols - 1; j >= 0; j--) {
88 tmp += A[i][j] * x[j];
89 }
90 y[i] = tmp;
91 }
92 return;
93}
94
95/*!
96 * \brief Compute the dyadic product of two vectors.
97 * The result is stored in the matrix A.
98 *
99 * This function is multi-threaded with OpenMP and can be called within a
100 * parallel OpenMP region.
101 *
102 * A = x * y^T
103 *
104 *
105 * \param x (double *)
106 * \param y (double *)
107 * \param A (float **) -- matrix of size rows*cols
108 * \param rows (int) -- length of vector x
109 * \param cols (int) -- length of vector y
110 * \return (void)
111 *
112 * */
113void G_math_d_x_dyad_y(double *x, double *y, double **A, int rows, int cols)
114{
115 int i, j;
116
117#pragma omp for schedule(static) private(i, j)
118 for (i = 0; i < rows; i++) {
119 for (j = cols - 1; j >= 0; j--) {
120 A[i][j] = x[i] * y[j];
121 }
122 }
123 return;
124}
125
126/*!
127 * \brief Compute the dyadic product of two vectors.
128 * The result is stored in the matrix A.
129 *
130 * This function is multi-threaded with OpenMP and can be called within a
131 * parallel OpenMP region.
132 *
133 * A = x * y^T
134 *
135 *
136 * \param x (float *)
137 * \param y (float *)
138 * \param A (float **= -- matrix of size rows*cols
139 * \param rows (int) -- length of vector x
140 * \param cols (int) -- length of vector y
141 * \return (void)
142 *
143 * */
144void G_math_f_x_dyad_y(float *x, float *y, float **A, int rows, int cols)
145{
146 int i, j;
147
148#pragma omp for schedule(static) private(i, j)
149 for (i = 0; i < rows; i++) {
150 for (j = cols - 1; j >= 0; j--) {
151 A[i][j] = x[i] * y[j];
152 }
153 }
154 return;
155}
156
157/*!
158 * \brief Compute the scaled matrix - vector product
159 * of matrix double **A and vector x and y.
160 *
161 * z = a * A * x + b * y
162 *
163 * This function is multi-threaded with OpenMP and can be called within a
164 * parallel OpenMP region.
165 *
166 *
167 * \param A (double **)
168 * \param x (double *)
169 * \param y (double *)
170 * \param a (double)
171 * \param b (double)
172 * \param z (double *)
173 * \param rows (int)
174 * \param cols (int)
175 * \return (void)
176 *
177 * */
178
179void G_math_d_aAx_by(double **A, double *x, double *y, double a, double b,
180 double *z, int rows, int cols)
181{
182 int i, j;
183
184 double tmp;
185
186 /*catch specific cases */
187 if (a == b) {
188#pragma omp for schedule(static) private(i, j, tmp)
189 for (i = 0; i < rows; i++) {
190 tmp = 0;
191 for (j = cols - 1; j >= 0; j--) {
192 tmp += A[i][j] * x[j] + y[j];
193 }
194 z[i] = a * tmp;
195 }
196 }
197 else if (b == -1.0) {
198#pragma omp for schedule(static) private(i, j, tmp)
199 for (i = 0; i < rows; i++) {
200 tmp = 0;
201 for (j = cols - 1; j >= 0; j--) {
202 tmp += a * A[i][j] * x[j] - y[j];
203 }
204 z[i] = tmp;
205 }
206 }
207 else if (b == 0.0) {
208#pragma omp for schedule(static) private(i, j, tmp)
209 for (i = 0; i < rows; i++) {
210 tmp = 0;
211 for (j = cols - 1; j >= 0; j--) {
212 tmp += A[i][j] * x[j];
213 }
214 z[i] = a * tmp;
215 }
216 }
217 else if (a == -1.0) {
218#pragma omp for schedule(static) private(i, j, tmp)
219 for (i = 0; i < rows; i++) {
220 tmp = 0;
221 for (j = cols - 1; j >= 0; j--) {
222 tmp += b * y[j] - A[i][j] * x[j];
223 }
224 z[i] = tmp;
225 }
226 }
227 else {
228#pragma omp for schedule(static) private(i, j, tmp)
229 for (i = 0; i < rows; i++) {
230 tmp = 0;
231 for (j = cols - 1; j >= 0; j--) {
232 tmp += a * A[i][j] * x[j] + b * y[j];
233 }
234 z[i] = tmp;
235 }
236 }
237 return;
238}
239
240/*!
241 * \brief Compute the scaled matrix - vector product
242 * of matrix A and vectors x and y.
243 *
244 * z = a * A * x + b * y
245 *
246 * This function is multi-threaded with OpenMP and can be called within a
247 * parallel OpenMP region.
248 *
249 *
250 * \param A (float **)
251 * \param x (float *)
252 * \param y (float *)
253 * \param a (float)
254 * \param b (float)
255 * \param z (float *)
256 * \param rows (int)
257 * \param cols (int)
258 * \return (void)
259 *
260 * */
261
262void G_math_f_aAx_by(float **A, float *x, float *y, float a, float b, float *z,
263 int rows, int cols)
264{
265 int i, j;
266
267 float tmp;
268
269 /*catch specific cases */
270 if (a == b) {
271#pragma omp for schedule(static) private(i, j, tmp)
272 for (i = 0; i < rows; i++) {
273 tmp = 0;
274 for (j = cols - 1; j >= 0; j--) {
275 tmp += A[i][j] * x[j] + y[j];
276 }
277 z[i] = a * tmp;
278 }
279 }
280 else if (b == -1.0) {
281#pragma omp for schedule(static) private(i, j, tmp)
282 for (i = 0; i < rows; i++) {
283 tmp = 0;
284 for (j = cols - 1; j >= 0; j--) {
285 tmp += a * A[i][j] * x[j] - y[j];
286 }
287 z[i] = tmp;
288 }
289 }
290 else if (b == 0.0) {
291#pragma omp for schedule(static) private(i, j, tmp)
292 for (i = 0; i < rows; i++) {
293 tmp = 0;
294 for (j = cols - 1; j >= 0; j--) {
295 tmp += A[i][j] * x[j];
296 }
297 z[i] = a * tmp;
298 }
299 }
300 else if (a == -1.0) {
301#pragma omp for schedule(static) private(i, j, tmp)
302 for (i = 0; i < rows; i++) {
303 tmp = 0;
304 for (j = cols - 1; j >= 0; j--) {
305 tmp += b * y[j] - A[i][j] * x[j];
306 }
307 z[i] = tmp;
308 }
309 }
310 else {
311#pragma omp for schedule(static) private(i, j, tmp)
312 for (i = 0; i < rows; i++) {
313 tmp = 0;
314 for (j = cols - 1; j >= 0; j--) {
315 tmp += a * A[i][j] * x[j] + b * y[j];
316 }
317 z[i] = tmp;
318 }
319 }
320 return;
321}
322
323/*!
324 * \fn int G_math_d_A_T(double **A, int rows)
325 *
326 * \brief Compute the transposition of matrix A.
327 * Matrix A will be overwritten.
328 *
329 * This function is multi-threaded with OpenMP and can be called within a
330 * parallel OpenMP region.
331 *
332 * Returns 0.
333 *
334 * \param A (double **)
335 * \param rows (int)
336 * \return int
337 */
338int G_math_d_A_T(double **A, int rows)
339{
340 int i, j;
341
342 double tmp;
343
344#pragma omp for schedule(static) private(i, j, tmp)
345 for (i = 0; i < rows; i++)
346 for (j = 0; j < i; j++) {
347 tmp = A[i][j];
348
349 A[i][j] = A[j][i];
350 A[j][i] = tmp;
351 }
352
353 return 0;
354}
355
356/*!
357 * \fn int G_math_f_A_T(float **A, int rows)
358 *
359 * \brief Compute the transposition of matrix A.
360 * Matrix A will be overwritten.
361 *
362 * This function is multi-threaded with OpenMP and can be called within a
363 * parallel OpenMP region.
364 *
365 * Returns 0.
366 *
367 * \param A (float **)
368 * \param rows (int)
369 * \return int
370 */
371int G_math_f_A_T(float **A, int rows)
372{
373 int i, j;
374
375 float tmp;
376
377#pragma omp for schedule(static) private(i, j, tmp)
378 for (i = 0; i < rows; i++)
379 for (j = 0; j < i; j++) {
380 tmp = A[i][j];
381
382 A[i][j] = A[j][i];
383 A[j][i] = tmp;
384 }
385
386 return 0;
387}
int G_math_d_A_T(double **A, int rows)
Compute the transposition of matrix A. Matrix A will be overwritten.
void G_math_d_aAx_by(double **A, double *x, double *y, double a, double b, double *z, int rows, int cols)
Compute the scaled matrix - vector product of matrix double **A and vector x and y.
void G_math_d_Ax(double **A, double *x, double *y, int rows, int cols)
Compute the matrix - vector product of matrix A and vector x.
void G_math_f_aAx_by(float **A, float *x, float *y, float a, float b, float *z, int rows, int cols)
Compute the scaled matrix - vector product of matrix A and vectors x and y.
void G_math_f_x_dyad_y(float *x, float *y, float **A, int rows, int cols)
Compute the dyadic product of two vectors. The result is stored in the matrix A.
void G_math_f_Ax(float **A, float *x, float *y, int rows, int cols)
Compute the matrix - vector product of matrix A and vector x.
void G_math_d_x_dyad_y(double *x, double *y, double **A, int rows, int cols)
Compute the dyadic product of two vectors. The result is stored in the matrix A.
int G_math_f_A_T(float **A, int rows)
Compute the transposition of matrix A. Matrix A will be overwritten.
double b
Definition r_raster.c:37
#define x