Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Matrix.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include <vector>
5
9
10namespace Stroika::Foundation::Math::LinearAlgebra {
11
12 /*
13 ********************************************************************************
14 ******************************** Matrix<T>::Rep_ *******************************
15 ********************************************************************************
16 */
17 template <typename T>
18 class Matrix<T>::Rep_ {
19 public:
20 Rep_ (const DimensionType& dimensions)
21 : fDimensions_{dimensions}
22 {
23 }
24
25 T GetAt (size_t row, size_t col) const
26 {
27 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
28 Require (row < fDimensions_.fRows);
29 Require (col < fDimensions_.fColumns);
30 return fData_[row * fDimensions_.fColumns + col];
31 }
32 void SetAt (size_t row, size_t col, T value)
33 {
34 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
35 Require (row < fDimensions_.fRows);
36 Require (col < fDimensions_.fColumns);
37 //fData_.SetAt (row * fDimensions_.fColumns + col, value);
38 fData_[row * fDimensions_.fColumns + col] = value;
39 }
40 void push_back (Common::ArgByValueType<T> fillValue)
41 {
42 Debug::AssertExternallySynchronizedMutex::WriteContext declareContext{fThisAssertExternallySynchronized_};
43 fData_.push_back (fillValue);
44 }
45
46 DimensionType GetDimensions () const
47 {
48 Debug::AssertExternallySynchronizedMutex::ReadContext declareContext{fThisAssertExternallySynchronized_};
49 return fDimensions_;
50 }
51
52 private:
53 DimensionType fDimensions_;
54 // nb: use vector<> because for debug builds - big difference in speed - and hidden anyhow
55 // row*nCols + col is addressing scheme
56 vector<T> fData_;
57 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
58 };
59
60 /*
61 ********************************************************************************
62 ********************************** Matrix<T> ***********************************
63 ********************************************************************************
64 */
65 template <typename T>
66 inline Matrix<T>::Matrix (const DimensionType& dimensions)
67 : Matrix{dimensions, T{0}}
68 {
69 }
70 template <typename T>
71 inline Matrix<T>::Matrix (size_t rows, size_t columns)
72 : Matrix{DimensionType{rows, columns}}
73 {
74 }
75 template <typename T>
76 Matrix<T>::Matrix (const DimensionType& dimensions, Common::ArgByValueType<T> fillValue)
77 : fRep_{make_shared<Rep_> (dimensions)}
78 {
79 for (size_t r = 0; r < dimensions.fRows; ++r) {
80 for (size_t c = 0; c < dimensions.fColumns; ++c) {
81 fRep_.rwget ()->push_back (fillValue);
82 }
83 }
84 }
85 template <typename T>
86 inline Matrix<T>::Matrix (size_t rows, size_t columns, Common::ArgByValueType<T> fillValue)
87 : Matrix{DimensionType{rows, columns}, fillValue}
88 {
89 }
90 template <typename T>
91 Matrix<T>::Matrix (const DimensionType& dimensions, const function<T ()>& filler)
92 : fRep_{make_shared<Rep_> (dimensions)}
93 {
94 for (size_t r = 0; r < dimensions.fRows; ++r) {
95 for (size_t c = 0; c < dimensions.fColumns; ++c) {
96 fRep_.rwget ()->push_back (filler ());
97 }
98 }
99 }
100 template <typename T>
101 Matrix<T> Matrix<T>::Identity (const DimensionType& dimensions)
102 {
103 size_t row = 0;
104 size_t col = 0;
105 return Matrix{dimensions, [&] () {
106 T result = (row == col) ? 1 : 0;
107 ++col;
108 if (col > dimensions.fColumns) {
109 col = 0;
110 ++row;
111 }
112 }};
113 }
114 template <typename T>
115 inline auto Matrix<T>::GetDimensions () const -> DimensionType
116 {
117 return fRep_.cget ()->GetDimensions ();
118 }
119 template <typename T>
120 Containers::Sequence<Vector<T>> Matrix<T>::GetRows () const
121 {
122 Containers::Sequence<Vector<T>> result;
123 DimensionType dim = GetDimensions ();
124 for (size_t r = 0; r < dim.fRows; ++r) {
125 vector<T> row;
126 for (size_t c = 0; c < dim.fColumns; ++c) {
127 row.push_back (fRep_.cget ()->GetAt (r, c));
128 }
129 result += Vector<T>{row};
130 }
131 return result;
132 }
133 template <typename T>
134 Containers::Sequence<Vector<T>> Matrix<T>::GetColumns () const
135 {
136 Containers::Sequence<Vector<T>> result;
137 DimensionType dim = GetDimensions ();
138 for (size_t c = 0; c < dim.fColumns; ++c) {
139 vector<T> col;
140 for (size_t r = 0; r < dim.fRows; ++r) {
141 col.push_back (fRep_.cget ()->GetAt (r, c));
142 }
143 result += Vector<T>{col};
144 }
145 return result;
146 }
147 template <typename T>
148 inline T Matrix<T>::GetAt (size_t r, size_t c) const
149 {
150 return fRep_.cget ()->GetAt (r, c);
151 }
152 template <typename T>
153 inline void Matrix<T>::SetAt (size_t r, size_t c, T v)
154 {
155 fRep_.rwget ()->SetAt (r, c, v);
156 }
157 template <typename T>
158 inline const typename Matrix<T>::ReadOnlyTemporaryRowReference_ Matrix<T>::operator[] (size_t row) const
159 {
160 return ReadOnlyTemporaryRowReference_{*this, row};
161 }
162 template <typename T>
163 Characters::String Matrix<T>::ToString () const
164 {
165 Characters::StringBuilder sb;
166 sb << "["sv;
167 for (size_t row = 0; row < GetDimensions ().fRows; ++row) {
168 sb << "["sv;
169 for (size_t col = 0; col < GetDimensions ().fColumns; ++col) {
170 sb << GetAt (row, col) << ", "sv;
171 }
172 sb << "],"sv;
173 }
174 sb << "]"sv;
175 return sb;
176 }
177
178}
shared_lock< const AssertExternallySynchronizedMutex > ReadContext
Instantiate AssertExternallySynchronizedMutex::ReadContext to designate an area of code where protect...
unique_lock< AssertExternallySynchronizedMutex > WriteContext
Instantiate AssertExternallySynchronizedMutex::WriteContext to designate an area of code where protec...