gctl/lib/core/matrix.h

1187 lines
28 KiB
C
Raw Normal View History

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_MATRIX_H
#define _GCTL_MATRIX_H
2025-02-09 19:08:36 +08:00
#include <typeinfo>
2025-02-03 22:30:56 +08:00
#include "array.h"
2024-09-10 15:45:07 +08:00
namespace gctl
{
template <typename MatValType> class matrix;
/*
2025-02-21 09:51:44 +08:00
* Here we define some commonly used matrix types.
2024-09-10 15:45:07 +08:00
*/
2025-02-21 09:51:44 +08:00
typedef matrix<int> _2i_matrix; ///< 2-D integer matrix
typedef matrix<float> _2f_matrix; ///< 2-D single-precision floating-point matrix
typedef matrix<double> _2d_matrix; ///< 2-D double-precision floating-point matrix
typedef matrix<std::string> _2s_matrix; ///< 2-D string matrix
typedef matrix<std::complex<float> > _2cf_matrix; ///< 1-D complex float matrix
typedef matrix<std::complex<double> > _2cd_matrix; ///< 1-D complex double matrix
2024-09-10 15:45:07 +08:00
/**
* @brief
*
* IO操作函数
*
* @tparam MatValType
*/
template <typename MatValType>
class matrix
{
protected:
MatValType **val; ///< 二维数组数据
size_t row_length, col_length; ///< 二维数组的行列数
public:
/**
* @brief
*/
matrix();
/**
* @brief
*
* @param[in] row_len
* @param[in] col_len
*/
matrix(size_t row_len, size_t col_len);
/**
* @brief
*
* @param[in] row_len
* @param[in] col_len
* @param[in] init_val
*/
matrix(size_t row_len, size_t col_len, MatValType init_val);
/**
* @brief
*
* @param init_mat
* @param[in] row_len
* @param[in] col_len
*/
matrix(MatValType *init_mat, size_t row_len, size_t col_len);
/**
* @brief
*
* @param init_mat
* @param[in] row_len
* @param[in] col_len
*/
matrix(MatValType **init_mat, size_t row_len, size_t col_len);
/**
* @brief
*
* @param[in] b
* @param[in] row_len
* @param[in] col_len
*/
matrix(const std::vector<MatValType> &b, size_t row_len, size_t col_len);
/**
* @brief
*
* @param[in] b
*/
2025-02-06 21:17:24 +08:00
explicit matrix(const std::vector<std::vector<MatValType> > &b);
2024-09-10 15:45:07 +08:00
/**
* @brief
*
* @param[in] b
* @param[in] row_len
* @param[in] col_len
*/
matrix(const array<MatValType> &b, size_t row_len, size_t col_len);
/**
* @brief
*
* @param[in] b
*/
matrix(const matrix<MatValType> &b);
/**
* @brief
*
* @param[in] b
*
* @return
*/
matrix<MatValType>& operator= (const matrix<MatValType> &b);
/**
* @brief
*/
virtual ~matrix();
/**
* @brief
*
* @param[in] row_len
* @param[in] col_len
*/
void resize(size_t row_len, size_t col_len);
/**
* @brief
*
* @param[in] row_len
* @param[in] col_len
* @param[in] init_val
*/
void resize(size_t row_len, size_t col_len, MatValType init_val);
/**
* @brief
*
* @param init_mat
* @param[in] row_len
* @param[in] col_len
*/
void resize(MatValType *init_mat, size_t row_len, size_t col_len);
/**
* @brief
*
* @param init_mat
* @param[in] row_len
* @param[in] col_len
*/
void resize(MatValType **init_mat, size_t row_len, size_t col_len);
/**
* @brief
*
* @param[in] b
* @param[in] row_len
* @param[in] col_len
*/
void resize(const std::vector<MatValType> &b, size_t row_len, size_t col_len);
/**
* @brief
*
* @param[in] b
*/
void resize(const std::vector<std::vector<MatValType> > &b);
/**
* @brief
*
* @param[in] b
* @param[in] row_len
* @param[in] col_len
*/
void resize(const array<MatValType> &b, size_t row_len, size_t col_len);
/**
* @brief
*
* @param[in] b
*/
void resize(const matrix<MatValType> &b);
/**
* @brief
*/
void clear();
/**
* @brief Initialize the array with selected random types.
*
* @param[in] np1 Mean (Gauss) or low bound value (Even)
* @param[in] np2 Standard deviation (Gauss) or hig bound value (Even).
* @param[in] mode Random types. 'RdNormal' for Gaussian distributed numbers and
* 'RdUniform' for even distributed numbers.
*/
2024-09-16 14:28:08 +08:00
void random_float(MatValType np1, MatValType np2, random_type_e mode = RdNormal, unsigned int seed = 0);
/**
* @brief Initialize the array with selected random types.
*
* @param[in] np1 Mean (Gauss) or low bound value (Even)
* @param[in] np2 Standard deviation (Gauss) or hig bound value (Even).
* @param[in] mode Random types. 'RdNormal' for Gaussian distributed numbers and
* 'RdUniform' for even distributed numbers.
*/
void random_int(MatValType np1, MatValType np2, unsigned int seed = 0);
2024-09-10 15:45:07 +08:00
/**
* @brief
*
* @param[in] in_val
*/
void assign_all(MatValType in_val);
2025-02-22 11:40:45 +08:00
/**
* @brief
*
* @param r_id
* @param in_val
*/
void fill_row(size_t r_id, const array<MatValType> &in_arr);
/**
* @brief
*
* @param c_id
* @param in_val
*/
void fill_column(size_t c_id, const array<MatValType> &in_arr);
2024-09-10 15:45:07 +08:00
/**
* @brief
*
* @param s
*/
void scale(MatValType s);
/**
* @brief
*
* @param m
* @param odr
*/
void mean(array<MatValType> &m, matrix_order_e odr = RowMajor);
2025-02-21 09:51:44 +08:00
/**
* @brief
*
* @param odr
*/
void normalize(matrix_order_e odr = RowMajor);
2024-09-10 15:45:07 +08:00
/**
* @brief
*
* @param n_type
*/
2025-02-21 09:51:44 +08:00
double module(norm_type_e n_type = L2) const;
2024-09-10 15:45:07 +08:00
/**
* @brief Set elements' value as a sequent.
*
* @param st_val Start value.
* @param row_inc Row increasement.
* @param col_inc Column increasement.
*/
2024-09-16 14:28:08 +08:00
void sequence(MatValType st_val, MatValType row_inc, MatValType col_inc);
2024-09-10 15:45:07 +08:00
/**
* @brief
*
* @note
*
* @param[in] row_index
* @param[in] col_index
*
* @return
*/
MatValType &at(size_t row_index, size_t col_index);
/**
* @brief
*
* @note
*
* @param[in] row_index
* @param[in] col_index
*
* @return
*/
MatValType &at(size_t row_index, size_t col_index) const;
/**
* @brief
*
* @note
*
* @param[in] index
*
* @return
*/
MatValType *operator[](size_t index);
/**
* @brief
*
* @note
*
* @param[in] index
*
* @return
*/
MatValType *operator[](size_t index) const;
/**
* @brief
*
* @param[in] row_index row_index = 0
*
* @return
*/
MatValType *get(size_t row_index = 0) const;
/**
* @brief
*
* @return
*/
bool empty() const;
/**
* @brief
*
* @return
*/
size_t row_size() const;
/**
* @brief
*
* @return
*/
size_t col_size() const;
/**
* @brief
*
* @return
*/
size_t val_size() const;
/**
* @brief
*
* @param b
*/
void copy_to(matrix<MatValType> &b) const;
/**
* @brief
*
* @param b
*/
void copy_to(std::vector<std::vector<MatValType> > &b) const;
/**
* @brief
*
* @param b
* @param[in] index
* @param[in] order
*/
void extract(array<MatValType> &b, size_t index, matrix_order_e order = RowMajor) const;
/**
* @brief
*
* @warning
*
* @param b
* @param[in] order
*/
void reform(array<MatValType> &b, matrix_order_e order = RowMajor) const;
/**
* @brief element operate function pointer
*
*/
2024-09-16 14:28:08 +08:00
typedef void (*foreach_m_ptr)(MatValType &ele_ptr, size_t r_id, size_t c_id);
2024-09-10 15:45:07 +08:00
/**
* @brief Operate on each and every element
*
* @param func operation function
*/
void for_each(foreach_m_ptr func);
/**
* @brief Display the elements.
*
*/
void show(std::ostream &os = std::cout, char sep = '\t') const;
};
template <typename MatValType>
matrix<MatValType>::matrix()
{
row_length = col_length = 0;
val = nullptr;
}
template <typename MatValType>
matrix<MatValType>::matrix(size_t row_len, size_t col_len)
{
row_length = col_length = 0;
val = nullptr;
resize(row_len, col_len);
}
template <typename MatValType>
matrix<MatValType>::matrix(size_t row_len, size_t col_len, MatValType init_val)
{
row_length = col_length = 0;
val = nullptr;
resize(row_len, col_len, init_val);
}
template <typename MatValType>
matrix<MatValType>::matrix(MatValType *init_mat, size_t row_len, size_t col_len)
{
row_length = col_length = 0;
val = nullptr;
resize(init_mat, row_len, col_len);
}
template <typename MatValType>
matrix<MatValType>::matrix(MatValType **init_mat, size_t row_len, size_t col_len)
{
row_length = col_length = 0;
val = nullptr;
resize(init_mat, row_len, col_len);
}
template <typename MatValType>
matrix<MatValType>::matrix(const std::vector<MatValType> &b, size_t row_len, size_t col_len)
{
row_length = col_length = 0;
val = nullptr;
resize(b, row_len, col_len);
}
template <typename MatValType>
matrix<MatValType>::matrix(const std::vector<std::vector<MatValType> > &b)
{
row_length = col_length = 0;
val = nullptr;
resize(b);
}
template <typename MatValType>
matrix<MatValType>::matrix(const array<MatValType> &b, size_t row_len, size_t col_len)
{
row_length = col_length = 0;
val = nullptr;
resize(b, row_len, col_len);
}
template <typename MatValType>
matrix<MatValType>::matrix(const matrix<MatValType> &b)
{
row_length = col_length = 0;
val = nullptr;
resize(b);
}
template <typename MatValType>
matrix<MatValType>& matrix<MatValType>::operator= (const matrix<MatValType> &b)
{
if (b.empty())
{
clear();
}
else
{
resize(b.row_size(), b.col_size());
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
val[i][j] = b[i][j];
}
}
}
return *this;
}
template <typename MatValType>
matrix<MatValType>::~matrix()
{
clear();
}
template <typename MatValType>
void matrix<MatValType>::resize(size_t row_len, size_t col_len)
{
if (row_len == 0 || col_len == 0)
{
2024-09-16 14:28:08 +08:00
throw std::invalid_argument("[gctl::matrix<T>::resize] Invalid matrix size.");
2024-09-10 15:45:07 +08:00
}
// nothing needs to be done
if (row_len == row_length && col_len == col_length)
{
return;
}
// re-indexing
if (row_len*col_len == row_length*col_length)
{
row_length = row_len;
col_length = col_len;
// construct new row-indexing
MatValType *t_ptr = val[0];
delete[] val;
val = new MatValType* [row_len];
val[0] = t_ptr;
for (size_t i = 1; i < row_len; i++)
{
val[i] = val[i-1] + col_len;
}
return;
}
// re-allocate
if (!empty()) clear();
row_length = row_len;
col_length = col_len;
val = new MatValType* [row_len];
val[0] = new MatValType [row_len*col_len];
for (size_t i = 1; i < row_len; i++)
{
val[i] = val[i-1] + col_len;
}
return;
}
template <typename MatValType>
void matrix<MatValType>::resize(size_t row_len, size_t col_len, MatValType init_val)
{
resize(row_len, col_len);
for (size_t i = 0; i < row_len; i++)
{
for (size_t j = 0; j < col_len; j++)
{
val[i][j] = init_val;
}
}
return;
}
template <typename MatValType>
void matrix<MatValType>::resize(MatValType *init_mat, size_t row_len, size_t col_len)
{
if (init_mat == nullptr)
{
2024-09-16 14:28:08 +08:00
throw std::domain_error("[gctl::matrix<T>::resize] Invalid pointer.");
2024-09-10 15:45:07 +08:00
}
resize(row_len, col_len);
for (size_t i = 0; i < row_len; i++)
{
for (size_t j = 0; j < col_len; j++)
{
val[i][j] = init_mat[j + i*col_len];
}
}
return;
}
template <typename MatValType>
void matrix<MatValType>::resize(MatValType **init_mat, size_t row_len, size_t col_len)
{
if (init_mat == nullptr)
{
2024-09-16 14:28:08 +08:00
throw std::domain_error("[gctl::matrix<T>::resize] Invalid pointer.");
2024-09-10 15:45:07 +08:00
}
resize(row_len, col_len);
for (size_t i = 0; i < row_len; i++)
{
for (size_t j = 0; j < col_len; j++)
{
val[i][j] = init_mat[i][j];
}
}
return;
}
template <typename MatValType>
void matrix<MatValType>::resize(const std::vector<MatValType> &b, size_t row_len, size_t col_len)
{
if (!b.empty())
{
resize(row_len, col_len);
for (size_t i = 0; i < row_len; i++)
{
for (size_t j = 0; j < col_len; j++)
{
val[i][j] = b[j + i*col_len];
}
}
return;
}
return;
}
template <typename MatValType>
void matrix<MatValType>::resize(const std::vector<std::vector<MatValType> > &b)
{
if (!b.empty())
{
2024-09-16 14:28:08 +08:00
size_t max_col = 0;
for (size_t i = 0; i < b.size(); i++)
2024-09-10 15:45:07 +08:00
{
2024-09-16 14:28:08 +08:00
max_col = std::max(max_col, b[i].size());
2024-09-10 15:45:07 +08:00
}
2024-09-16 14:28:08 +08:00
resize(b.size(), max_col, 0);
2024-09-10 15:45:07 +08:00
for (size_t i = 0; i < row_length; i++)
{
2024-09-16 14:28:08 +08:00
for (size_t j = 0; j < b[i].size(); j++)
2024-09-10 15:45:07 +08:00
{
val[i][j] = b[i][j];
}
}
return;
}
return;
}
template <typename MatValType>
void matrix<MatValType>::resize(const array<MatValType> &b, size_t row_len, size_t col_len)
{
if (!b.empty())
{
if (b.size() != row_len*col_len)
{
2024-09-16 14:28:08 +08:00
throw std::runtime_error("[gctl::matrix<T>::resize] Invalid matrix parameters.");
2024-09-10 15:45:07 +08:00
}
resize(row_len, col_len);
for (size_t i = 0; i < row_len; i++)
{
for (size_t j = 0; j < col_len; j++)
{
val[i][j] = b[j + i*col_len];
}
}
return;
}
return;
}
template <typename MatValType>
void matrix<MatValType>::resize(const matrix<MatValType> &b)
{
if (!b.empty())
{
resize(b.row_size(), b.col_size());
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
val[i][j] = b[i][j];
}
}
return;
}
return;
}
template <typename MatValType>
void matrix<MatValType>::clear()
{
row_length = col_length = 0;
if (val != nullptr)
{
delete[] val[0];
delete[] val;
val = nullptr;
}
return;
}
template <typename MatValType>
2024-09-16 14:28:08 +08:00
void matrix<MatValType>::random_float(MatValType np1, MatValType np2, random_type_e mode, unsigned int seed)
2024-09-10 15:45:07 +08:00
{
2024-09-16 14:28:08 +08:00
static_assert(std::is_floating_point<MatValType>::value,
"gctl::matrix<T>::random_float(...) could only be used with a float point type.");
2024-09-10 15:45:07 +08:00
if (seed == 0) seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
if (mode == RdNormal)
{
std::normal_distribution<MatValType> dist(np1, np2); // 添加高斯分布的随机值
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
val[i][j] = dist(generator);
}
}
return;
}
std::uniform_real_distribution<MatValType> dist(np1, np2); // /添加均匀分布的随机值
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
val[i][j] = dist(generator);
}
}
return;
}
2024-09-16 14:28:08 +08:00
template <typename MatValType>
void matrix<MatValType>::random_int(MatValType np1, MatValType np2, unsigned int seed)
{
static_assert(std::is_integral<MatValType>::value,
"gctl::matrix<T>::random_int(...) could only be used with an integral type.");
if (seed == 0) seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
//添加均匀分布的随机值
std::uniform_int_distribution<MatValType> dist(np1, np2);
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
val[i][j] = dist(generator);
}
}
return;
}
2024-09-10 15:45:07 +08:00
template <typename MatValType>
void matrix<MatValType>::assign_all(MatValType in_val)
{
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
val[i][j] = in_val;
}
}
return;
}
2025-02-22 11:40:45 +08:00
template <typename MatValType>
void matrix<MatValType>::fill_row(size_t r_id, const array<MatValType> &in_arr)
{
if (r_id >= row_length) throw std::out_of_range("[gctl::matrix<T>::fill_row] Row index out of range.");
if (in_arr.size() != col_length) throw std::invalid_argument("[gctl::matrix<T>::fill_row] Invalid array length.");
for (size_t j = 0; j < col_length; j++)
{
val[r_id][j] = in_arr[j];
}
return;
}
template <typename MatValType>
void matrix<MatValType>::fill_column(size_t c_id, const array<MatValType> &in_arr)
{
if (c_id >= col_length) throw std::out_of_range("[gctl::matrix<T>::fill_column] Column index out of range.");
if (in_arr.size()!= row_length) throw std::invalid_argument("[gctl::matrix<T>::fill_column] Invalid array length.");
for (size_t i = 0; i < row_length; i++)
{
val[i][c_id] = in_arr[i];
}
return;
}
2024-09-10 15:45:07 +08:00
template <typename MatValType>
void matrix<MatValType>::scale(MatValType s)
{
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
val[i][j] *= s;
}
}
return;
}
template <typename MatValType>
void matrix<MatValType>::mean(array<MatValType> &m, matrix_order_e odr)
{
if (odr == RowMajor)
{
m.resize(col_length);
for (size_t j = 0; j < col_length; j++)
{
m[j] = 0.0;
for (size_t i = 0; i < row_length; i++)
{
m[j] += val[i][j];
}
m[j] /= row_length;
}
}
else
{
m.resize(row_length);
for (size_t i = 0; i < row_length; i++)
{
m[i] = 0.0;
for (size_t j = 0; j < col_length; j++)
{
m[i] += val[i][j];
}
m[i] /= col_length;
}
}
return;
}
template <typename MatValType>
2025-02-21 09:51:44 +08:00
void matrix<MatValType>::normalize(matrix_order_e odr)
{
if (odr == RowMajor)
{
for (size_t i = 0; i < row_length; i++)
{
MatValType sum = 0.0;
for (size_t j = 0; j < col_length; j++)
{
sum += val[i][j]*val[i][j];
}
sum = sqrt(sum);
for (size_t j = 0; j < col_length; j++)
{
val[i][j] /= sum;
}
}
}
else // ColMajor
{
for (size_t j = 0; j < col_length; j++)
{
MatValType sum = 0.0;
for (size_t i = 0; i < row_length; i++)
{
sum += val[i][j]*val[i][j];
}
sum = sqrt(sum);
for (size_t i = 0; i < row_length; i++)
{
val[i][j] /= sum;
}
}
}
return;
}
template <typename MatValType>
double matrix<MatValType>::module(norm_type_e n_type) const
2024-09-10 15:45:07 +08:00
{
MatValType nval = (MatValType) 0;
if (n_type == L0)
{
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
if (val[i][j] != (MatValType) 0)
{
nval += (MatValType) 1;
}
}
}
return nval;
}
if (n_type == L1)
{
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
nval += GCTL_FABS(val[i][j]);
}
}
return nval;
}
if (n_type == L2)
{
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
nval += val[i][j]*val[i][j];
}
}
return sqrt(nval);
}
nval = val[0][0];
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
nval = GCTL_MAX(nval, val[i][j]);
}
}
return sqrt(nval);
}
template <typename MatValType>
2024-09-16 14:28:08 +08:00
void matrix<MatValType>::sequence(MatValType st_val, MatValType row_inc, MatValType col_inc)
2024-09-10 15:45:07 +08:00
{
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
val[i][j] = st_val + i*row_inc + j*col_inc;
}
}
return;
}
template <typename MatValType>
MatValType *matrix<MatValType>::get(size_t row_index) const
{
#ifdef GCTL_BOUND_CHECK
if (row_index >= row_length || col_index >= col_length)
2024-09-16 14:28:08 +08:00
throw std::out_of_range("[gctl::matrix<T>::get] Invalid index.");
2024-09-10 15:45:07 +08:00
#endif // GCTL_BOUND_CHECK
return val[row_index];
}
template <typename MatValType>
MatValType &matrix<MatValType>::at(size_t row_index, size_t col_index)
{
#ifdef GCTL_BOUND_CHECK
if (row_index >= row_length || col_index >= col_length)
2024-09-16 14:28:08 +08:00
throw std::out_of_range("[gctl::matrix<T>::at] Invalid index.");
2024-09-10 15:45:07 +08:00
#endif // GCTL_BOUND_CHECK
return val[row_index][col_index];
}
template <typename MatValType>
MatValType &matrix<MatValType>::at(size_t row_index, size_t col_index) const
{
#ifdef GCTL_BOUND_CHECK
if (row_index >= row_length || col_index >= col_length)
2024-09-16 14:28:08 +08:00
throw std::out_of_range("[gctl::matrix<T>::at] Invalid index.");
2024-09-10 15:45:07 +08:00
#endif // GCTL_BOUND_CHECK
return val[row_index][col_index];
}
template <typename MatValType>
MatValType *matrix<MatValType>::operator[](size_t index)
{
return val[index];
}
template <typename MatValType>
MatValType *matrix<MatValType>::operator[](size_t index) const
{
return val[index];
}
template <typename MatValType>
bool matrix<MatValType>::empty() const
{
if (row_length == 0 && col_length == 0) return true;
else return false;
}
template <typename MatValType>
size_t matrix<MatValType>::row_size() const
{
return row_length;
}
template <typename MatValType>
size_t matrix<MatValType>::col_size() const
{
return col_length;
}
template <typename MatValType>
size_t matrix<MatValType>::val_size() const
{
return row_length*col_length;
}
template <typename MatValType>
void matrix<MatValType>::copy_to(matrix<MatValType> &b) const
{
b.resize(row_length, col_length);
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
b[i][j] = val[i][j];
}
}
return;
}
template <typename MatValType>
void matrix<MatValType>::copy_to(std::vector<std::vector<MatValType> > &b) const
{
if (!b.empty())
{
for (size_t i = 0; i < b.size(); i++)
{
b[i].clear();
}
b.clear();
}
b.resize(row_length);
for (size_t i = 0; i < row_length; i++)
{
b[i].resize(col_length);
}
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
b[i][j] = val[i][j];
}
}
return;
}
template <typename MatValType>
void matrix<MatValType>::extract(array<MatValType> &b, size_t index, matrix_order_e order) const
{
if (order == RowMajor)
{
if (index >= row_length)
{
2024-09-16 14:28:08 +08:00
throw std::out_of_range("[gctl::matrix<T>::extract] Invalid index.");
2024-09-10 15:45:07 +08:00
}
b.resize(col_length);
for (size_t i = 0; i < col_length; i++)
{
b[i] = val[index][i];
}
return;
}
if (index >= col_length)
{
2024-09-16 14:28:08 +08:00
throw std::out_of_range("[gctl::matrix<T>::extract] Invalid index.");
2024-09-10 15:45:07 +08:00
}
b.resize(row_length);
for (size_t i = 0; i < row_length; i++)
{
b[i] = val[i][index];
}
return;
}
template <typename MatValType>
void matrix<MatValType>::reform(array<MatValType> &b, matrix_order_e order) const
{
b.resize(row_length*col_length);
if (order == RowMajor)
{
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
b[j+i*col_length] = val[i][j];
}
}
return;
}
for (size_t j = 0; j < col_length; j++)
{
for (size_t i = 0; i < row_length; i++)
{
b[i+j*row_length] = val[i][j];
}
}
return;
}
template <typename MatValType>
void matrix<MatValType>::for_each(foreach_m_ptr func)
{
for (size_t i = 0; i < row_length; i++)
{
for (size_t j = 0; j < col_length; j++)
{
2024-09-16 14:28:08 +08:00
func(val[i][j], i, j);
2024-09-10 15:45:07 +08:00
}
}
return;
}
template <typename MatValType>
void matrix<MatValType>::show(std::ostream &os, char sep) const
{
for (size_t i = 0; i < row_length; i++)
{
2024-09-16 14:28:08 +08:00
os << val[i][0];
for (size_t j = 1; j < col_length; j++)
2024-09-10 15:45:07 +08:00
{
2024-09-16 14:28:08 +08:00
os << sep << val[i][j];
2024-09-10 15:45:07 +08:00
}
os << std::endl;
}
return;
}
2025-02-06 21:17:24 +08:00
};
2024-09-10 15:45:07 +08:00
#endif // _GCTL_MATRIX_H