00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #if !defined (octave_DiagArray2_h)
00027 #define octave_DiagArray2_h 1
00028
00029 #include <cassert>
00030 #include <cstdlib>
00031
00032 #include "Array.h"
00033 #include "Array2.h"
00034 #include "lo-error.h"
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 template <class T>
00052 class
00053 DiagArray2 : protected Array<T>
00054 {
00055 private:
00056
00057 T get (octave_idx_type i) { return Array<T>::xelem (i); }
00058
00059 void set (const T& val, octave_idx_type i) { Array<T>::xelem (i) = val; }
00060
00061 class Proxy
00062 {
00063 public:
00064
00065 Proxy (DiagArray2<T> *ref, octave_idx_type r, octave_idx_type c)
00066 : i (r), j (c), object (ref) { }
00067
00068 const Proxy& operator = (const T& val) const;
00069
00070 operator T () const;
00071
00072 private:
00073
00074
00075
00076
00077
00078 T *operator& () const { assert (0); return 0; }
00079
00080 octave_idx_type i;
00081 octave_idx_type j;
00082
00083 DiagArray2<T> *object;
00084
00085 };
00086
00087 friend class Proxy;
00088
00089 protected:
00090 octave_idx_type d1, d2;
00091
00092 DiagArray2 (T *d, octave_idx_type r, octave_idx_type c)
00093 : Array<T> (d, std::min (r, c)), d1 (r), d2 (c) { }
00094
00095 public:
00096
00097 using Array<T>::element_type;
00098
00099 DiagArray2 (void)
00100 : Array<T> (), d1 (0), d2 (0) { }
00101
00102 DiagArray2 (octave_idx_type r, octave_idx_type c)
00103 : Array<T> (std::min (r, c)), d1 (r), d2 (c) { }
00104
00105 DiagArray2 (octave_idx_type r, octave_idx_type c, const T& val)
00106 : Array<T> (std::min (r, c), val), d1 (r), d2 (c) { }
00107
00108 DiagArray2 (const dim_vector& dv)
00109 : Array<T> (std::min (dv(0), dv(1))), d1 (dv(0)), d2 (dv(0))
00110 {
00111 if (dv.length () != 2)
00112 (*current_liboctave_error_handler) ("too many dimensions");
00113 }
00114
00115 DiagArray2 (const Array<T>& a)
00116 : Array<T> (a), d1 (a.numel ()), d2 (a.numel ()) { }
00117
00118 DiagArray2 (const DiagArray2<T>& a)
00119 : Array<T> (a), d1 (a.d1), d2 (a.d2) { }
00120
00121 template <class U>
00122 DiagArray2 (const DiagArray2<U>& a)
00123 : Array<T> (a.diag ()), d1 (a.dim1 ()), d2 (a.dim2 ()) { }
00124
00125 ~DiagArray2 (void) { }
00126
00127 DiagArray2<T>& operator = (const DiagArray2<T>& a)
00128 {
00129 if (this != &a)
00130 {
00131 Array<T>::operator = (a);
00132 d1 = a.d1;
00133 d2 = a.d2;
00134 }
00135
00136 return *this;
00137 }
00138
00139 octave_idx_type dim1 (void) const { return d1; }
00140 octave_idx_type dim2 (void) const { return d2; }
00141
00142 octave_idx_type rows (void) const { return dim1 (); }
00143 octave_idx_type cols (void) const { return dim2 (); }
00144 octave_idx_type columns (void) const { return dim2 (); }
00145
00146 octave_idx_type diag_length (void) const { return Array<T>::length (); }
00147
00148 octave_idx_type length (void) const { return Array<T>::length (); }
00149 octave_idx_type nelem (void) const { return dim1 () * dim2 (); }
00150 octave_idx_type numel (void) const { return nelem (); }
00151
00152 size_t byte_size (void) const { return length () * sizeof (T); }
00153
00154 dim_vector dims (void) const { return dim_vector (d1, d2); }
00155
00156 Array<T> diag (octave_idx_type k = 0) const;
00157
00158
00159
00160
00161 T elem (octave_idx_type r, octave_idx_type c) const
00162 {
00163 return (r == c) ? Array<T>::elem (r) : T (0);
00164 }
00165
00166 T& elem (octave_idx_type r, octave_idx_type c)
00167 {
00168 static T zero (0);
00169 return (r == c) ? Array<T>::elem (r) : zero;
00170 }
00171
00172 T dgelem (octave_idx_type i) const
00173 { return Array<T>::elem (i); }
00174
00175 T& dgelem (octave_idx_type i)
00176 { return Array<T>::elem (i); }
00177
00178 T checkelem (octave_idx_type r, octave_idx_type c) const;
00179 Proxy checkelem (octave_idx_type r, octave_idx_type c);
00180
00181 T operator () (octave_idx_type r, octave_idx_type c) const
00182 {
00183 #if defined (BOUNDS_CHECKING)
00184 return checkelem (r, c);
00185 #else
00186 return elem (r, c);
00187 #endif
00188 }
00189
00190
00191 #if defined (BOUNDS_CHECKING)
00192 Proxy operator () (octave_idx_type r, octave_idx_type c)
00193 {
00194 return checkelem (r, c);
00195 }
00196 #else
00197 T& operator () (octave_idx_type r, octave_idx_type c)
00198 {
00199 return elem (r, c);
00200 }
00201 #endif
00202
00203
00204
00205 T xelem (octave_idx_type r, octave_idx_type c) const
00206 {
00207 return (r == c) ? Array<T>::xelem (r) : T (0);
00208 }
00209
00210 T& dgxelem (octave_idx_type i)
00211 { return Array<T>::xelem (i); }
00212
00213 T dgxelem (octave_idx_type i) const
00214 { return Array<T>::xelem (i); }
00215
00216 void resize (octave_idx_type n, octave_idx_type m);
00217 void resize_fill (octave_idx_type n, octave_idx_type m, const T& val);
00218
00219 DiagArray2<T> transpose (void) const;
00220 DiagArray2<T> hermitian (T (*fcn) (const T&) = 0) const;
00221
00222 operator Array2<T> (void) const;
00223
00224 const T *data (void) const { return Array<T>::data (); }
00225
00226 const T *fortran_vec (void) const { return Array<T>::fortran_vec (); }
00227
00228 T *fortran_vec (void) { return Array<T>::fortran_vec (); }
00229
00230 void print_info (std::ostream& os, const std::string& prefix) const
00231 { Array<T>::print_info (os, prefix); }
00232 };
00233
00234 #endif
00235
00236
00237
00238
00239
00240