GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CDiagMatrix.cc
Go to the documentation of this file.
1 // DiagMatrix manipulations.
2 /*
3 
4 Copyright (C) 1994-2017 John W. Eaton
5 Copyright (C) 2009 VZLU Prague
6 
7 This file is part of Octave.
8 
9 Octave is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Octave; see the file COPYING. If not, see
21 <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 #if defined (HAVE_CONFIG_H)
26 # include "config.h"
27 #endif
28 
29 #include <iostream>
30 
31 #include "Array-util.h"
32 #include "lo-error.h"
33 #include "lo-ieee.h"
34 #include "mx-base.h"
35 #include "mx-inlines.cc"
36 #include "oct-cmplx.h"
37 
38 // Complex Diagonal Matrix class
39 
41  : MDiagArray2<Complex> (a.rows (), a.cols ())
42 {
43  for (octave_idx_type i = 0; i < length (); i++)
44  elem (i, i) = a.elem (i, i);
45 }
46 
47 bool
49 {
50  if (rows () != a.rows () || cols () != a.cols ())
51  return 0;
52 
53  return mx_inline_equal (length (), data (), a.data ());
54 }
55 
56 bool
58 {
59  return !(*this == a);
60 }
61 
64 {
65  for (octave_idx_type i = 0; i < length (); i++)
66  elem (i, i) = val;
67  return *this;
68 }
69 
72 {
73  for (octave_idx_type i = 0; i < length (); i++)
74  elem (i, i) = val;
75  return *this;
76 }
77 
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 {
171  octave_idx_type a_len = a.numel ();
172  if (beg < 0 || beg + a_len >= length ())
173  (*current_liboctave_error_handler) ("range error for fill");
174 
175  for (octave_idx_type i = 0; i < a_len; i++)
176  elem (i+beg, i+beg) = a.elem (i);
177 
178  return *this;
179 }
180 
183 {
184  octave_idx_type a_len = a.numel ();
185  if (beg < 0 || beg + a_len >= length ())
186  (*current_liboctave_error_handler) ("range error for fill");
187 
188  for (octave_idx_type i = 0; i < a_len; i++)
189  elem (i+beg, i+beg) = a.elem (i);
190 
191  return *this;
192 }
193 
196 {
197  octave_idx_type a_len = a.numel ();
198  if (beg < 0 || beg + a_len >= length ())
199  (*current_liboctave_error_handler) ("range error for fill");
200 
201  for (octave_idx_type i = 0; i < a_len; i++)
202  elem (i+beg, i+beg) = a.elem (i);
203 
204  return *this;
205 }
206 
209 {
210  return DiagMatrix (extract_diag ().abs (), rows (), columns ());
211 }
212 
215 {
216  return ComplexDiagMatrix (conj (a.extract_diag ()), a.rows (), a.columns ());
217 }
218 
219 // resize is the destructive analog for this one
220 
223  octave_idx_type r2, octave_idx_type c2) const
224 {
225  if (r1 > r2) { std::swap (r1, r2); }
226  if (c1 > c2) { std::swap (c1, c2); }
227 
228  octave_idx_type new_r = r2 - r1 + 1;
229  octave_idx_type new_c = c2 - c1 + 1;
230 
231  ComplexMatrix result (new_r, new_c);
232 
233  for (octave_idx_type j = 0; j < new_c; j++)
234  for (octave_idx_type i = 0; i < new_r; i++)
235  result.elem (i, j) = elem (r1+i, c1+j);
236 
237  return result;
238 }
239 
240 // extract row or column i.
241 
244 {
245  octave_idx_type r = rows ();
246  octave_idx_type c = cols ();
247  if (i < 0 || i >= r)
248  (*current_liboctave_error_handler) ("invalid row selection");
249 
250  ComplexRowVector retval (c, 0.0);
251  if (r <= c || (r > c && i < c))
252  retval.elem (i) = elem (i, i);
253 
254  return retval;
255 }
256 
259 {
260  if (! s)
261  (*current_liboctave_error_handler) ("invalid row selection");
262 
263  char c = *s;
264  if (c == 'f' || c == 'F')
265  return row (static_cast<octave_idx_type>(0));
266  else if (c == 'l' || c == 'L')
267  return row (rows () - 1);
268  else
269  (*current_liboctave_error_handler) ("invalid row selection");
270 }
271 
274 {
275  octave_idx_type r = rows ();
276  octave_idx_type c = cols ();
277  if (i < 0 || i >= c)
278  (*current_liboctave_error_handler) ("invalid column selection");
279 
280  ComplexColumnVector retval (r, 0.0);
281  if (r >= c || (r < c && i < r))
282  retval.elem (i) = elem (i, i);
283 
284  return retval;
285 }
286 
289 {
290  if (! s)
291  (*current_liboctave_error_handler) ("invalid column selection");
292 
293  char c = *s;
294  if (c == 'f' || c == 'F')
295  return column (static_cast<octave_idx_type>(0));
296  else if (c == 'l' || c == 'L')
297  return column (cols () - 1);
298  else
299  (*current_liboctave_error_handler) ("invalid column selection");
300 }
301 
304 {
305  octave_idx_type info;
306  return inverse (info);
307 }
308 
311 {
312  octave_idx_type r = rows ();
313  octave_idx_type c = cols ();
314  if (r != c)
315  (*current_liboctave_error_handler) ("inverse requires square matrix");
316 
317  ComplexDiagMatrix retval (r, c);
318 
319  info = 0;
320  for (octave_idx_type i = 0; i < length (); i++)
321  {
322  if (elem (i, i) == 0.0)
323  {
324  info = -1;
325  return *this;
326  }
327  else
328  retval.elem (i, i) = 1.0 / elem (i, i);
329  }
330 
331  return retval;
332 }
333 
336 {
337  octave_idx_type r = rows ();
338  octave_idx_type c = cols ();
339  octave_idx_type len = length ();
340 
341  ComplexDiagMatrix retval (c, r);
342 
343  for (octave_idx_type i = 0; i < len; i++)
344  {
345  double val = std::abs (elem (i, i));
346  if (val < tol || val == 0.0)
347  retval.elem (i, i) = 0.0;
348  else
349  retval.elem (i, i) = 1.0 / elem (i, i);
350  }
351 
352  return retval;
353 }
354 
355 bool
357 {
358  return mx_inline_all_real (length (), data ());
359 }
360 
361 // diagonal matrix by diagonal matrix -> diagonal matrix operations
362 
365 {
366  octave_idx_type r = rows ();
367  octave_idx_type c = cols ();
368 
369  octave_idx_type a_nr = a.rows ();
370  octave_idx_type a_nc = a.cols ();
371 
372  if (r != a_nr || c != a_nc)
373  octave::err_nonconformant ("operator +=", r, c, a_nr, a_nc);
374 
375  if (r == 0 || c == 0)
376  return *this;
377 
378  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
379 
380  mx_inline_add2 (length (), d, a.data ());
381  return *this;
382 }
383 
386 {
387  octave_idx_type a_nr = a.rows ();
388  octave_idx_type a_nc = a.cols ();
389 
390  octave_idx_type b_nr = b.rows ();
391  octave_idx_type b_nc = b.cols ();
392 
393  if (a_nc != b_nr)
394  octave::err_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
395 
396  ComplexDiagMatrix c (a_nr, b_nc);
397 
398  octave_idx_type len = c.length ();
399  octave_idx_type lenm = len < a_nc ? len : a_nc;
400 
401  for (octave_idx_type i = 0; i < lenm; i++)
402  c.dgxelem (i) = a.dgelem (i) * b.dgelem (i);
403  for (octave_idx_type i = lenm; i < len; i++)
404  c.dgxelem (i) = 0.0;
405 
406  return c;
407 }
408 
411 {
412  octave_idx_type a_nr = a.rows ();
413  octave_idx_type a_nc = a.cols ();
414 
415  octave_idx_type b_nr = b.rows ();
416  octave_idx_type b_nc = b.cols ();
417 
418  if (a_nc != b_nr)
419  octave::err_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
420 
421  if (a_nr == 0 || a_nc == 0 || b_nc == 0)
422  return ComplexDiagMatrix (a_nr, a_nc, 0.0);
423 
424  ComplexDiagMatrix c (a_nr, b_nc);
425 
426  octave_idx_type len = a_nr < b_nc ? a_nr : b_nc;
427 
428  for (octave_idx_type i = 0; i < len; i++)
429  {
430  double a_element = a.elem (i, i);
431  Complex b_element = b.elem (i, i);
432 
433  c.elem (i, i) = a_element * b_element;
434  }
435 
436  return c;
437 }
438 
441 {
442  octave_idx_type a_nr = a.rows ();
443  octave_idx_type a_nc = a.cols ();
444 
445  octave_idx_type b_nr = b.rows ();
446  octave_idx_type b_nc = b.cols ();
447 
448  if (a_nc != b_nr)
449  octave::err_nonconformant ("operator *", a_nr, a_nc, b_nr, b_nc);
450 
451  if (a_nr == 0 || a_nc == 0 || b_nc == 0)
452  return ComplexDiagMatrix (a_nr, a_nc, 0.0);
453 
454  ComplexDiagMatrix c (a_nr, b_nc);
455 
456  octave_idx_type len = a_nr < b_nc ? a_nr : b_nc;
457 
458  for (octave_idx_type i = 0; i < len; i++)
459  {
460  Complex a_element = a.elem (i, i);
461  Complex b_element = b.elem (i, i);
462 
463  c.elem (i, i) = a_element * b_element;
464  }
465 
466  return c;
467 }
468 
469 // other operations
470 
473 {
474  ComplexDET det (1.0);
475  if (rows () != cols ())
476  (*current_liboctave_error_handler) ("determinant requires square matrix");
477 
478  octave_idx_type len = length ();
479  for (octave_idx_type i = 0; i < len; i++)
480  det *= elem (i, i);
481 
482  return det;
483 }
484 
485 double
487 {
488  ColumnVector av = extract_diag (0).map<double> (std::abs);
489  double amx = av.max ();
490  double amn = av.min ();
491  return amx == 0 ? 0.0 : amn / amx;
492 }
493 
494 // i/o
495 
496 std::ostream&
497 operator << (std::ostream& os, const ComplexDiagMatrix& a)
498 {
499  Complex ZERO (0.0);
500 // int field_width = os.precision () + 7;
501  for (octave_idx_type i = 0; i < a.rows (); i++)
502  {
503  for (octave_idx_type j = 0; j < a.cols (); j++)
504  {
505  if (i == j)
506  os << " " /* setw (field_width) */ << a.elem (i, i);
507  else
508  os << " " /* setw (field_width) */ << ZERO;
509  }
510  os << "\n";
511  }
512  return os;
513 }
void mx_inline_add2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:127
bool operator!=(const ComplexDiagMatrix &a) const
Definition: CDiagMatrix.cc:57
const Complex * fortran_vec(void) const
Definition: DiagArray2.h:178
Complex elem(octave_idx_type r, octave_idx_type c) const
Definition: DiagArray2.h:114
std::ostream & operator<<(std::ostream &os, const ComplexDiagMatrix &a)
Definition: CDiagMatrix.cc:497
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:5068
ComplexDiagMatrix conj(const ComplexDiagMatrix &a)
Definition: CDiagMatrix.cc:214
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
Definition: lo-error.c:38
ComplexColumnVector extract_diag(octave_idx_type k=0) const
Definition: CDiagMatrix.h:132
ComplexDiagMatrix inverse(void) const
Definition: CDiagMatrix.cc:303
ComplexMatrix extract(octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const
Definition: CDiagMatrix.cc:222
octave_idx_type b_nr
Definition: sylvester.cc:74
octave_idx_type rows(void) const
Definition: DiagArray2.h:88
const Complex * data(void) const
Definition: DiagArray2.h:176
ComplexRowVector row(octave_idx_type i) const
Definition: CDiagMatrix.cc:243
T & elem(octave_idx_type n)
Definition: Array.h:482
ComplexDiagMatrix pseudo_inverse(double tol=0.0) const
Definition: CDiagMatrix.cc:335
bool operator==(const ComplexDiagMatrix &a) const
Definition: CDiagMatrix.cc:48
s
Definition: file-io.cc:2682
octave_idx_type a_nc
Definition: sylvester.cc:72
octave_idx_type rows(void) const
Definition: Array.h:401
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &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 F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
ComplexDiagMatrix operator*(const ComplexDiagMatrix &a, const DiagMatrix &b)
Definition: CDiagMatrix.cc:385
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:398
bool swap
Definition: load-save.cc:725
bool mx_inline_all_real(size_t n, const std::complex< T > *x)
Definition: mx-inlines.cc:295
T dgelem(octave_idx_type i) const
Definition: DiagArray2.h:121
octave_idx_type a_nr
Definition: sylvester.cc:71
Array< U > map(F fcn) const
Apply function fcn to each element of the Array.
Definition: Array.h:760
ComplexDiagMatrix & operator+=(const DiagMatrix &a)
Definition: CDiagMatrix.cc:364
Definition: DET.h:33
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
octave_value retval
Definition: data.cc:6294
Template for two dimensional diagonal array with math operators.
Definition: MDiagArray2.h:33
ComplexDiagMatrix(void)
Definition: CDiagMatrix.h:44
T & dgxelem(octave_idx_type i)
Definition: DiagArray2.h:159
the sparsity preserving column transformation such that that defines the pivoting threshold can be given in which case it defines the c
Definition: lu.cc:138
With real return the complex result
Definition: data.cc:3375
double rcond(void) const
Definition: CDiagMatrix.cc:486
ComplexDET determinant(void) const
Definition: CDiagMatrix.cc:472
octave_idx_type cols(void) const
Definition: DiagArray2.h:89
double min(void) const
Definition: dColVector.cc:244
double max(void) const
Definition: dColVector.cc:260
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
octave_idx_type b_nc
Definition: sylvester.cc:75
OCTAVE_EXPORT octave_value_list return the value of the option it must match the dimension of the state and the relative tolerance must also be a vector of the same length tem it must match the dimension of the state and the absolute tolerance must also be a vector of the same length The local error test applied at each integration step is xample roup abs(local error in x(i))<
ComplexDiagMatrix & fill(double val)
Definition: CDiagMatrix.cc:63
octave_idx_type columns(void) const
Definition: DiagArray2.h:90
b
Definition: cellfun.cc:398
std::complex< double > Complex
Definition: oct-cmplx.h:31
bool mx_inline_equal(size_t n, const T1 *x, const T2 *y)
Definition: mx-inlines.cc:532
octave_idx_type cols(void) const
Definition: Array.h:409
bool all_elements_are_real(void) const
Definition: CDiagMatrix.cc:356
ComplexColumnVector column(octave_idx_type i) const
Definition: CDiagMatrix.cc:273
octave_idx_type length(void) const
Definition: DiagArray2.h:94
DiagMatrix abs(void) const
Definition: CDiagMatrix.cc:208