/******************************************************** * ██████╗ ██████╗████████╗██╗ * ██╔════╝ ██╔════╝╚══██╔══╝██║ * ██║ ███╗██║ ██║ ██║ * ██║ ██║██║ ██║ ██║ * ╚██████╔╝╚██████╗ ██║ ███████╗ * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ * Geophysical Computational Tools & Library (GCTL) * * Copyright (c) 2023 Yi Zhang (yizhang-geo@zju.edu.cn) * * GCTL is distributed under a dual licensing scheme. You can redistribute * it and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either version 2 * of the License, or (at your option) any later version. You should have * received a copy of the GNU Lesser General Public License along with this * program. If not, see . * * If the terms and conditions of the LGPL v.2. would prevent you from using * the GCTL, please consider the option to obtain a commercial license for a * fee. These licenses are offered by the GCTL's original author. As a rule, * licenses are provided "as-is", unlimited in time for a one time fee. Please * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget * to include some description of your company and the realm of its activities. * Also add information on how to contact you by electronic and paper mail. ******************************************************/ #ifndef _GCTL_LINEAR_ALGEBRA_H #define _GCTL_LINEAR_ALGEBRA_H #include "../core.h" #ifdef GCTL_OPENMP #include "omp.h" #endif // GCTL_OPENMP #ifdef GCTL_OPENBLAS #include "cblas.h" #endif // GCTL_OPENBLAS namespace gctl { /** * @brief Set values of an array's members to a given value. x .= c. * * @param x The input/output array. * @param c The input value. */ void vecset(_1d_array &x, double c); /** * @brief Set values of an array's members to a given value. x .= c. * * @param x The input/output array. * @param c The input value. */ void vecset(_1cd_array &x, std::complex c); /** * @brief Copy values of an array to another with conjugate values * * @param x The input/output array. * @param c The input value. */ void vecconj(_1cd_array &x, const _1cd_array &y); /** * @brief Copy values of an array to another. x = c.*y. * * @param x The input/output array. * @param y The source array. * @param c Multiplier of the source array. The default value is 1.0. */ void veccpy(_1d_array &x, const _1d_array &y, double c = 1.0); /** * @brief Copy values of an array to another. x = c.*y. * * @param x The input/output array. * @param y The source array. * @param c Multiplier of the source array. */ void veccpy(_1cd_array &x, const _1cd_array &y, std::complex c); /** * @brief Calculate the sum of two input arrays. a = t.*b + p.*c. * * @param a The output array. * @param b The input array. * @param c The input array. * @param t Multiplier of b. The default value is 1.0. * @param p MUltiplier of c. The default value is 1.0. */ void vecadd(_1d_array &a, const _1d_array &b, const _1d_array &c, double t = 1.0, double p = 1.0); /** * @brief Calculate the sum of two input arrays. a = t.*b + p.*c. * * @param a The output array. * @param b The input array. * @param c The input array. * @param t Multiplier of b. * @param p MUltiplier of c. */ void vecadd(_1cd_array &a, const _1cd_array &b, const _1cd_array &c, std::complex t, std::complex p); /** * @brief Calculate the difference of two input arrays. a = t.*b - p.*c. * * @param a The output array. * @param b The input array. * @param c The input array. * @param t Multiplier of b. The default value is 1.0. * @param p MUltiplier of c. The default value is 1.0. */ void vecdiff(_1d_array &a, const _1d_array &b, const _1d_array &c, double t = 1.0, double p = 1.0); /** * @brief Calculate the difference of two input arrays. a = t.*b - p.*c. * * @param a The output array. * @param b The input array. * @param c The input array. * @param t Multiplier of b. The default value is 1.0. * @param p MUltiplier of c. The default value is 1.0. */ void vecdiff(_1cd_array &a, const _1cd_array &b, const _1cd_array &c, std::complex t, std::complex p); /** * @brief Calculate the element-wise products of the two input array. a = t.*b.*c. * * @param a The output array. * @param b The input array. * @param c The input array. * @param t Multiplier of the output array. The default value is 1.0. */ void vecmul(_1d_array &a, const _1d_array &b, const _1d_array &c, double t = 1.0); /** * @brief Calculate the element-wise divisions of the two input array. a = t.*b./c. * * @param a The output array. * @param b The input array. * @param c The input array. * @param t Multiplier of the output array. The default value is 1.0. */ void vecdiv(_1d_array &a, const _1d_array &b, const _1d_array &c, double t = 1.0); /** * @brief Scale the input/output array. x = c.*x. * * @param x The input/output array. * @param c The input value. */ void vecscale(_1d_array &x, double c); /** * @brief Append the source array to the output array. x += c.*b. * * @param x The input/output array. * @param b The input/source array. * @param c Multiplier of the output array. The default value is 1.0. */ void vecapp(_1d_array &x, const _1d_array &b, double c = 1.0); /** * @brief Append the source array to the output array. x += c.*b. * * @param x The input/output array. * @param b The input/source array. * @param c Multiplier of the output array. */ void vecapp(_1cd_array &x, const _1cd_array &b, std::complex c); /** * @brief Subtract the source array from the output array. x -= c.*b. * * @param x The input/output array. * @param b The input/source array. * @param c Multiplier of the output array. The default value is 1.0. */ void vecsub(_1d_array &x, const _1d_array &b, double c = 1.0); /** * @brief Subtract the source array from the output array. x -= c.*b. * * @param x The input/output array. * @param b The input/source array. * @param c Multiplier of the output array. */ void vecsub(_1cd_array &x, const _1cd_array &b, std::complex c); /** * @brief Set lower bound of the input/output array. x = min(x, l). * * @param x The input/output array. * @param l The lower bound array. */ void vecbtm(_1d_array &x, const _1d_array &l); /** * @brief Set upper bound of the input/output array. x = max(x, h). * * @param x The input/output array. * @param h The upper bound array. */ void vectop(_1d_array &x, const _1d_array &h); /** * @brief Calculate the product of a matrix and a vector. r = m * v or r = m^T * v. * * @param r The output array. * @param m The input matrix. * @param v The input vector. * @param trans Transports the input matrix or not. */ void matvec(_1d_array &r, const _2d_matrix &m, const _1d_array &v, matrix_layout_e trans = NoTrans); /** * @brief Calculate the product of two matrixes. r = m * v, r = m^T * v, r = m * v^T or r = m^T * v^T. * * @param r The output matrix. * @param m The input matrix. * @param v The input matrix. * @param m_trans Transports the m matrix or not. * @param v_trans Transports the v matrix or not. */ void matmat(_2d_matrix &r, const _2d_matrix &m, const _2d_matrix &v, matrix_layout_e m_trans = NoTrans, matrix_layout_e v_trans = NoTrans); /** * @brief Append vectors to an exciting matrix. r += v in a row-wise or column-wise fashion. * * @param r Input/Output matrix * @param v Input array * @param odr Calculating direction */ void matapp(_2d_matrix &r, const _1d_array &v, matrix_order_e odr = RowMajor); /** * @brief Calculate the difference of two matrixes. r = m - v * * @param r The output matrix. * @param m The input matrix. * @param v The input matrix. */ void matdiff(_2d_matrix &r, const _2d_matrix &m, const _2d_matrix &v); /** * @brief Calculate the product of a matrix and a vector. r = m * v or r = m^T * v. * * @param r The output array. * @param m The input matrix. * @param v The input vector. * @param trans Transports the input matrix or not. * @param conj Conjugates the input matrix or not. */ void matvec(_1cd_array &r, const _2cd_matrix &m, const _1cd_array &v, matrix_layout_e trans = NoTrans, conjugate_type_e conj = NoConj); /** * @brief Generate a set of orthogonal arrays. * * @param a The input random array. * @param e The output orthogonal arrays. * @param a_s Size of the orthogonal set. */ void schmidt_orthogonal(const _1d_array &a, _1d_array &e, size_t a_s); /** * @brief Check validity of the input box arrays. h > l. * * @param h The input upper bound array. * @param l The input lower bound array. * @return true The input box arrays are valid. * @return false The input box arrays are not valid. */ bool veccheckbox(const _1d_array &h, const _1d_array &l); /** * @brief Check if elements of the input array are all positive. * * @param a The input array. * @return true All elements are positive. * @return false Not all elements are positive. */ bool veccheckpos(const _1d_array &a); /** * @brief Check if elements of the input array are valid. * * @param a The input array. * @return true All elements are valid. * @return false Not all elements are valid. */ bool vecvalid(const _1d_array &a); /** * @brief Check if elements of the input array are valid. * * @param a The input array. * @return true All elements are valid. * @return false Not all elements are valid. */ bool vecvalid(const _1cd_array &a); /** * @brief Calculate the dot product of two input arrays. * * @param b The input array. * @param c The input array. * @return The dot product. */ double vecdot(const _1d_array &b, const _1d_array &c); /** * @brief Calculate the dot product of two input arrays. * * @param a The input array. * @param b The input array. * @return The dot product. */ std::complex vecdot(const _1cd_array &a, const _1cd_array &b); /** * @brief Calculate the inner product of two input arrays. * * @param a The input array. * @param b The input array. * @return The dot product. */ std::complex vecinner(const _1cd_array &a, const _1cd_array &b); /** * @brief Calculate the running average value. * * @param old_mean Old average value. * @param old_count Old calculating counts. * @param new_input New input value. * @return New average value. */ double dynamic_average(double old_mean, size_t old_count, double new_input); /** * @brief Calculate the running standard deviation value. * * @param old_stddev Old standard deviation value. * @param old_count Old calculating counts. * @param old_mean Old averaging value. * @param new_input New input value. * @param new_mean New output averaging value. * @return New standard deviation value. */ double dynamic_stddev(double old_stddev, size_t old_count, double old_mean, double new_input, double &new_mean); } #endif // _GCTL_LINEAR_ALGEBRA_H