GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
fCDiagMatrix.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 "lo-ieee.h"
33 #include "mx-base.h"
34 #include "mx-inlines.cc"
35 #include "oct-cmplx.h"
36 
37 // FloatComplex Diagonal Matrix class
38 
40  : MDiagArray2<FloatComplex> (a.rows (), a.cols ())
41 {
42  for (octave_idx_type i = 0; i < length (); i++)
43  elem (i, i) = a.elem (i, i);
44 }
45 
46 bool
48 {
49  if (rows () != a.rows () || cols () != a.cols ())
50  return 0;
51 
52  return mx_inline_equal (length (), data (), a.data ());
53 }
54 
55 bool
57 {
58  return !(*this == a);
59 }
60 
63 {
64  for (octave_idx_type i = 0; i < length (); i++)
65  elem (i, i) = val;
66  return *this;
67 }
68 
71 {
72  for (octave_idx_type i = 0; i < length (); i++)
73  elem (i, i) = val;
74  return *this;
75 }
76 
80 {
81  if (beg < 0 || end >= length () || end < beg)
82  (*current_liboctave_error_handler) ("range error for fill");
83 
84  for (octave_idx_type i = beg; i <= end; i++)
85  elem (i, i) = val;
86 
87  return *this;
88 }
89 
93 {
94  if (beg < 0 || end >= length () || end < beg)
95  (*current_liboctave_error_handler) ("range error for fill");
96 
97  for (octave_idx_type i = beg; i <= end; i++)
98  elem (i, i) = val;
99 
100  return *this;
101 }
102 
105 {
106  octave_idx_type len = length ();
107  if (a.numel () != len)
108  (*current_liboctave_error_handler) ("range error for fill");
109 
110  for (octave_idx_type i = 0; i < len; i++)
111  elem (i, i) = a.elem (i);
112 
113  return *this;
114 }
115 
118 {
119  octave_idx_type len = length ();
120  if (a.numel () != len)
121  (*current_liboctave_error_handler) ("range error for fill");
122 
123  for (octave_idx_type i = 0; i < len; i++)
124  elem (i, i) = a.elem (i);
125 
126  return *this;
127 }
128 
131 {
132  octave_idx_type len = length ();
133  if (a.numel () != len)
134  (*current_liboctave_error_handler) ("range error for fill");
135 
136  for (octave_idx_type i = 0; i < len; i++)
137  elem (i, i) = a.elem (i);
138 
139  return *this;
140 }
141 
144 {
145  octave_idx_type len = length ();
146  if (a.numel () != len)
147  (*current_liboctave_error_handler) ("range error for fill");
148 
149  for (octave_idx_type i = 0; i < len; i++)
150  elem (i, i) = a.elem (i);
151 
152  return *this;
153 }
154 
157 {
158  octave_idx_type a_len = a.numel ();
159  if (beg < 0 || beg + a_len >= length ())
160  (*current_liboctave_error_handler) ("range error for fill");
161 
162  for (octave_idx_type i = 0; i < a_len; i++)
163  elem (i+beg, i+beg) = a.elem (i);
164 
165  return *this;
166 }
167 
170  octave_idx_type beg)
171 {
172  octave_idx_type a_len = a.numel ();
173  if (beg < 0 || beg + a_len >= length ())
174  (*current_liboctave_error_handler) ("range error for fill");
175 
176  for (octave_idx_type i = 0; i < a_len; i++)
177  elem (i+beg, i+beg) = a.elem (i);
178 
179  return *this;
180 }
181 
184 {
185  octave_idx_type a_len = a.numel ();
186  if (beg < 0 || beg + a_len >= length ())
187  (*current_liboctave_error_handler) ("range error for fill");
188 
189  for (octave_idx_type i = 0; i < a_len; i++)
190  elem (i+beg, i+beg) = a.elem (i);
191 
192  return *this;
193 }
194 
197  octave_idx_type beg)
198 {
199  octave_idx_type a_len = a.numel ();
200  if (beg < 0 || beg + a_len >= length ())
201  (*current_liboctave_error_handler) ("range error for fill");
202 
203  for (octave_idx_type i = 0; i < a_len; i++)
204  elem (i+beg, i+beg) = a.elem (i);
205 
206  return *this;
207 }
208 
211 {
212  return FloatDiagMatrix (extract_diag ().abs (), rows (), columns ());
213 }
214 
217 {
218  return FloatComplexDiagMatrix (conj (a.extract_diag ()), a.rows (),
219  a.columns ());
220 }
221 
222 // resize is the destructive analog for this one
223 
226  octave_idx_type r2, octave_idx_type c2) const
227 {
228  if (r1 > r2) { std::swap (r1, r2); }
229  if (c1 > c2) { std::swap (c1, c2); }
230 
231  octave_idx_type new_r = r2 - r1 + 1;
232  octave_idx_type new_c = c2 - c1 + 1;
233 
234  FloatComplexMatrix result (new_r, new_c);
235 
236  for (octave_idx_type j = 0; j < new_c; j++)
237  for (octave_idx_type i = 0; i < new_r; i++)
238  result.elem (i, j) = elem (r1+i, c1+j);
239 
240  return result;
241 }
242 
243 // extract row or column i.
244 
247 {
248  octave_idx_type r = rows ();
249  octave_idx_type c = cols ();
250  if (i < 0 || i >= r)
251  (*current_liboctave_error_handler) ("invalid row selection");
252 
254  if (r <= c || (r > c && i < c))
255  retval.elem (i) = elem (i, i);
256 
257  return retval;
258 }
259 
262 {
263  if (! s)
264  (*current_liboctave_error_handler) ("invalid row selection");
265 
266  char c = *s;
267  if (c == 'f' || c == 'F')
268  return row (static_cast<octave_idx_type>(0));
269  else if (c == 'l' || c == 'L')
270  return row (rows () - 1);
271  else
272  (*current_liboctave_error_handler) ("invalid row selection");
273 }
274 
277 {
278  octave_idx_type r = rows ();
279  octave_idx_type c = cols ();
280  if (i < 0 || i >= c)
281  (*current_liboctave_error_handler) ("invalid column selection");
282 
284  if (r >= c || (r < c && i < r))
285  retval.elem (i) = elem (i, i);
286 
287  return retval;
288 }
289 
292 {
293  if (! s)
294  (*current_liboctave_error_handler) ("invalid column selection");
295 
296  char c = *s;
297  if (c == 'f' || c == 'F')
298  return column (static_cast<octave_idx_type>(0));
299  else if (c == 'l' || c == 'L')
300  return column (cols () - 1);
301  else
302  (*current_liboctave_error_handler) ("invalid column selection");
303 }
304 
307 {
308  octave_idx_type info;
309  return inverse (info);
310 }
311 
314 {
315  octave_idx_type r = rows ();
316  octave_idx_type c = cols ();
317  if (r != c)
318  (*current_liboctave_error_handler) ("inverse requires square matrix");
319 
321 
322  info = 0;
323  for (octave_idx_type i = 0; i < length (); i++)
324  {
325  if (elem (i, i) == 0.0f)
326  {
327  info = -1;
328  return *this;
329  }
330  else
331  retval.elem (i, i) = 1.0f / elem (i, i);
332  }
333 
334  return retval;
335 }
336 
339 {
340  octave_idx_type r = rows ();
341  octave_idx_type c = cols ();
342  octave_idx_type len = length ();
343 
345 
346  for (octave_idx_type i = 0; i < len; i++)
347  {
348  float val = std::abs (elem (i, i));
349  if (val < tol || val == 0.0f)
350  retval.elem (i, i) = 0.0f;
351  else
352  retval.elem (i, i) = 1.0f / elem (i, i);
353  }
354 
355  return retval;
356 }
357 
358 bool
360 {
361  return mx_inline_all_real (length (), data ());
362 }
363 
364 // diagonal matrix by diagonal matrix -> diagonal matrix operations
365 
368 {
369  octave_idx_type r = rows ();
370  octave_idx_type c = cols ();
371 
372  octave_idx_type a_nr = a.rows ();
373  octave_idx_type a_nc = a.cols ();
374 
375  if (r != a_nr || c != a_nc)
376  octave::err_nonconformant ("operator +=", r, c, a_nr, a_nc);
377 
378  if (r == 0 || c == 0)
379  return *this;
380 
381  FloatComplex *d = fortran_vec (); // Ensures only 1 reference to my privates!
382 
383  mx_inline_add2 (length (), d, a.data ());
384  return *this;
385 }
386 
389 {
390  octave_idx_type a_nr = a.rows ();
391  octave_idx_type a_nc = a.cols ();
392 
393  octave_idx_type b_nr = b.rows ();
394  octave_idx_type b_nc = b.cols ();
395 
396  if (a_nc != b_nr)
397  octave::err_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
398 
400 
401  octave_idx_type len = c.length ();
402  octave_idx_type lenm = (len < a_nc ? len : a_nc);
403 
404  for (octave_idx_type i = 0; i < lenm; i++)
405  c.dgxelem (i) = a.dgelem (i) * b.dgelem (i);
406  for (octave_idx_type i = lenm; i < len; i++)
407  c.dgxelem (i) = 0.0f;
408 
409  return c;
410 }
411 
414 {
415  octave_idx_type a_nr = a.rows ();
416  octave_idx_type a_nc = a.cols ();
417 
418  octave_idx_type b_nr = b.rows ();
419  octave_idx_type b_nc = b.cols ();
420 
421  if (a_nc != b_nr)
422  octave::err_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
423 
424  if (a_nr == 0 || a_nc == 0 || b_nc == 0)
425  return FloatComplexDiagMatrix (a_nr, a_nc, 0.0);
426 
428 
429  octave_idx_type len = (a_nr < b_nc ? a_nr : b_nc);
430 
431  for (octave_idx_type i = 0; i < len; i++)
432  {
433  float a_element = a.elem (i, i);
434  FloatComplex b_element = b.elem (i, i);
435 
436  c.elem (i, i) = a_element * b_element;
437  }
438 
439  return c;
440 }
441 
444 {
445  octave_idx_type a_nr = a.rows ();
446  octave_idx_type a_nc = a.cols ();
447 
448  octave_idx_type b_nr = b.rows ();
449  octave_idx_type b_nc = b.cols ();
450 
451  if (a_nc != b_nr)
452  octave::err_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
453 
454  if (a_nr == 0 || a_nc == 0 || b_nc == 0)
455  return FloatComplexDiagMatrix (a_nr, a_nc, 0.0);
456 
458 
459  octave_idx_type len = (a_nr < b_nc ? a_nr : b_nc);
460 
461  for (octave_idx_type i = 0; i < len; i++)
462  {
463  FloatComplex a_element = a.elem (i, i);
464  FloatComplex b_element = b.elem (i, i);
465 
466  c.elem (i, i) = a_element * b_element;
467  }
468 
469  return c;
470 }
471 
472 // other operations
473 
476 {
477  FloatComplexDET det (1.0f);
478  if (rows () != cols ())
479  (*current_liboctave_error_handler) ("determinant requires square matrix");
480 
481  octave_idx_type len = length ();
482  for (octave_idx_type i = 0; i < len; i++)
483  det *= elem (i, i);
484 
485  return det;
486 }
487 
488 float
490 {
491  FloatColumnVector av = extract_diag (0).map<float> (std::abs);
492  float amx = av.max ();
493  float amn = av.min ();
494  return amx == 0 ? 0.0f : amn / amx;
495 }
496 
497 // i/o
498 
499 std::ostream&
500 operator << (std::ostream& os, const FloatComplexDiagMatrix& a)
501 {
502  FloatComplex ZERO (0.0);
503 // int field_width = os.precision () + 7;
504  for (octave_idx_type i = 0; i < a.rows (); i++)
505  {
506  for (octave_idx_type j = 0; j < a.cols (); j++)
507  {
508  if (i == j)
509  os << ' ' /* setw (field_width) */ << a.elem (i, i);
510  else
511  os << ' ' /* setw (field_width) */ << ZERO;
512  }
513  os << "\n";
514  }
515  return os;
516 }
float max(void) const
Definition: fColVector.cc:259
octave_idx_type rows(void) const
Definition: Array.h:404
void mx_inline_add2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:125
bool operator==(const FloatComplexDiagMatrix &a) const
Definition: fCDiagMatrix.cc:47
FloatComplexMatrix extract(octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
bool all_elements_are_real(void) const
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
const FloatComplex * fortran_vec(void) const
Definition: DiagArray2.h:169
FloatComplexDiagMatrix & fill(float val)
Definition: fCDiagMatrix.cc:62
octave_idx_type b_nr
Definition: sylvester.cc:76
static T abs(T x)
Definition: pr-output.cc:1696
FloatDiagMatrix abs(void) const
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
FloatComplex elem(octave_idx_type r, octave_idx_type c) const
Definition: DiagArray2.h:115
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 F77_DBLE * d
Template for two dimensional diagonal array with math operators.
Definition: MDiagArray2.h:32
octave_idx_type cols(void) const
Definition: Array.h:412
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 mx_inline_all_real(size_t n, const std::complex< T > *x)
Definition: mx-inlines.cc:308
FloatComplexColumnVector extract_diag(octave_idx_type k=0) const
Definition: fCDiagMatrix.h:142
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
bool operator!=(const FloatComplexDiagMatrix &a) const
Definition: fCDiagMatrix.cc:56
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
float rcond(void) const
FloatComplexDiagMatrix pseudo_inverse(float tol=0.0f) const
FloatComplexDiagMatrix operator*(const FloatComplexDiagMatrix &a, const FloatDiagMatrix &b)
With real return the complex result
Definition: data.cc:3260
FloatComplexDiagMatrix & operator+=(const FloatDiagMatrix &a)
FloatComplexDiagMatrix conj(const FloatComplexDiagMatrix &a)
float min(void) const
Definition: fColVector.cc:243
FloatComplexRowVector row(octave_idx_type i) const
FloatComplexDET determinant(void) const
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
FloatComplexDiagMatrix inverse(void) const
FloatComplexColumnVector column(octave_idx_type i) const
b
Definition: cellfun.cc:400
octave_idx_type columns(void) const
Definition: DiagArray2.h:89
for i
Definition: data.cc:5264
std::complex< float > FloatComplex
Definition: oct-cmplx.h:32
std::ostream & operator<<(std::ostream &os, const FloatComplexDiagMatrix &a)
bool mx_inline_equal(size_t n, const T1 *x, const T2 *y)
Definition: mx-inlines.cc:569
octave::stream os
Definition: file-io.cc:627
const FloatComplex * data(void) const
Definition: DiagArray2.h:167