123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- /*****************************************************************************
- *
- * MODULE: Grass numerical math interface
- * AUTHOR(S): Soeren Gebbert, Berlin (GER) Dec 2006
- * soerengebbert <at> googlemail <dot> com
- *
- * PURPOSE: grass blas implementation
- * part of the gmath library
- *
- * COPYRIGHT: (C) 2010 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public
- * License (>=v2). Read the file COPYING that comes with GRASS
- * for details.
- *
- *****************************************************************************/
- #include <math.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <grass/gmath.h>
- #include <grass/gis.h>
- #define EPSILON 0.00000000000000001
- /*!
- * \brief Compute the matrix - vector product
- * of matrix A and vector x.
- *
- * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
- *
- * y = A * x
- *
- *
- * \param A (double ** )
- * \param x (double *)
- * \param y (double *)
- * \param rows (int)
- * \param cols (int)
- * \return (void)
- *
- * */
- void G_math_d_Ax(double **A, double *x, double *y, int rows, int cols)
- {
- int i, j;
- double tmp;
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++) {
- tmp = 0;
- for (j = cols - 1; j >= 0; j--) {
- tmp += A[i][j] * x[j];
- }
- y[i] = tmp;
- }
- return;
- }
- /*!
- * \brief Compute the matrix - vector product
- * of matrix A and vector x.
- *
- * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
- *
- * y = A * x
- *
- *
- * \param A (float ** )
- * \param x (float *)
- * \param y (float *)
- * \param rows (int)
- * \param cols (int)
- * \return (void)
- *
- * */
- void G_math_f_Ax(float **A, float *x, float *y, int rows, int cols)
- {
- int i, j;
- float tmp;
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++) {
- tmp = 0;
- for (j = cols - 1; j >= 0; j--) {
- tmp += A[i][j] * x[j];
- }
- y[i] = tmp;
- }
- return;
- }
- /*!
- * \brief Compute the dyadic product of two vectors.
- * The result is stored in the matrix A.
- *
- * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
- *
- * A = x * y^T
- *
- *
- * \param x (double *)
- * \param y (double *)
- * \param A (float **) -- matrix of size rows*cols
- * \param rows (int) -- length of vector x
- * \param cols (int) -- lengt of vector y
- * \return (void)
- *
- * */
- void G_math_d_x_dyad_y(double *x, double *y, double **A, int rows, int cols)
- {
- int i, j;
- #pragma omp for schedule (static) private(i, j)
- for (i = 0; i < rows; i++) {
- for (j = cols - 1; j >= 0; j--) {
- A[i][j] = x[i] * y[j];
- }
- }
- return;
- }
- /*!
- * \brief Compute the dyadic product of two vectors.
- * The result is stored in the matrix A.
- *
- * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
- *
- * A = x * y^T
- *
- *
- * \param x (float *)
- * \param y (float *)
- * \param A (float **= -- matrix of size rows*cols
- * \param rows (int) -- length of vector x
- * \param cols (int) -- lengt of vector y
- * \return (void)
- *
- * */
- void G_math_f_x_dyad_y(float *x, float *y, float **A, int rows, int cols)
- {
- int i, j;
- #pragma omp for schedule (static) private(i, j)
- for (i = 0; i < rows; i++) {
- for (j = cols - 1; j >= 0; j--) {
- A[i][j] = x[i] * y[j];
- }
- }
- return;
- }
- /*!
- * \brief Compute the scaled matrix - vector product
- * of matrix double **A and vector x and y.
- *
- * z = a * A * x + b * y
- *
- * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
- *
- *
- * \param A (double **)
- * \param x (double *)
- * \param y (double *)
- * \param a (double)
- * \param b (double)
- * \param z (double *)
- * \param rows (int)
- * \param cols (int)
- * \return (void)
- *
- * */
- void G_math_d_aAx_by(double **A, double *x, double *y, double a, double b,
- double *z, int rows, int cols)
- {
- int i, j;
- double tmp;
- /*catch specific cases */
- if (a == b) {
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++) {
- tmp = 0;
- for (j = cols - 1; j >= 0; j--) {
- tmp += A[i][j] * x[j] + y[j];
- }
- z[i] = a * tmp;
- }
- }
- else if (b == -1.0) {
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++) {
- tmp = 0;
- for (j = cols - 1; j >= 0; j--) {
- tmp += a * A[i][j] * x[j] - y[j];
- }
- z[i] = tmp;
- }
- }
- else if (b == 0.0) {
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++) {
- tmp = 0;
- for (j = cols - 1; j >= 0; j--) {
- tmp += A[i][j] * x[j];
- }
- z[i] = a * tmp;
- }
- }
- else if (a == -1.0) {
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++) {
- tmp = 0;
- for (j = cols - 1; j >= 0; j--) {
- tmp += b * y[j] - A[i][j] * x[j];
- }
- z[i] = tmp;
- }
- }
- else {
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++) {
- tmp = 0;
- for (j = cols - 1; j >= 0; j--) {
- tmp += a * A[i][j] * x[j] + b * y[j];
- }
- z[i] = tmp;
- }
- }
- return;
- }
- /*!
- * \brief Compute the scaled matrix - vector product
- * of matrix A and vectors x and y.
- *
- * z = a * A * x + b * y
- *
- * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
- *
- *
- * \param A (float **)
- * \param x (float *)
- * \param y (float *)
- * \param a (float)
- * \param b (float)
- * \param z (float *)
- * \param rows (int)
- * \param cols (int)
- * \return (void)
- *
- * */
- void G_math_f_aAx_by(float **A, float *x, float *y, float a, float b,
- float *z, int rows, int cols)
- {
- int i, j;
- float tmp;
- /*catch specific cases */
- if (a == b) {
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++) {
- tmp = 0;
- for (j = cols - 1; j >= 0; j--) {
- tmp += A[i][j] * x[j] + y[j];
- }
- z[i] = a * tmp;
- }
- }
- else if (b == -1.0) {
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++) {
- tmp = 0;
- for (j = cols - 1; j >= 0; j--) {
- tmp += a * A[i][j] * x[j] - y[j];
- }
- z[i] = tmp;
- }
- }
- else if (b == 0.0) {
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++) {
- tmp = 0;
- for (j = cols - 1; j >= 0; j--) {
- tmp += A[i][j] * x[j];
- }
- z[i] = a * tmp;
- }
- }
- else if (a == -1.0) {
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++) {
- tmp = 0;
- for (j = cols - 1; j >= 0; j--) {
- tmp += b * y[j] - A[i][j] * x[j];
- }
- z[i] = tmp;
- }
- }
- else {
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++) {
- tmp = 0;
- for (j = cols - 1; j >= 0; j--) {
- tmp += a * A[i][j] * x[j] + b * y[j];
- }
- z[i] = tmp;
- }
- }
- return;
- }
- /*!
- * \fn int G_math_d_A_T(double **A, int rows)
- *
- * \brief Compute the transposition of matrix A.
- * Matrix A will be overwritten.
- *
- * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
- *
- * Returns 0.
- *
- * \param A (double **)
- * \param rows (int)
- * \return int
- */
- int G_math_d_A_T(double **A, int rows)
- {
- int i, j;
- double tmp;
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++)
- for (j = 0; j < i; j++) {
- tmp = A[i][j];
- A[i][j] = A[j][i];
- A[j][i] = tmp;
- }
- return 0;
- }
- /*!
- * \fn int G_math_f_A_T(float **A, int rows)
- *
- * \brief Compute the transposition of matrix A.
- * Matrix A will be overwritten.
- *
- * This function is multi-threaded with OpenMP and can be called within a parallel OpenMP region.
- *
- * Returns 0.
- *
- * \param A (float **)
- * \param rows (int)
- * \return int
- */
- int G_math_f_A_T(float **A, int rows)
- {
- int i, j;
- float tmp;
- #pragma omp for schedule (static) private(i, j, tmp)
- for (i = 0; i < rows; i++)
- for (j = 0; j < i; j++) {
- tmp = A[i][j];
- A[i][j] = A[j][i];
- A[j][i] = tmp;
- }
- return 0;
- }
|