GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
fDiagMatrix.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1994-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <ostream>
31 
32 #include "Array-util.h"
33 #include "lo-error.h"
34 #include "mx-base.h"
35 #include "mx-inlines.cc"
36 #include "oct-cmplx.h"
37 
38 // Diagonal Matrix class.
39 
40 bool
42 {
43  if (rows () != a.rows () || cols () != a.cols ())
44  return 0;
45 
46  return mx_inline_equal (length (), data (), a.data ());
47 }
48 
49 bool
51 {
52  return !(*this == a);
53 }
54 
57 {
58  for (octave_idx_type i = 0; i < length (); i++)
59  elem (i, i) = val;
60  return *this;
61 }
62 
65 {
66  if (beg < 0 || end >= length () || end < beg)
67  (*current_liboctave_error_handler) ("range error for fill");
68 
69  for (octave_idx_type i = beg; i <= end; i++)
70  elem (i, i) = val;
71 
72  return *this;
73 }
74 
77 {
79  if (a.numel () != len)
80  (*current_liboctave_error_handler) ("range error for fill");
81 
82  for (octave_idx_type i = 0; i < len; i++)
83  elem (i, i) = a.elem (i);
84 
85  return *this;
86 }
87 
90 {
92  if (a.numel () != len)
93  (*current_liboctave_error_handler) ("range error for fill");
94 
95  for (octave_idx_type i = 0; i < len; i++)
96  elem (i, i) = a.elem (i);
97 
98  return *this;
99 }
100 
103 {
104  octave_idx_type a_len = a.numel ();
105  if (beg < 0 || beg + a_len >= length ())
106  (*current_liboctave_error_handler) ("range error for fill");
107 
108  for (octave_idx_type i = 0; i < a_len; i++)
109  elem (i+beg, i+beg) = a.elem (i);
110 
111  return *this;
112 }
113 
116 {
117  octave_idx_type a_len = a.numel ();
118  if (beg < 0 || beg + a_len >= length ())
119  (*current_liboctave_error_handler) ("range error for fill");
120 
121  for (octave_idx_type i = 0; i < a_len; i++)
122  elem (i+beg, i+beg) = a.elem (i);
123 
124  return *this;
125 }
126 
129 {
130  return FloatDiagMatrix (extract_diag ().abs (), rows (), columns ());
131 }
132 
135 {
136  return FloatDiagMatrix (real (a.extract_diag ()), a.rows (), a.columns ());
137 }
138 
141 {
142  return FloatDiagMatrix (imag (a.extract_diag ()), a.rows (), a.columns ());
143 }
144 
147  octave_idx_type r2, octave_idx_type c2) const
148 {
149  if (r1 > r2) { std::swap (r1, r2); }
150  if (c1 > c2) { std::swap (c1, c2); }
151 
152  octave_idx_type new_r = r2 - r1 + 1;
153  octave_idx_type new_c = c2 - c1 + 1;
154 
155  FloatMatrix result (new_r, new_c);
156 
157  for (octave_idx_type j = 0; j < new_c; j++)
158  for (octave_idx_type i = 0; i < new_r; i++)
159  result.elem (i, j) = elem (r1+i, c1+j);
160 
161  return result;
162 }
163 
164 // extract row or column i.
165 
168 {
169  octave_idx_type r = rows ();
170  octave_idx_type c = cols ();
171  if (i < 0 || i >= r)
172  (*current_liboctave_error_handler) ("invalid row selection");
173 
174  FloatRowVector retval (c, 0.0);
175  if (r <= c || i < c)
176  retval.elem (i) = elem (i, i);
177 
178  return retval;
179 }
180 
182 FloatDiagMatrix::row (char *s) const
183 {
184  if (! s)
185  (*current_liboctave_error_handler) ("invalid row selection");
186 
187  char c = s[0];
188  if (c == 'f' || c == 'F')
189  return row (static_cast<octave_idx_type> (0));
190  else if (c == 'l' || c == 'L')
191  return row (rows () - 1);
192  else
193  (*current_liboctave_error_handler) ("invalid row selection");
194 }
195 
198 {
199  octave_idx_type r = rows ();
200  octave_idx_type c = cols ();
201  if (i < 0 || i >= c)
202  (*current_liboctave_error_handler) ("invalid column selection");
203 
204  FloatColumnVector retval (r, 0.0);
205  if (r >= c || i < r)
206  retval.elem (i) = elem (i, i);
207 
208  return retval;
209 }
210 
212 FloatDiagMatrix::column (char *s) const
213 {
214  if (! s)
215  (*current_liboctave_error_handler) ("invalid column selection");
216 
217  char c = s[0];
218  if (c == 'f' || c == 'F')
219  return column (static_cast<octave_idx_type> (0));
220  else if (c == 'l' || c == 'L')
221  return column (cols () - 1);
222  else
223  (*current_liboctave_error_handler) ("invalid column selection");
224 }
225 
228 {
229  octave_idx_type info;
230  return inverse (info);
231 }
232 
235 {
236  octave_idx_type r = rows ();
237  octave_idx_type c = cols ();
239  if (r != c)
240  (*current_liboctave_error_handler) ("inverse requires square matrix");
241 
242  FloatDiagMatrix retval (r, c);
243 
244  info = 0;
245  for (octave_idx_type i = 0; i < len; i++)
246  {
247  if (elem (i, i) == 0.0)
248  retval.elem (i, i) = octave::numeric_limits<float>::Inf ();
249  else
250  retval.elem (i, i) = 1.0 / elem (i, i);
251  }
252 
253  return retval;
254 }
255 
258 {
259  octave_idx_type r = rows ();
260  octave_idx_type c = cols ();
262 
263  FloatDiagMatrix retval (c, r);
264 
265  for (octave_idx_type i = 0; i < len; i++)
266  {
267  float val = std::abs (elem (i, i));
268  if (val < tol || val == 0.0f)
269  retval.elem (i, i) = 0.0f;
270  else
271  retval.elem (i, i) = 1.0f / elem (i, i);
272  }
273 
274  return retval;
275 }
276 
277 // diagonal matrix by diagonal matrix -> diagonal matrix operations
278 
279 // diagonal matrix by diagonal matrix -> diagonal matrix operations
280 
283 {
284  octave_idx_type a_nr = a.rows ();
285  octave_idx_type a_nc = a.cols ();
286 
287  octave_idx_type b_nr = b.rows ();
288  octave_idx_type b_nc = b.cols ();
289 
290  if (a_nc != b_nr)
291  octave::err_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
292 
293  FloatDiagMatrix c (a_nr, b_nc);
294 
295  octave_idx_type len = c.length ();
296  octave_idx_type lenm = (len < a_nc ? len : a_nc);
297 
298  for (octave_idx_type i = 0; i < lenm; i++)
299  c.dgxelem (i) = a.dgelem (i) * b.dgelem (i);
300  for (octave_idx_type i = lenm; i < len; i++)
301  c.dgxelem (i) = 0.0f;
302 
303  return c;
304 }
305 
306 // other operations
307 
308 FloatDET
310 {
311  FloatDET det (1.0f);
312  if (rows () != cols ())
313  (*current_liboctave_error_handler) ("determinant requires square matrix");
314 
316  for (octave_idx_type i = 0; i < len; i++)
317  det *= elem (i, i);
318 
319  return det;
320 }
321 
322 float
324 {
325  FloatColumnVector av = extract_diag (0).map<float> (fabsf);
326  float amx = av.max ();
327  float amn = av.min ();
328  return amx == 0 ? 0.0f : amn / amx;
329 }
330 
331 std::ostream&
332 operator << (std::ostream& os, const FloatDiagMatrix& a)
333 {
334 // int field_width = os.precision () + 7;
335 
336  for (octave_idx_type i = 0; i < a.rows (); i++)
337  {
338  for (octave_idx_type j = 0; j < a.cols (); j++)
339  {
340  if (i == j)
341  os << ' ' /* setw (field_width) */ << a.elem (i, i);
342  else
343  os << ' ' /* setw (field_width) */ << 0.0;
344  }
345  os << "\n";
346  }
347  return os;
348 }
#define Inf
Definition: Faddeeva.cc:260
T & elem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:562
Array< U, A > map(F fcn) const
Apply function fcn to each element of the Array<T, Alloc>.
Definition: Array.h:859
octave_idx_type numel() const
Number of elements in the array.
Definition: Array.h:414
octave_idx_type rows() const
Definition: DiagArray2.h:89
T dgelem(octave_idx_type i) const
Definition: DiagArray2.h:124
octave_idx_type length() const
Definition: DiagArray2.h:95
T elem(octave_idx_type r, octave_idx_type c) const
Definition: DiagArray2.h:117
T & dgxelem(octave_idx_type i)
Definition: DiagArray2.h:152
octave_idx_type columns() const
Definition: DiagArray2.h:91
octave_idx_type cols() const
Definition: DiagArray2.h:90
const T * data() const
Definition: DiagArray2.h:169
float max() const
Definition: fColVector.cc:261
float min() const
Definition: fColVector.cc:245
FloatComplexColumnVector extract_diag(octave_idx_type k=0) const
Definition: fCDiagMatrix.h:144
bool operator==(const FloatDiagMatrix &a) const
Definition: fDiagMatrix.cc:41
FloatRowVector row(octave_idx_type i) const
Definition: fDiagMatrix.cc:167
float rcond() const
Definition: fDiagMatrix.cc:323
FloatDiagMatrix inverse() const
Definition: fDiagMatrix.cc:227
FloatDiagMatrix abs() const
Definition: fDiagMatrix.cc:128
bool operator!=(const FloatDiagMatrix &a) const
Definition: fDiagMatrix.cc:50
FloatDiagMatrix & fill(float val)
Definition: fDiagMatrix.cc:56
FloatColumnVector extract_diag(octave_idx_type k=0) const
Definition: fDiagMatrix.h:110
FloatDET determinant() const
Definition: fDiagMatrix.cc:309
FloatMatrix extract(octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
Definition: fDiagMatrix.cc:146
FloatDiagMatrix pseudo_inverse(float tol=0.0f) const
Definition: fDiagMatrix.cc:257
FloatColumnVector column(octave_idx_type i) const
Definition: fDiagMatrix.cc:197
FloatDiagMatrix()=default
Definition: DET.h:39
std::ostream & operator<<(std::ostream &os, const FloatDiagMatrix &a)
Definition: fDiagMatrix.cc:332
FloatDiagMatrix real(const FloatComplexDiagMatrix &a)
Definition: fDiagMatrix.cc:134
FloatDiagMatrix operator*(const FloatDiagMatrix &a, const FloatDiagMatrix &b)
Definition: fDiagMatrix.cc:282
FloatDiagMatrix imag(const FloatComplexDiagMatrix &a)
Definition: fDiagMatrix.cc:140
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
Definition: lo-error.c:41
bool mx_inline_equal(std::size_t n, const T1 *x, const T2 *y)
Definition: mx-inlines.cc:577
T * r
Definition: mx-inlines.cc:781
F77_RET_T len
Definition: xerbla.cc:61