GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
dDiagMatrix.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 
112 DiagMatrix&
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 
126 DiagMatrix::abs (void) const
127 {
128  return DiagMatrix (extract_diag ().abs (), rows (), columns ());
129 }
130 
133 {
134  return DiagMatrix (real (a.extract_diag ()), a.rows (), a.cols ());
135 }
136 
139 {
140  return DiagMatrix (imag (a.extract_diag ()), a.rows (), a.cols ());
141 }
142 
143 Matrix
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  Matrix 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 
164 RowVector
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  RowVector 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 
179 RowVector
180 DiagMatrix::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  ColumnVector 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 
210 DiagMatrix::column (char *s) const
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  DiagMatrix 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 
255 DiagMatrix::pseudo_inverse (double tol) const
256 {
257  octave_idx_type r = rows ();
258  octave_idx_type c = cols ();
259  octave_idx_type len = length ();
260 
261  DiagMatrix retval (c, r);
262 
263  for (octave_idx_type i = 0; i < len; i++)
264  {
265  double val = std::abs (elem (i, i));
266  if (val < tol || val == 0.0)
267  retval.elem (i, i) = 0.0;
268  else
269  retval.elem (i, i) = 1.0 / 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 
291  DiagMatrix c (a_nr, b_nc);
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.0;
300 
301  return c;
302 }
303 
304 // other operations
305 
306 DET
308 {
309  DET det (1.0);
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 double
321 DiagMatrix::rcond (void) const
322 {
323  ColumnVector av = extract_diag (0).map<double> (fabs);
324  double amx = av.max ();
325  double amn = av.min ();
326  return amx == 0 ? 0.0 : amn / amx;
327 }
328 
329 std::ostream&
330 operator << (std::ostream& os, const DiagMatrix& 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 }
ColumnVector extract_diag(octave_idx_type k=0) const
Definition: dDiagMatrix.h:104
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
Definition: lo-error.c:38
DiagMatrix inverse(void) const
Definition: dDiagMatrix.cc:225
DiagMatrix & fill(double val)
Definition: dDiagMatrix.cc:54
bool operator==(const DiagMatrix &a) const
Definition: dDiagMatrix.cc:39
octave_idx_type b_nr
Definition: sylvester.cc:76
DiagMatrix(void)
Definition: dDiagMatrix.h:42
static T abs(T x)
Definition: pr-output.cc:1696
bool operator!=(const DiagMatrix &a) const
Definition: dDiagMatrix.cc:48
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
double min(void) const
Definition: dColVector.cc:243
octave_idx_type a_nc
Definition: sylvester.cc:74
double elem(octave_idx_type r, octave_idx_type c) const
Definition: DiagArray2.h:115
DET determinant(void) const
Definition: dDiagMatrix.cc:307
DiagMatrix operator*(const DiagMatrix &a, const DiagMatrix &b)
Definition: dDiagMatrix.cc:280
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
DiagMatrix imag(const ComplexDiagMatrix &a)
Definition: dDiagMatrix.cc:138
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
DiagMatrix abs(void) const
Definition: dDiagMatrix.cc:126
Definition: DET.h:34
double rcond(void) const
Definition: dDiagMatrix.cc:321
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
octave_value retval
Definition: data.cc:6246
DiagMatrix real(const ComplexDiagMatrix &a)
Definition: dDiagMatrix.cc:132
Definition: dMatrix.h:36
With real return the complex result
Definition: data.cc:3260
#define Inf
Definition: Faddeeva.cc:247
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
Matrix extract(octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
Definition: dDiagMatrix.cc:144
double max(void) const
Definition: dColVector.cc:259
b
Definition: cellfun.cc:400
octave_idx_type columns(void) const
Definition: DiagArray2.h:89
for i
Definition: data.cc:5264
ColumnVector column(octave_idx_type i) const
Definition: dDiagMatrix.cc:195
std::ostream & operator<<(std::ostream &os, const DiagMatrix &a)
Definition: dDiagMatrix.cc:330
bool mx_inline_equal(size_t n, const T1 *x, const T2 *y)
Definition: mx-inlines.cc:569
DiagMatrix pseudo_inverse(double tol=0.0) const
Definition: dDiagMatrix.cc:255
octave::stream os
Definition: file-io.cc:627
const double * data(void) const
Definition: DiagArray2.h:167
RowVector row(octave_idx_type i) const
Definition: dDiagMatrix.cc:165