GNU Octave 11.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
dim-vector.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2003-2026 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// or <https://octave.org/copyright/>.
7//
8// Copyirght (C) 2009, 2010 VZLU Prague
9//
10// This file is part of Octave.
11//
12// Octave is free software: you can redistribute it and/or modify it
13// under the terms of the GNU General Public License as published by
14// the Free Software Foundation, either version 3 of the License, or
15// (at your option) any later version.
16//
17// Octave is distributed in the hope that it will be useful, but
18// WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU General Public License for more details.
21//
22// You should have received a copy of the GNU General Public License
23// along with Octave; see the file COPYING. If not, see
24// <https://www.gnu.org/licenses/>.
25//
26////////////////////////////////////////////////////////////////////////
27
28#if defined (HAVE_CONFIG_H)
29# include "config.h"
30#endif
31
32#include <limits>
33#include <new>
34#include <sstream>
35
36#include "Array-oct.h"
37#include "dim-vector.h"
38
39void
41{
42 int j = 0;
43 int nd = ndims ();
44
45 for (int i = 0; i < nd; i++)
46 {
47 if (xelem(i) != 1)
48 xelem(j++) = xelem(i);
49 }
50
51 if (j == 1)
52 xelem(1) = 1;
53
54 m_num_dims = (j > 2 ? j : 2);
55}
56
57std::string
58dim_vector::str (char sep) const
59{
60 std::ostringstream buf;
61
62 for (int i = 0; i < ndims (); i++)
63 {
64 buf << xelem (i);
65
66 if (i < ndims () - 1)
67 buf << sep;
68 }
69
70 std::string retval = buf.str ();
71
72 return retval;
73}
74
75int
77{
78 int retval = 0;
79
80 for (int i = 0; i < ndims (); i++)
81 if (xelem (i) == 1)
82 retval++;
83
84 return retval;
85}
86
89{
90 dim_vector new_dims = *this;
91 new_dims.chop_all_singletons ();
92
93 // preserve orientation if there is only one non-singleton dimension left
94 if (new_dims.ndims () == 2 && xelem(0) == 1 && new_dims.elem(1) == 1)
95 return new_dims.as_row ();
96
97 return new_dims;
98}
99
100// This is the rule for cat(). cat (dim, A, B) works if one
101// of the following holds, in this order:
102//
103// 1. size (A, k) == size (B, k) for all k != dim.
104// In this case, size (C, dim) = size (A, dim) + size (B, dim) and
105// other sizes remain intact.
106//
107// 2. A is 0x0, in which case B is the result
108// 3. B is 0x0, in which case A is the result
109
110bool
111dim_vector::concat (const dim_vector& dvb, int dim)
112{
113 int orig_nd = ndims ();
114 int ndb = dvb.ndims ();
115 int new_nd = (dim < ndb ? ndb : dim + 1);
116 if (new_nd > orig_nd)
117 resize (new_nd, 1);
118 else
119 new_nd = orig_nd;
120
121 bool match = true;
122
123 for (int i = 0; i < ndb; i++)
124 {
125 if (i != dim && xelem(i) != dvb(i))
126 {
127 match = false;
128 break;
129 }
130 }
131
132 for (int i = ndb; i < new_nd; i++)
133 {
134 if (i != dim && xelem(i) != 1)
135 {
136 match = false;
137 break;
138 }
139 }
140
141 if (match)
142 xelem(dim) += (dim < ndb ? dvb(dim) : 1);
143 else
144 {
145 // Dimensions don't match. The only allowed fix is to omit 0x0.
146 if (ndb == 2 && dvb(0) == 0 && dvb(1) == 0)
147 match = true;
148 else if (orig_nd == 2 && xelem(0) == 0 && xelem(1) == 0)
149 {
150 *this = dvb;
151 match = true;
152 }
153 }
154
156
157 return match;
158}
159
160// Rules for horzcat/vertcat are yet looser.
161// two arrays A, B can be concatenated
162// horizontally (dim = 2) or vertically (dim = 1) if one of the
163// following holds, in this order:
164//
165// 1. cat (dim, A, B) works
166//
167// 2. A, B are 2-D and one of them is an empty vector, in which
168// case the result is the other one except if both of them
169// are empty vectors, in which case the result is 0x0.
170
171bool
172dim_vector::hvcat (const dim_vector& dvb, int dim)
173{
174 if (concat (dvb, dim))
175 return true;
176 else if (ndims () == 2 && dvb.ndims () == 2)
177 {
178 bool e2dv = xelem(0) + xelem(1) == 1;
179 bool e2dvb = dvb(0) + dvb(1) == 1;
180 if (e2dvb)
181 {
182 if (e2dv)
183 *this = dim_vector ();
184 return true;
185 }
186 else if (e2dv)
187 {
188 *this = dvb;
189 return true;
190 }
191 }
192
193 return false;
194}
195
197dim_vector::redim (int n) const
198{
199 int n_dims = ndims ();
200
201 if (n_dims == n)
202 return *this;
203 else if (n_dims < n)
204 {
205 dim_vector retval = alloc (n);
206
207 std::copy_n (m_dims, n_dims, retval.m_dims);
208 std::fill_n (retval.m_dims + n_dims, n - n_dims, 1);
209
210 return retval;
211 }
212 else
213 {
214 if (n < 1)
215 n = 1;
216
217 dim_vector retval = alloc (n);
218
219 std::copy_n (m_dims, n-1, retval.m_dims);
220
221 // Accumulate overflow dimensions into last remaining dimension
222 int k = xelem(n-1);
223 for (int i = n; i < n_dims; i++)
224 k *= xelem(i);
225
226 retval.xelem(n-1) = k;
227
228 // All dim_vectors are at least 2-D. Make Nx1 if necessary.
229 if (n == 1)
230 retval.xelem(1) = 1;
231
232 return retval;
233 }
234}
235
238{
239 octave_idx_type nd = ndims ();
240
241 Array<octave_idx_type> retval (dim_vector (1, nd));
242
243 for (octave_idx_type i = 0; i < nd; i++)
244 retval(i) = elem (i);
245
246 return retval;
247}
N Dimensional Array with copy-on-write semantics.
Definition Array-base.h:130
Vector representing the dimensions (size) of an Array.
Definition dim-vector.h:92
bool concat(const dim_vector &dvb, int dim)
This corresponds to cat().
std::string str(char sep='x') const
Definition dim-vector.cc:58
void chop_trailing_singletons()
Definition dim-vector.h:162
dim_vector squeeze() const
Definition dim-vector.cc:88
void resize(int n, int fill_value=0)
Definition dim-vector.h:278
static dim_vector alloc(int n)
Definition dim-vector.h:208
Array< octave_idx_type > as_array() const
octave_idx_type ndims() const
Number of dimensions.
Definition dim-vector.h:263
void chop_all_singletons()
Definition dim-vector.cc:40
bool hvcat(const dim_vector &dvb, int dim)
This corresponds to [,] (horzcat, dim = 0) and [;] (vertcat, dim = 1).
octave_idx_type & xelem(int i)
Definition dim-vector.h:149
int num_ones() const
Definition dim-vector.cc:76
octave_idx_type & elem(int i)
Definition dim-vector.h:155
dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
dim_vector as_row() const
Definition dim-vector.h:424