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