GNU Octave  3.8.0
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
DiagArray2.h
Go to the documentation of this file.
1 // Template array classes
2 /*
3 
4 Copyright (C) 1996-2013 John W. Eaton
5 Copyright (C) 2008-2009 Jaroslav Hajek
6 Copyright (C) 2010 VZLU Prague
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 the
12 Free Software Foundation; either version 3 of the License, or (at your
13 option) any later version.
14 
15 Octave is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 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 <http://www.gnu.org/licenses/>.
23 
24 */
25 
26 #if !defined (octave_DiagArray2_h)
27 #define octave_DiagArray2_h 1
28 
29 #include <cassert>
30 #include <cstdlib>
31 
32 #include "Array.h"
33 
34 // Array<T> is inherited privately so that some methods, like index, don't
35 // produce unexpected results.
36 
37 template <class T>
38 class
39 DiagArray2 : protected Array<T>
40 {
41 protected:
43 
44 public:
45 
46  using typename Array<T>::element_type;
47 
48  DiagArray2 (void)
49  : Array<T> (), d1 (0), d2 (0) { }
50 
52  : Array<T> (dim_vector (std::min (r, c), 1)), d1 (r), d2 (c) { }
53 
55  : Array<T> (dim_vector (std::min (r, c), 1), val), d1 (r), d2 (c) { }
56 
57  explicit DiagArray2 (const Array<T>& a)
58  : Array<T> (a.as_column ()), d1 (a.numel ()), d2 (a.numel ()) { }
59 
61 
63  : Array<T> (a), d1 (a.d1), d2 (a.d2) { }
64 
65  template <class U>
67  : Array<T> (a.extract_diag ()), d1 (a.dim1 ()), d2 (a.dim2 ()) { }
68 
69  ~DiagArray2 (void) { }
70 
72  {
73  if (this != &a)
74  {
76  d1 = a.d1;
77  d2 = a.d2;
78  }
79 
80  return *this;
81  }
82 
83  octave_idx_type dim1 (void) const { return d1; }
84  octave_idx_type dim2 (void) const { return d2; }
85 
86  octave_idx_type rows (void) const { return dim1 (); }
87  octave_idx_type cols (void) const { return dim2 (); }
88  octave_idx_type columns (void) const { return dim2 (); }
89 
90  octave_idx_type diag_length (void) const { return Array<T>::length (); }
91  // FIXME: a dangerous ambiguity?
92  octave_idx_type length (void) const { return Array<T>::length (); }
93  octave_idx_type nelem (void) const { return dim1 () * dim2 (); }
94  octave_idx_type numel (void) const { return nelem (); }
95 
96  size_t byte_size (void) const { return Array<T>::byte_size (); }
97 
98  dim_vector dims (void) const { return dim_vector (d1, d2); }
99 
100  Array<T> diag (octave_idx_type k = 0) const GCC_ATTR_DEPRECATED;
101  Array<T> extract_diag (octave_idx_type k = 0) const;
102  DiagArray2<T> build_diag_matrix () const
103  {
104  return DiagArray2<T> (array_value ());
105  }
106 
107  // Warning: the non-const two-index versions will silently ignore assignments
108  // to off-diagonal elements.
109 
111  {
112  return (r == c) ? Array<T>::elem (r) : T (0);
113  }
114 
116  {
117  static T zero (0);
118  return (r == c) ? Array<T>::elem (r) : zero;
119  }
120 
121  T dgelem (octave_idx_type i) const
122  { return Array<T>::elem (i); }
123 
124  T& dgelem (octave_idx_type i)
125  { return Array<T>::elem (i); }
126 
127  T checkelem (octave_idx_type r, octave_idx_type c) const
128  {
129  return check_idx (r, c) ? elem (r, c) : T (0);
130  }
131 
132  T operator () (octave_idx_type r, octave_idx_type c) const
133  {
134 #if defined (BOUNDS_CHECKING)
135  return checkelem (r, c);
136 #else
137  return elem (r, c);
138 #endif
139  }
140 
141  T& checkelem (octave_idx_type r, octave_idx_type c)
142  {
143  static T zero (0);
144  return check_idx (r, c) ? elem (r, c) : zero;
145  }
146 
147  T& operator () (octave_idx_type r, octave_idx_type c)
148  {
149 #if defined (BOUNDS_CHECKING)
150  return checkelem (r, c);
151 #else
152  return elem (r, c);
153 #endif
154  }
155 
156  // No checking.
157 
158  T xelem (octave_idx_type r, octave_idx_type c) const
159  {
160  return (r == c) ? Array<T>::xelem (r) : T (0);
161  }
162 
163  T& dgxelem (octave_idx_type i)
164  { return Array<T>::xelem (i); }
165 
166  T dgxelem (octave_idx_type i) const
167  { return Array<T>::xelem (i); }
168 
169  void resize (octave_idx_type n, octave_idx_type m, const T& rfv);
170  void resize (octave_idx_type n, octave_idx_type m)
171  {
172  resize (n, m, Array<T>::resize_fill_value ());
173  }
174 
175  DiagArray2<T> transpose (void) const;
176  DiagArray2<T> hermitian (T (*fcn) (const T&) = 0) const;
177 
178  Array<T> array_value (void) const;
179 
180  const T *data (void) const { return Array<T>::data (); }
181 
182  const T *fortran_vec (void) const { return Array<T>::fortran_vec (); }
183 
184  T *fortran_vec (void) { return Array<T>::fortran_vec (); }
185 
186  void print_info (std::ostream& os, const std::string& prefix) const
187  { Array<T>::print_info (os, prefix); }
188 
189 private:
190 
191  bool check_idx (octave_idx_type r, octave_idx_type c) const;
192 };
193 
194 #endif