GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Cell.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1999-2024 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 (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include "idx-vector.h"
31 
32 #include "Cell.h"
33 #include "error.h"
34 #include "errwarn.h"
35 #include "ovl.h"
36 
38  : Array<octave_value> (ovl.cell_value ())
39 { }
40 
41 Cell::Cell (const string_vector& sv, bool trim)
42  : Array<octave_value> ()
43 {
44  octave_idx_type n = sv.numel ();
45 
46  if (n > 0)
47  {
48  resize (dim_vector (n, 1));
49 
50  for (octave_idx_type i = 0; i < n; i++)
51  {
52  std::string s = sv[i];
53 
54  if (trim)
55  {
56  std::size_t pos = s.find_last_not_of (' ');
57 
58  s = (pos == std::string::npos) ? "" : s.substr (0, pos+1);
59  }
60 
61  elem (i, 0) = s;
62  }
63  }
64 }
65 
66 Cell::Cell (const std::list<std::string>& sl)
67  : Array<octave_value> ()
68 {
69  octave_idx_type n = sl.size ();
70 
71  if (n > 0)
72  {
73  resize (dim_vector (n, 1));
74 
75  octave_value *dst = fortran_vec ();
76  auto p = sl.begin ();
77 
78  for (octave_idx_type i = 0; i < n; i++)
79  dst[i] = *p++;
80  }
81 }
82 
84  : Array<octave_value> (sa.dims ())
85 {
86  octave_idx_type n = sa.numel ();
87 
88  octave_value *dst = fortran_vec ();
89  const std::string *src = sa.data ();
90 
91  for (octave_idx_type i = 0; i < n; i++)
92  dst[i] = src[i];
93 }
94 
95 // Set size to DV, filling with []. Then fill with as many elements of
96 // SV as possible.
97 
98 Cell::Cell (const dim_vector& dv, const string_vector& sv, bool trim)
99  : Array<octave_value> (dv, Matrix ())
100 {
101  octave_idx_type n = sv.numel ();
102 
103  if (n > 0)
104  {
105  octave_idx_type m = numel ();
106 
107  octave_idx_type len = (n > m ? m : n);
108 
109  for (octave_idx_type i = 0; i < len; i++)
110  {
111  std::string s = sv[i];
112 
113  if (trim)
114  {
115  std::size_t pos = s.find_last_not_of (' ');
116 
117  s = (pos == std::string::npos) ? "" : s.substr (0, pos+1);
118  }
119 
120  elem(i) = s;
121  }
122  }
123 }
124 
125 bool
127 {
128  bool retval = true;
129 
130  octave_idx_type n = numel ();
131 
132  for (octave_idx_type i = 0; i < n; i++)
133  {
134  if (! elem(i).is_string ())
135  {
136  retval = false;
137  break;
138  }
139  }
140 
141  return retval;
142 }
143 
146 {
147  Array<std::string> retval (dims ());
148 
149  octave_idx_type n = numel ();
150 
151  for (octave_idx_type i = 0; i < n; i++)
152  retval.xelem (i) = elem (i).string_value ();
153 
154  return retval;
155 }
156 
159 {
160  octave_idx_type n = numel ();
161 
162  string_vector retval (n);
163 
164  for (octave_idx_type i = 0; i < n; i++)
165  retval.xelem (i) = elem (i).string_value ();
166 
167  return retval;
168 }
169 
170 Cell
171 Cell::index (const octave_value_list& idx_arg, bool resize_ok) const
172 {
173  Cell retval;
174 
175  octave_idx_type n = idx_arg.length ();
176 
177  // If we catch an indexing error in index_vector, we flag an error
178  // in index k. Ensure it is the right value before each idx_vector
179  // call. Same variable as used in for loop in default case.
180 
181  octave_idx_type k = 0;
182 
183  try
184  {
185  switch (n)
186  {
187  case 0:
188  warn_empty_index ("cell array");
189  retval = *this;
190  break;
191 
192  case 1:
193  {
194  octave::idx_vector i = idx_arg(0).index_vector ();
195 
196  retval = Array<octave_value>::index (i, resize_ok, Matrix ());
197  }
198  break;
199 
200  case 2:
201  {
202  octave::idx_vector i = idx_arg(0).index_vector ();
203 
204  k = 1;
205  octave::idx_vector j = idx_arg(1).index_vector ();
206 
207  retval = Array<octave_value>::index (i, j, resize_ok, Matrix ());
208  }
209  break;
210 
211  default:
212  {
214 
215  for (k = 0; k < n; k++)
216  iv(k) = idx_arg(k).index_vector ();
217 
218  retval = Array<octave_value>::index (iv, resize_ok, Matrix ());
219  }
220  break;
221  }
222  }
223  catch (octave::index_exception& ie)
224  {
225  // Rethrow to allow more info to be reported later.
226  ie.set_pos_if_unset (n, k+1);
227  throw;
228  }
229 
230  return retval;
231 }
232 
233 /*
234 %% This behavior is required for Matlab compatibility.
235 %!shared a
236 %! a = {"foo", "bar"};
237 %!assert (a(), a)
238 %!error <invalid empty index expression> a{}
239 */
240 
241 void
242 Cell::assign (const octave_value_list& idx_arg, const Cell& rhs,
243  const octave_value& fill_val)
244 
245 {
246  octave_idx_type len = idx_arg.length ();
247 
249 
250  for (octave_idx_type i = 0; i < len; i++)
251  {
252  try
253  {
254  ra_idx(i) = idx_arg(i).index_vector ();
255  }
256  catch (octave::index_exception& ie)
257  {
258  // Rethrow to allow more info to be reported later.
259  ie.set_pos (len, i+1);
260  throw;
261  }
262  }
263 
264  Array<octave_value>::assign (ra_idx, rhs, fill_val);
265 }
266 
267 void
269 
270 {
271  octave_idx_type len = idx_arg.length ();
272 
274 
275  for (octave_idx_type i = 0; i < len; i++)
276  try
277  {
278  ra_idx.xelem (i) = idx_arg(i).index_vector ();
279  }
280  catch (octave::index_exception& ie)
281  {
282  // Rethrow to allow more info to be reported later.
283  ie.set_pos (len, i+1);
284  throw;
285  }
286 
288 }
289 
291 Cell::nnz () const
292 {
293  err_wrong_type_arg ("nnz", "cell array");
294 }
295 
296 /*
297 %!error <wrong type argument 'cell array'> nnz ({0, 1, 2})
298 %!error <wrong type argument 'cell array'> nnz (cell ())
299 %!error <wrong type argument 'cell array'> nnz ({"foo", "bar"})
300 */
301 
302 Cell
304 {
305  Cell retval;
306 
307  if (ndims () > 2)
308  error ("Cell::column: requires 2-D cell array");
309 
310  if (i < 0 || i >= cols ())
311  error ("invalid column selection");
312 
313  octave_idx_type nr = rows ();
314 
315  retval.resize (dim_vector (nr, 1));
316 
317  for (octave_idx_type j = 0; j < nr; j++)
318  retval.xelem (j) = elem (j, i);
319 
320  return retval;
321 }
322 
323 Cell
325 {
326  return insert (rb, ra_idx);
327 }
328 
329 Cell&
331 {
333  return *this;
334 }
335 
336 Cell&
338 {
340  return *this;
341 }
342 
343 Cell
344 Cell::map (ctype_mapper fcn) const
345 {
346  Cell retval (dims ());
347  octave_value *r = retval.fortran_vec ();
348 
349  const octave_value *p = data ();
350 
351  for (octave_idx_type i = 0; i < numel (); i++)
352  r[i] = ((p++)->*fcn) ();
353 
354  return retval;
355 }
356 
359 {
360  static octave_value rfv = octave_value (Matrix ());
361  return rfv;
362 }
363 
364 Cell
366 {
367  return Array<octave_value>::diag (k);
368 }
369 
370 Cell
372 {
373  return Array<octave_value>::diag (m, n);
374 }
N Dimensional Array with copy-on-write semantics.
Definition: Array.h:130
octave_value & elem(octave_idx_type n)
Definition: Array.h:562
octave_value * fortran_vec()
Definition: Array-base.cc:1764
Array< T, Alloc > index(const octave::idx_vector &i) const
Indexing without resizing.
Definition: Array-base.cc:710
void assign(const octave::idx_vector &i, const Array< T, Alloc > &rhs, const T &rfv)
Indexed assignment (always with resize & fill).
Definition: Array-base.cc:1128
int ndims() const
Definition: Array.h:671
octave_idx_type rows() const
Definition: Array.h:459
void resize(const dim_vector &dv, const octave_value &rfv)
Definition: Array-base.cc:1023
Array< T, Alloc > & insert(const Array< T, Alloc > &a, const Array< octave_idx_type > &idx)
Insert an array into another at a specified position.
Definition: Array-base.cc:1608
const T * data() const
Size of the specified dimension.
Definition: Array.h:663
void delete_elements(const octave::idx_vector &i)
Deleting elements.
Definition: Array-base.cc:1407
octave_idx_type cols() const
Definition: Array.h:469
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:503
T & xelem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:524
Array< T, Alloc > diag(octave_idx_type k=0) const
Get the kth super or subdiagonal.
Definition: Array-base.cc:2541
octave_idx_type numel() const
Number of elements in the array.
Definition: Array.h:414
Definition: Cell.h:43
Cell & insert(const Cell &a, octave_idx_type r, octave_idx_type c)
Definition: Cell.cc:330
void assign(const octave_value_list &idx, const Cell &rhs, const octave_value &fill_val=Matrix())
Definition: Cell.cc:242
Cell column(octave_idx_type i) const
Definition: Cell.cc:303
Cell concat(const Cell &rb, const Array< octave_idx_type > &ra_idx)
Definition: Cell.cc:324
Cell index(const octave_value_list &idx, bool resize_ok=false) const
Definition: Cell.cc:171
Cell diag(octave_idx_type k=0) const
Definition: Cell.cc:365
Cell()=default
void delete_elements(const octave_value_list &idx)
Definition: Cell.cc:268
Array< std::string > cellstr_value() const
Definition: Cell.cc:145
octave_idx_type nnz() const
Definition: Cell.cc:291
string_vector string_vector_value() const
Definition: Cell.cc:158
octave_value resize_fill_value() const
Size of the specified dimension.
Definition: Cell.cc:358
bool iscellstr() const
Definition: Cell.cc:126
Definition: dMatrix.h:42
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
octave_idx_type length() const
Definition: ovl.h:113
std::string string_value(bool force=false) const
Definition: ov.h:974
std::string & xelem(octave_idx_type i)
Definition: str-vec.h:108
octave_idx_type numel() const
Definition: str-vec.h:100
void() error(const char *fmt,...)
Definition: error.cc:988
void warn_empty_index(const std::string &type_name)
Definition: errwarn.cc:336
void err_wrong_type_arg(const char *name, const char *s)
Definition: errwarn.cc:166
octave::idx_vector idx_vector
Definition: idx-vector.h:1022
T octave_idx_type m
Definition: mx-inlines.cc:781
octave_idx_type n
Definition: mx-inlines.cc:761
T * r
Definition: mx-inlines.cc:781
const octave_base_value const Array< octave_idx_type > & ra_idx
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:219
F77_RET_T len
Definition: xerbla.cc:61