GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
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