GNU Octave  4.4.1
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-2018 John W. Eaton
4 Copyright (C) 2009 VZLU Prague
5 
6 This file is part of Octave.
7 
8 Octave is free software: you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <https://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if defined (HAVE_CONFIG_H)
25 # include "config.h"
26 #endif
27 
28 #include <iostream>
29 
30 #include "Array-util.h"
31 #include "lo-error.h"
32 #include "mx-base.h"
33 #include "mx-inlines.cc"
34 #include "oct-cmplx.h"
35 
36 // Diagonal Matrix class.
37 
38 bool
40 {
41  if (rows () != a.rows () || cols () != a.cols ())
42  return 0;
43 
44  return mx_inline_equal (length (), data (), a.data ());
45 }
46 
47 bool
49 {
50  return !(*this == a);
51 }
52 
55 {
56  for (octave_idx_type i = 0; i < length (); i++)
57  elem (i, i) = val;
58  return *this;
59 }
60 
63 {
64  if (beg < 0 || end >= length () || end < beg)
65  (*current_liboctave_error_handler) ("range error for fill");
66 
67  for (octave_idx_type i = beg; i <= end; i++)
68  elem (i, i) = val;
69 
70  return *this;
71 }
72 
75 {
76  octave_idx_type len = length ();
77  if (a.numel () != len)
78  (*current_liboctave_error_handler) ("range error for fill");
79 
80  for (octave_idx_type i = 0; i < len; i++)
81  elem (i, i) = a.elem (i);
82 
83  return *this;
84 }
85 
88 {
89  octave_idx_type len = length ();
90  if (a.numel () != len)
91  (*current_liboctave_error_handler) ("range error for fill");
92 
93  for (octave_idx_type i = 0; i < len; i++)
94  elem (i, i) = a.elem (i);
95 
96  return *this;
97 }
98 
101 {
102  octave_idx_type a_len = a.numel ();
103  if (beg < 0 || beg + a_len >= length ())
104  (*current_liboctave_error_handler) ("range error for fill");
105 
106  for (octave_idx_type i = 0; i < a_len; i++)
107  elem (i+beg, i+beg) = a.elem (i);
108 
109  return *this;
110 }
111 
114 {
115  octave_idx_type a_len = a.numel ();
116  if (beg < 0 || beg + a_len >= length ())
117  (*current_liboctave_error_handler) ("range error for fill");
118 
119  for (octave_idx_type i = 0; i < a_len; i++)
120  elem (i+beg, i+beg) = a.elem (i);
121 
122  return *this;
123 }
124 
127 {
128  return FloatDiagMatrix (extract_diag ().abs (), rows (), columns ());
129 }
130 
133 {
134  return FloatDiagMatrix (real (a.extract_diag ()), a.rows (), a.columns ());
135 }
136 
139 {
140  return FloatDiagMatrix (imag (a.extract_diag ()), a.rows (), a.columns ());
141 }
142 
145  octave_idx_type r2, octave_idx_type c2) const
146 {
147  if (r1 > r2) { std::swap (r1, r2); }
148  if (c1 > c2) { std::swap (c1, c2); }
149 
150  octave_idx_type new_r = r2 - r1 + 1;
151  octave_idx_type new_c = c2 - c1 + 1;
152 
153  FloatMatrix result (new_r, new_c);
154 
155  for (octave_idx_type j = 0; j < new_c; j++)
156  for (octave_idx_type i = 0; i < new_r; i++)
157  result.elem (i, j) = elem (r1+i, c1+j);
158 
159  return result;
160 }
161 
162 // extract row or column i.
163 
166 {
167  octave_idx_type r = rows ();
168  octave_idx_type c = cols ();
169  if (i < 0 || i >= r)
170  (*current_liboctave_error_handler) ("invalid row selection");
171 
172  FloatRowVector retval (c, 0.0);
173  if (r <= c || (r > c && i < c))
174  retval.elem (i) = elem (i, i);
175 
176  return retval;
177 }
178 
180 FloatDiagMatrix::row (char *s) const
181 {
182  if (! s)
183  (*current_liboctave_error_handler) ("invalid row selection");
184 
185  char c = *s;
186  if (c == 'f' || c == 'F')
187  return row (static_cast<octave_idx_type>(0));
188  else if (c == 'l' || c == 'L')
189  return row (rows () - 1);
190  else
191  (*current_liboctave_error_handler) ("invalid row selection");
192 }
193 
196 {
197  octave_idx_type r = rows ();
198  octave_idx_type c = cols ();
199  if (i < 0 || i >= c)
200  (*current_liboctave_error_handler) ("invalid column selection");
201 
202  FloatColumnVector retval (r, 0.0);
203  if (r >= c || (r < c && i < r))
204  retval.elem (i) = elem (i, i);
205 
206  return retval;
207 }
208 
211 {
212  if (! s)
213  (*current_liboctave_error_handler) ("invalid column selection");
214 
215  char c = *s;
216  if (c == 'f' || c == 'F')
217  return column (static_cast<octave_idx_type>(0));
218  else if (c == 'l' || c == 'L')
219  return column (cols () - 1);
220  else
221  (*current_liboctave_error_handler) ("invalid column selection");
222 }
223 
226 {
227  octave_idx_type info;
228  return inverse (info);
229 }
230 
233 {
234  octave_idx_type r = rows ();
235  octave_idx_type c = cols ();
236  octave_idx_type len = length ();
237  if (r != c)
238  (*current_liboctave_error_handler) ("inverse requires square matrix");
239 
240  FloatDiagMatrix retval (r, c);
241 
242  info = 0;
243  for (octave_idx_type i = 0; i < len; i++)
244  {
245  if (elem (i, i) == 0.0)
247  else
248  retval.elem (i, i) = 1.0 / elem (i, i);
249  }
250 
251  return retval;
252 }
253 
256 {
257  octave_idx_type r = rows ();
258  octave_idx_type c = cols ();
259  octave_idx_type len = length ();
260 
261  FloatDiagMatrix retval (c, r);
262 
263  for (octave_idx_type i = 0; i < len; i++)
264  {
265  float val = std::abs (elem (i, i));
266  if (val < tol || val == 0.0f)
267  retval.elem (i, i) = 0.0f;
268  else
269  retval.elem (i, i) = 1.0f / elem (i, i);
270  }
271 
272  return retval;
273 }
274 
275 // diagonal matrix by diagonal matrix -> diagonal matrix operations
276 
277 // diagonal matrix by diagonal matrix -> diagonal matrix operations
278 
281 {
282  octave_idx_type a_nr = a.rows ();
283  octave_idx_type a_nc = a.cols ();
284 
285  octave_idx_type b_nr = b.rows ();
286  octave_idx_type b_nc = b.cols ();
287 
288  if (a_nc != b_nr)
289  octave::err_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
290 
292 
293  octave_idx_type len = c.length ();
294  octave_idx_type lenm = (len < a_nc ? len : a_nc);
295 
296  for (octave_idx_type i = 0; i < lenm; i++)
297  c.dgxelem (i) = a.dgelem (i) * b.dgelem (i);
298  for (octave_idx_type i = lenm; i < len; i++)
299  c.dgxelem (i) = 0.0f;
300 
301  return c;
302 }
303 
304 // other operations
305 
306 FloatDET
308 {
309  FloatDET det (1.0f);
310  if (rows () != cols ())
311  (*current_liboctave_error_handler) ("determinant requires square matrix");
312 
313  octave_idx_type len = length ();
314  for (octave_idx_type i = 0; i < len; i++)
315  det *= elem (i, i);
316 
317  return det;
318 }
319 
320 float
322 {
323  FloatColumnVector av = extract_diag (0).map<float> (fabsf);
324  float amx = av.max ();
325  float amn = av.min ();
326  return amx == 0 ? 0.0f : amn / amx;
327 }
328 
329 std::ostream&
330 operator << (std::ostream& os, const FloatDiagMatrix& a)
331 {
332 // int field_width = os.precision () + 7;
333 
334  for (octave_idx_type i = 0; i < a.rows (); i++)
335  {
336  for (octave_idx_type j = 0; j < a.cols (); j++)
337  {
338  if (i == j)
339  os << ' ' /* setw (field_width) */ << a.elem (i, i);
340  else
341  os << ' ' /* setw (field_width) */ << 0.0;
342  }
343  os << "\n";
344  }
345  return os;
346 }
FloatDiagMatrix & fill(float val)
Definition: fDiagMatrix.cc:54
float max(void) const
Definition: fColVector.cc:259
FloatColumnVector extract_diag(octave_idx_type k=0) const
Definition: fDiagMatrix.h:105
FloatRowVector row(octave_idx_type i) const
Definition: fDiagMatrix.cc:165
FloatDiagMatrix inverse(void) const
Definition: fDiagMatrix.cc:225
FloatDET determinant(void) const
Definition: fDiagMatrix.cc:307
FloatColumnVector column(octave_idx_type i) const
Definition: fDiagMatrix.cc:195
FloatDiagMatrix operator*(const FloatDiagMatrix &a, const FloatDiagMatrix &b)
Definition: fDiagMatrix.cc:280
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE * f
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
Definition: lo-error.c:38
octave_idx_type b_nr
Definition: sylvester.cc:76
static T abs(T x)
Definition: pr-output.cc:1696
FloatDiagMatrix pseudo_inverse(float tol=0.0f) const
Definition: fDiagMatrix.cc:255
octave_idx_type rows(void) const
Definition: DiagArray2.h:87
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
Definition: file-io.cc:587
s
Definition: file-io.cc:2729
octave_idx_type a_nc
Definition: sylvester.cc:74
float elem(octave_idx_type r, octave_idx_type c) const
Definition: DiagArray2.h:115
bool operator!=(const FloatDiagMatrix &a) const
Definition: fDiagMatrix.cc:48
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:400
bool swap
Definition: load-save.cc:738
bool operator==(const FloatDiagMatrix &a) const
Definition: fDiagMatrix.cc:39
FloatDiagMatrix abs(void) const
Definition: fDiagMatrix.cc:126
octave_idx_type length(void) const
Definition: DiagArray2.h:93
octave_idx_type cols(void) const
Definition: DiagArray2.h:88
octave_idx_type a_nr
Definition: sylvester.cc:73
Definition: DET.h:34
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
octave_value retval
Definition: data.cc:6246
FloatDiagMatrix real(const FloatComplexDiagMatrix &a)
Definition: fDiagMatrix.cc:132
With real return the complex result
Definition: data.cc:3260
float rcond(void) const
Definition: fDiagMatrix.cc:321
#define Inf
Definition: Faddeeva.cc:247
float min(void) const
Definition: fColVector.cc:243
Array< U > map(F fcn) const
Apply function fcn to each element of the Array<T>.
Definition: Array.h:764
octave_idx_type b_nc
Definition: sylvester.cc:77
b
Definition: cellfun.cc:400
octave_idx_type columns(void) const
Definition: DiagArray2.h:89
for i
Definition: data.cc:5264
FloatDiagMatrix(void)
Definition: fDiagMatrix.h:42
FloatMatrix extract(octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
Definition: fDiagMatrix.cc:144
bool mx_inline_equal(size_t n, const T1 *x, const T2 *y)
Definition: mx-inlines.cc:569
FloatDiagMatrix imag(const FloatComplexDiagMatrix &a)
Definition: fDiagMatrix.cc:138
octave::stream os
Definition: file-io.cc:627
const float * data(void) const
Definition: DiagArray2.h:167
std::ostream & operator<<(std::ostream &os, const FloatDiagMatrix &a)
Definition: fDiagMatrix.cc:330