1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 1998-2021 The Octave Project Developers 4 // 5 // See the file COPYRIGHT.md in the top-level directory of this 6 // distribution or <https://octave.org/copyright/>. 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 12 // the Free Software Foundation, either version 3 of the License, or 13 // (at your option) any later version. 14 // 15 // Octave is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License 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 // <https://www.gnu.org/licenses/>. 23 // 24 //////////////////////////////////////////////////////////////////////// 25 26 #if ! defined (octave_ov_base_mat_h) 27 #define octave_ov_base_mat_h 1 28 29 #include "octave-config.h" 30 31 #include <cstdlib> 32 33 #include <iosfwd> 34 #include <string> 35 36 #include "mx-base.h" 37 #include "str-vec.h" 38 #include "MatrixType.h" 39 40 #include "error.h" 41 #include "ovl.h" 42 #include "ov-base.h" 43 #include "ov-typeinfo.h" 44 45 // Real matrix values. 46 47 template <typename MT> 48 class 49 octave_base_matrix : public octave_base_value 50 { 51 public: 52 octave_base_matrix(void)53 octave_base_matrix (void) 54 : octave_base_value (), matrix (), typ (), idx_cache () { } 55 56 octave_base_matrix (const MT& m, const MatrixType& t = MatrixType ()) octave_base_value()57 : octave_base_value (), matrix (m), 58 typ (t.is_known () ? new MatrixType (t) : nullptr), idx_cache () 59 { 60 if (matrix.ndims () == 0) 61 matrix.resize (dim_vector (0, 0)); 62 } 63 octave_base_matrix(const octave_base_matrix & m)64 octave_base_matrix (const octave_base_matrix& m) 65 : octave_base_value (), matrix (m.matrix), 66 typ (m.typ ? new MatrixType (*m.typ) : nullptr), 67 idx_cache (m.idx_cache ? new idx_vector (*m.idx_cache) : nullptr) 68 { } 69 ~octave_base_matrix(void)70 ~octave_base_matrix (void) { clear_cached_info (); } 71 byte_size(void)72 std::size_t byte_size (void) const { return matrix.byte_size (); } 73 squeeze(void)74 octave_value squeeze (void) const { return MT (matrix.squeeze ()); } 75 full_value(void)76 octave_value full_value (void) const { return matrix; } 77 maybe_economize(void)78 void maybe_economize (void) { matrix.maybe_economize (); } 79 80 // We don't need to override all three forms of subsref. The using 81 // declaration will avoid warnings about partially-overloaded virtual 82 // functions. 83 using octave_base_value::subsref; 84 85 octave_value subsref (const std::string& type, 86 const std::list<octave_value_list>& idx); 87 subsref(const std::string & type,const std::list<octave_value_list> & idx,int)88 octave_value_list subsref (const std::string& type, 89 const std::list<octave_value_list>& idx, int) 90 { return subsref (type, idx); } 91 92 octave_value subsasgn (const std::string& type, 93 const std::list<octave_value_list>& idx, 94 const octave_value& rhs); 95 96 octave_value do_index_op (const octave_value_list& idx, 97 bool resize_ok = false); 98 99 // FIXME: should we import the functions from the base class and 100 // overload them here, or should we use a different name so we don't 101 // have to do this? Without the using declaration or a name change, 102 // the base class functions will be hidden. That may be OK, but it 103 // can also cause some confusion. 104 using octave_base_value::assign; 105 106 void assign (const octave_value_list& idx, const MT& rhs); 107 108 void assign (const octave_value_list& idx, typename MT::element_type rhs); 109 110 void delete_elements (const octave_value_list& idx); 111 dims(void)112 dim_vector dims (void) const { return matrix.dims (); } 113 numel(void)114 octave_idx_type numel (void) const { return matrix.numel (); } 115 ndims(void)116 int ndims (void) const { return matrix.ndims (); } 117 nnz(void)118 octave_idx_type nnz (void) const { return matrix.nnz (); } 119 reshape(const dim_vector & new_dims)120 octave_value reshape (const dim_vector& new_dims) const 121 { return MT (matrix.reshape (new_dims)); } 122 123 octave_value permute (const Array<int>& vec, bool inv = false) const 124 { return MT (matrix.permute (vec, inv)); } 125 126 octave_value resize (const dim_vector& dv, bool fill = false) const; 127 128 octave_value all (int dim = 0) const { return matrix.all (dim); } 129 octave_value any (int dim = 0) const { return matrix.any (dim); } 130 matrix_type(void)131 MatrixType matrix_type (void) const { return typ ? *typ : MatrixType (); } 132 MatrixType matrix_type (const MatrixType& _typ) const; 133 134 octave_value diag (octave_idx_type k = 0) const 135 { return octave_value (matrix.diag (k)); } 136 diag(octave_idx_type m,octave_idx_type n)137 octave_value diag (octave_idx_type m, octave_idx_type n) const 138 { return octave_value (matrix.diag (m, n)); } 139 140 octave_value sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const 141 { return octave_value (matrix.sort (dim, mode)); } 142 octave_value sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0, 143 sortmode mode = ASCENDING) const 144 { return octave_value (matrix.sort (sidx, dim, mode)); } 145 146 sortmode issorted (sortmode mode = UNSORTED) const 147 { return matrix.issorted (mode); } 148 149 Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const 150 { return matrix.sort_rows_idx (mode); } 151 152 sortmode is_sorted_rows (sortmode mode = UNSORTED) const 153 { return matrix.is_sorted_rows (mode); } 154 is_matrix_type(void)155 bool is_matrix_type (void) const { return true; } 156 isnumeric(void)157 bool isnumeric (void) const { return true; } 158 is_defined(void)159 bool is_defined (void) const { return true; } 160 is_constant(void)161 bool is_constant (void) const { return true; } 162 163 bool is_true (void) const; 164 165 bool print_as_scalar (void) const; 166 167 void print (std::ostream& os, bool pr_as_read_syntax = false); 168 169 void print_info (std::ostream& os, const std::string& prefix) const; 170 171 void short_disp (std::ostream& os) const; 172 173 float_display_format get_edit_display_format (void) const; 174 175 std::string edit_display (const float_display_format& fmt, 176 octave_idx_type i, octave_idx_type j) const; 177 matrix_ref(void)178 MT& matrix_ref (void) 179 { 180 clear_cached_info (); 181 return matrix; 182 } 183 matrix_ref(void)184 const MT& matrix_ref (void) const 185 { 186 return matrix; 187 } 188 189 octave_value 190 fast_elem_extract (octave_idx_type n) const; 191 192 bool 193 fast_elem_insert (octave_idx_type n, const octave_value& x); 194 195 protected: 196 197 MT matrix; 198 set_idx_cache(const idx_vector & idx)199 idx_vector set_idx_cache (const idx_vector& idx) const 200 { 201 delete idx_cache; 202 idx_cache = (idx ? new idx_vector (idx) : nullptr); 203 return idx; 204 } 205 clear_cached_info(void)206 void clear_cached_info (void) const 207 { 208 delete typ; typ = nullptr; 209 delete idx_cache; idx_cache = nullptr; 210 } 211 212 mutable MatrixType *typ; 213 mutable idx_vector *idx_cache; 214 215 private: 216 217 // No assignment. 218 219 octave_base_matrix& operator = (const octave_base_matrix&); 220 }; 221 222 #endif 223