1 #ifndef _MATRIX_HPP_INC_
2 #define _MATRIX_HPP_INC_
14 operator>(
const std::complex<T> &
a,
const std::complex<T> &
b) {
15 return std::norm(
a) > std::norm(
b);
20 operator<(
const std::complex<T> &
a,
const std::complex<T> &
b) {
21 return std::norm(
a) < std::norm(
b);
27 return std::norm(
a) >= std::norm(
b);
32 operator<=(
const std::complex<T> &
a,
const std::complex<T> &
b) {
33 return std::norm(
a) <= std::norm(
b);
65 data.resize(
M *
N, initialValue);
77 for (
auto & entry :
data) {
82 void rowAddition(
size_t destinationRow,
size_t sourceRow, T scalingFactor) {
83 assert(0 <= destinationRow && destinationRow <=
N);
84 assert(0 <= sourceRow && sourceRow <=
M);
85 for (
size_t n = 0; n <
N; n++) {
86 data[destinationRow *
N + n] += scalingFactor *
data[sourceRow *
N + n];
91 std::swap_ranges(
data.begin() + row1 *
N,
data.begin() + (row1 + 1) *
N,
92 data.begin() + row2 *
N);
97 for (
size_t m = 0;
m <
M;
m++) {
98 for (
size_t n = 0; n <
N; n++) {
123 for (
size_t m = 0;
m <
M;
m++) {
124 for (
size_t k = 0;
k <
N;
k++) {
125 for (
size_t n = 0; n2 < dest.
N; n2++) {
134 assert(
N == rhs.
N &&
M == rhs.
M);
141 for (
size_t m = 0;
m <
M;
m++) {
142 for (
size_t n = 0; n <
N; n++) {
149 assert(
N == rhs.
N &&
M == rhs.
M);
156 for (
size_t m = 0;
m <
M;
m++) {
157 for (
size_t n = 0; n <
N; n++) {
164 std::stringstream
toRet;
165 for (
size_t m = 0;
m <
M;
m++) {
166 for (
size_t n = 0; n <
N; n++) {
167 toRet << std::setw(5) << std::setprecision(2) <<
data[
m *
N + n]
188 for (
size_t n = 0; n <
N; n++) {
189 dest.
l.data[n *
N + n] = 1.0;
193 for (
size_t r = 0;
r <
M - 1;
r++) {
195 size_t largestRow =
r;
196 auto maxV =
abs(dest.
u.data[
r *
N +
r]);
197 for (
size_t r2 =
r + 1; r2 <
M; r2++) {
198 if (
abs(dest.
u.data[r2 *
N +
r]) > maxV) {
199 maxV =
abs(dest.
u.data[r2 *
N +
r]);
205 dest.
u.swapRows(
r, largestRow);
206 std::swap(dest.
p[
r], dest.
p[largestRow]);
208 for (
size_t n = 0; n <
r; n++) {
209 std::swap(dest.
l.data[
r *
N + n], dest.
l.data[largestRow *
N + n]);
213 for (
size_t m =
r + 1;
m <
M;
m++) {
217 T multiplier = dest.
u.data[
m *
N +
r] / dest.
u.data[
r *
N +
r];
218 dest.
u.rowAddition(
m,
r, -multiplier);
219 dest.
l.data[
m *
N +
r] = multiplier;
238 template<
typename Iterator>
241 Iterator destBegin, Iterator destEnd)
const {
242 assert(destEnd - destBegin == scratchSpace.
M);
243 for (
size_t m = 0;
m <
M;
m++) {
244 destBegin[
m] = rhs.
data[lu.
p[
m]];
248 for (
size_t m = 0;
m <
M;
m++) {
249 T val = destBegin[
m];
250 for (
size_t n = 0; n <
m; n++) {
251 val -= scratchSpace.
data[n] * lu.
l.data[
m *
N + n];
253 scratchSpace.
data[
m] = val / lu.
l.data[
m *
N +
m];
257 for (
size_t m = 0;
m <
M;
m++) {
258 T val = scratchSpace.
data[
M -
m - 1];
259 for (
size_t n = 0; n <
m; n++) {
260 val -= destBegin[(
M - n - 1)] *
261 lu.
u.data[(
M -
m - 1) *
N +
N - n - 1];
263 destBegin[
M -
m - 1] = val / lu.
u.data[(
M -
m - 1) *
N +
M -
m - 1];
276 std::vector<size_t>
p;
283 :
l(other.
l),
u(other.
u),
p(other.
p),
M(other.
M) {
288 std::stringstream
toRet;
289 toRet <<
" U\n" <<
u.toString();
290 toRet <<
" L\n" <<
l.toString();
292 for (
size_t i = 0;
i <
p.size();
i++) {
293 toRet << std::setw(5) <<
p[
i] <<
" ";
std::complex< double > operator>(const std::complex< T > &a, const std::complex< T > &b)
std::complex< double > operator<(const std::complex< T > &a, const std::complex< T > &b)
std::complex< double > operator>=(const std::complex< T > &a, const std::complex< T > &b)
std::complex< double > operator<=(const std::complex< T > &a, const std::complex< T > &b)
Find a complex rational model for freq domain data for a
end if abs(real(dotprod))>rstoerst rstoerst
requires(std::is_arithmetic< ValType >::value &&NumVars >=0) struct DiffVar
A helper class to store the L U and pivot matrices. Mainly useful in solving systems of equations.
LUPair(const LUPair< T > &other)
A matrix class with support for LU-decomposition, and left division.
void leftDivide(const Matrix< T > &rhs, const LUPair< T > &lu, Matrix< T > &scratchSpace, Iterator destBegin, Iterator destEnd) const
const T & operator()(size_t m, size_t n) const
void swapRows(size_t row1, size_t row2)
void leftDivide(const Matrix< T > &rhs, const LUPair< T > &lu, Matrix< T > &scratchSpace, Matrix< T > &dest) const
void subtract(const Matrix< T > &rhs, Matrix< T > &dest) const
void luPair(LUPair< T > &dest) const
Matrix< T > add(const Matrix< T > &rhs) const
Matrix(size_t M, size_t N)
void multiply(const Matrix< T > &rhs, Matrix< T > &dest) const
std::string toString() const
Matrix< T > leftDivide(const Matrix< T > &rhs) const
LUPair< T > luPair() const
Matrix(size_t M, size_t N, T initialValue)
void rowAddition(size_t destinationRow, size_t sourceRow, T scalingFactor)
Matrix< T > multiply(const Matrix< T > &rhs) const
T & operator()(size_t m, size_t n)
Matrix< T > subtract(const Matrix< T > &rhs) const
void add(const Matrix< T > &rhs, Matrix< T > &dest) const