ready for parralization

This commit is contained in:
2025-09-12 22:58:52 +02:00
parent cb825aec40
commit 320436ce98
14 changed files with 920 additions and 294 deletions
+113
View File
@@ -0,0 +1,113 @@
#ifndef _inverse_n_
#define _inverse_n_
#include "./utils/vector.h"
#include "./utils/matrix.h"
namespace numerics{
template <typename T>
void inplace_inverse(utils::Matrix<T>& A, std::string method = "Gauss-Jordan"){
if (method == "Gauss-Jordan"){
utils::Matrix<T> B(A.rows(),A.cols(), T{0});
uint64_t icol{0}, irow{0}, rows{A.rows()}, cols{A.cols()};
double big, dum, pivinv, temp;
utils::Vi indxc(rows,0), indxr(rows,0), ipiv(rows,0);
//for (uint64_t j = 0; j < N; ++j){ ipiv[j] = 0;}
for (uint64_t i = 0; i < rows; i++){
big = 0.0;
for (uint64_t j = 0; j < rows; j++){
if (ipiv[j] != 1){
for (uint64_t k = 0; k < rows; k++){
if (ipiv[k] == 0){
if (abs(A(j,k)) >= big){
big = abs(A(j,k));
irow = j;
icol = k;
}
}
}
}
}
ipiv[icol]++;
if (irow != icol){
for (uint64_t l = 0; l < rows; l++){ // SWAP
temp = A(irow,l);
A(irow,l) = A(icol,l);
A(icol,l) = temp;
}
for (uint64_t l = 0; l < cols; l++){ // SWAP temp matrix
temp = B(irow,l);
B(irow,l) = B(icol,l);
B(icol,l) = temp;
}
}
indxr[i] = irow;
indxc[i] = icol;
if (A(icol,icol) == 0.0){
throw std::runtime_error("utill:inplace_inverse('Gauss-Jordan' - Singular Matrix");
}
pivinv= 1.0/A(icol,icol);
A(icol,icol)=1.0;
for (uint64_t l = 0; l < rows; l++){
A(icol,l) *= pivinv;
}
for (uint64_t l = 0; l < cols; l++){
B(icol,l) *= pivinv;
}
for (uint64_t ll = 0; ll < rows; ll++){
if (ll != icol){
dum = A(ll,icol);
A(ll,icol) = 0;
for (uint64_t l = 0; l < rows; l++){
A(ll,l) -= A(icol,l)*dum;
}
for (uint64_t l = 0; l < rows; l++){
B(ll,l) -= B(icol,l)*dum;
}
}
}
}
//m = temp_m;
for (int64_t l = rows-1; l >= 0; l--){
if (indxr[l] != indxc[l]){
for (uint64_t k = 0; k < rows; k++){
temp = A(k,indxr[l]);
A(k,indxr[l]) = A(k,indxc[l]);
A(k,indxc[l]) = temp;
}
}
}
}
else{
throw std::runtime_error("numerics::inplace_inverse(" + method + ") - Not implemented yet \r \nImplemented: 'Gauss-Jordan',");
}
}
template <typename T>
utils::Matrix<T> inverse(utils::Matrix<T>& A, std::string method = "Gauss-Jordan"){
utils::Matrix<T> B = A;
inplace_inverse(B, method);
return B;
}
} // namespace numerics
#endif // _inverse_n_
+42
View File
@@ -0,0 +1,42 @@
#ifndef _matmul_n_
#define _matmul_n_
#include "./utils/matrix.h"
namespace numerics{
template <typename T>
utils::Matrix<T> matmul(const utils::Matrix<T>& A, const utils::Matrix<T>& B){
if(A.cols() != B.rows()){
throw std::runtime_error("matmul: dimension mismatch");
}
const uint64_t m = A.rows();
const uint64_t n = A.cols(); // also B.rows()
const uint64_t p = B.cols();
T tmp;
utils::Matrix<T> C(m, n, T{0});
//#pragma omp parallel for collapse(2) schedule(static)
#pragma omp parallel for
for (uint64_t i = 0; i < m; ++i){
for (uint64_t j = 0; j < n; ++j){
tmp = A(i,j);
for (uint64_t k = 0; k < p; ++k){
C(i,k) += tmp * B(j,k);
}
}
}
return C;
}
} // namespace numerics
#endif // _matmul_n_
+54
View File
@@ -0,0 +1,54 @@
#ifndef _matvec_n_
#define _matvec_n_
#include "./utils/matrix.h"
namespace numerics{
// y = A * x, where A is (m×n) and x is length n and y is length m
template <typename T>
utils::Vector<T> matvec(const utils::Matrix<T>& A, const utils::Vector<T>& x) {
if (A.cols() != x.size()) {
throw std::runtime_error("matvec: dimension mismatch");
}
const uint64_t m = A.rows();
const uint64_t n = A.cols();
utils::Vector<T> y(m, T{0});
for (uint64_t i = 0; i < m; ++i) {
T acc = T{0};
for (uint64_t j = 0; j < n; ++j) {
acc += A(i, j) * x[j];
}
y[i] = acc;
}
return y;
}
// y = x * A, where x is length m and A is (m×n) -> y is length n
template <typename T>
utils::Vector<T> vecmat(const utils::Vector<T>& x, const utils::Matrix<T>& A) {
if (x.size() != A.rows()) {
throw std::runtime_error("vecmat: dimension mismatch");
}
const uint64_t m = A.rows();
const uint64_t n = A.cols();
utils::Vector<T> y(n, T{0});
for (uint64_t j = 0; j < n; ++j) {
T acc = T{0};
for (uint64_t i = 0; i < m; ++i) {
acc += x[i] * A(i, j);
}
y[j] = acc;
}
return y;
}
} // namespace numerics
#endif // _matvec_n_
+7
View File
@@ -0,0 +1,7 @@
// "./numerics/numerics.h"
#pragma once
#include "./numerics/transpose.h"
#include "./numerics/inverse.h"
#include "./numerics/matmul.h"
#include "./numerics/matvec.h"
+70
View File
@@ -0,0 +1,70 @@
#ifndef _transpose_n_
#define _transpose_n_
#include "./utils/matrix.h"
namespace numerics{
template <typename T>
void inplace_transpose(utils::Matrix<T>& A){
const uint64_t rows = A.rows();
const uint64_t cols = A.cols();
if (rows != cols){
throw std::runtime_error("inplace_transpose only valid for square matrices");
}
for (uint64_t i = 0; i < rows; ++i){
for (uint64_t j = i + 1; j < cols; ++j){
T tmp = A(j,i);
A(j,i) = A(i,j);
A(i,j) = tmp;
//std::swap(A(j,i), A(i,j));
}
}
}
template <typename T>
utils::Matrix<T> transpose(const utils::Matrix<T>& A){
const uint64_t rows = A.rows();
const uint64_t cols = A.cols();
utils::Matrix<T> B(cols, rows, T{});
for (uint64_t i = 0; i < rows; ++i){
for (uint64_t j = 0; j < cols; ++j){
B(j,i) = A(i,j);
}
}
return B;
}
} // namespace numerics
#endif // _transpose_n_