DiagArray2.h

Go to the documentation of this file.
00001 // Template array classes
00002 /*
00003 
00004 Copyright (C) 1996-2012 John W. Eaton
00005 Copyright (C) 2008-2009 Jaroslav Hajek
00006 Copyright (C) 2010 VZLU Prague
00007 
00008 This file is part of Octave.
00009 
00010 Octave is free software; you can redistribute it and/or modify it
00011 under the terms of the GNU General Public License as published by the
00012 Free Software Foundation; either version 3 of the License, or (at your
00013 option) any later version.
00014 
00015 Octave is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00017 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00018 for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with Octave; see the file COPYING.  If not, see
00022 <http://www.gnu.org/licenses/>.
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 
00034 // Array<T> is inherited privately so that some methods, like index, don't
00035 // produce unexpected results.
00036 
00037 template <class T>
00038 class
00039 DiagArray2 : protected Array<T>
00040 {
00041 protected:
00042   octave_idx_type d1, d2;
00043 
00044 public:
00045 
00046   using typename Array<T>::element_type;
00047 
00048   DiagArray2 (void)
00049     : Array<T> (), d1 (0), d2 (0) { }
00050 
00051   DiagArray2 (octave_idx_type r, octave_idx_type c)
00052     : Array<T> (dim_vector (std::min (r, c), 1)), d1 (r), d2 (c) { }
00053 
00054   DiagArray2 (octave_idx_type r, octave_idx_type c, const T& val)
00055     : Array<T> (dim_vector (std::min (r, c), 1), val), d1 (r), d2 (c) { }
00056 
00057   explicit DiagArray2 (const Array<T>& a)
00058     : Array<T> (a.as_column ()), d1 (a.numel ()), d2 (a.numel ()) { }
00059 
00060   DiagArray2 (const Array<T>& a, octave_idx_type r, octave_idx_type c);
00061 
00062   DiagArray2 (const DiagArray2<T>& a)
00063     : Array<T> (a), d1 (a.d1), d2 (a.d2) { }
00064 
00065   template <class U>
00066   DiagArray2 (const DiagArray2<U>& a)
00067     : Array<T> (a.extract_diag ()), d1 (a.dim1 ()), d2 (a.dim2 ()) { }
00068 
00069   ~DiagArray2 (void) { }
00070 
00071   DiagArray2<T>& operator = (const DiagArray2<T>& a)
00072     {
00073       if (this != &a)
00074         {
00075           Array<T>::operator = (a);
00076           d1 = a.d1;
00077           d2 = a.d2;
00078         }
00079 
00080       return *this;
00081     }
00082 
00083   octave_idx_type dim1 (void) const { return d1; }
00084   octave_idx_type dim2 (void) const { return d2; }
00085 
00086   octave_idx_type rows (void) const { return dim1 (); }
00087   octave_idx_type cols (void) const { return dim2 (); }
00088   octave_idx_type columns (void) const { return dim2 (); }
00089 
00090   octave_idx_type diag_length (void) const { return Array<T>::length (); }
00091   // FIXME: a dangerous ambiguity?
00092   octave_idx_type length (void) const { return Array<T>::length (); }
00093   octave_idx_type nelem (void) const { return dim1 () * dim2 (); }
00094   octave_idx_type numel (void) const { return nelem (); }
00095 
00096   size_t byte_size (void) const { return Array<T>::byte_size (); }
00097 
00098   dim_vector dims (void) const { return dim_vector (d1, d2); }
00099 
00100   Array<T> diag (octave_idx_type k = 0) const;
00101   Array<T> extract_diag (octave_idx_type k = 0) const;
00102   DiagArray2<T> build_diag_matrix () const
00103   {
00104     return DiagArray2<T> (array_value ());
00105   }
00106 
00107   // Warning: the non-const two-index versions will silently ignore assignments
00108   // to off-diagonal elements.
00109 
00110   T elem (octave_idx_type r, octave_idx_type c) const
00111     {
00112       return (r == c) ? Array<T>::elem (r) : T (0);
00113     }
00114 
00115   T& elem (octave_idx_type r, octave_idx_type c)
00116     {
00117       static T zero (0);
00118       return (r == c) ? Array<T>::elem (r) : zero;
00119     }
00120 
00121   T dgelem (octave_idx_type i) const
00122     { return Array<T>::elem (i); }
00123 
00124   T& dgelem (octave_idx_type i)
00125     { return Array<T>::elem (i); }
00126 
00127   T checkelem (octave_idx_type r, octave_idx_type c) const
00128     {
00129       return check_idx (r, c) ? elem (r, c) : T (0);
00130     }
00131 
00132   T operator () (octave_idx_type r, octave_idx_type c) const
00133     {
00134 #if defined (BOUNDS_CHECKING)
00135       checkelem (r, c);
00136 #else
00137       return elem (r, c);
00138 #endif
00139     }
00140 
00141   T& checkelem (octave_idx_type r, octave_idx_type c)
00142     {
00143       static T zero (0);
00144       return check_idx (r, c) ? elem (r, c) : zero;
00145     }
00146 
00147   T& operator () (octave_idx_type r, octave_idx_type c)
00148     {
00149 #if defined (BOUNDS_CHECKING)
00150       return checkelem (r, c);
00151 #else
00152       return elem (r, c);
00153 #endif
00154     }
00155 
00156   // No checking.
00157 
00158   T xelem (octave_idx_type r, octave_idx_type c) const
00159     {
00160       return (r == c) ? Array<T>::xelem (r) : T (0);
00161     }
00162 
00163   T& dgxelem (octave_idx_type i)
00164     { return Array<T>::xelem (i); }
00165 
00166   T dgxelem (octave_idx_type i) const
00167     { return Array<T>::xelem (i); }
00168 
00169   void resize (octave_idx_type n, octave_idx_type m,
00170                const T& rfv = Array<T>::resize_fill_value ());
00171 
00172   DiagArray2<T> transpose (void) const;
00173   DiagArray2<T> hermitian (T (*fcn) (const T&) = 0) const;
00174 
00175   Array<T> array_value (void) const;
00176 
00177   const T *data (void) const { return Array<T>::data (); }
00178 
00179   const T *fortran_vec (void) const { return Array<T>::fortran_vec (); }
00180 
00181   T *fortran_vec (void) { return Array<T>::fortran_vec (); }
00182 
00183   void print_info (std::ostream& os, const std::string& prefix) const
00184     { Array<T>::print_info (os, prefix); }
00185 
00186 private:
00187 
00188   bool check_idx (octave_idx_type r, octave_idx_type c) const;
00189 };
00190 
00191 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines