2024-09-10 15:45:07 +08:00
|
|
|
/********************************************************
|
|
|
|
* ██████╗ ██████╗████████╗██╗
|
|
|
|
* ██╔════╝ ██╔════╝╚══██╔══╝██║
|
|
|
|
* ██║ ███╗██║ ██║ ██║
|
|
|
|
* ██║ ██║██║ ██║ ██║
|
|
|
|
* ╚██████╔╝╚██████╗ ██║ ███████╗
|
|
|
|
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* 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<double> c);
|
2024-09-21 11:08:56 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @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);
|
2024-09-10 15:45:07 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @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<double> 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<double> t, std::complex<double> 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<double> t, std::complex<double> 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<double> 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<double> 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<double> 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<double> 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
|