~ubuntu-branches/ubuntu/utopic/octave-miscellaneous/utopic

« back to all changes in this revision

Viewing changes to src/partarray.cc

  • Committer: Package Import Robot
  • Author(s): Thomas Weber, Thomas Weber, Rafael Laboissiere
  • Date: 2014-06-09 15:43:35 UTC
  • mfrom: (13.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20140609154335-1orz1ug3ielyxsnn
Tags: 1.2.1-1
[ Thomas Weber ]
* Imported Upstream version 1.2.1
  - partarray.cc was removed upstream, making it no longer a problem for
    clang (closes: #749154)
* Drop unused lintian override: hardening-no-fortify-functions
* debian/control: Use canonical URLs in Vcs-* fields

[ Rafael Laboissiere ]
* Bump to Standards-Version 3.9.5, no changes needed

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright (C) 2010,2011 Olaf Till <i7tiol@t-online.de>
2
 
//
3
 
// This program is free software; you can redistribute it and/or modify it under
4
 
// the terms of the GNU General Public License as published by the Free Software
5
 
// Foundation; either version 3 of the License, or (at your option) any later
6
 
// version.
7
 
//
8
 
// This program is distributed in the hope that it will be useful, but WITHOUT
9
 
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11
 
// details.
12
 
//
13
 
// You should have received a copy of the GNU General Public License along with
14
 
// this program; if not, see <http://www.gnu.org/licenses/>.
15
 
 
16
 
#include <octave/oct.h>
17
 
#include <octave/ov-struct.h>
18
 
 
19
 
template<class NDA>
20
 
static Cell
21
 
do_partarray (const NDA& a, const std::string& fname,
22
 
              const octave_value_list& args)
23
 
{
24
 
  // FIXME: some type-independent code should probably go into an
25
 
  // extra function (no template) to avoid its repetitive instanciation
26
 
 
27
 
  int nidc = args.length () - 1;
28
 
 
29
 
  dim_vector dv = a.dims ();
30
 
 
31
 
  int ndims = dv.length ();
32
 
 
33
 
  int maxdims = ndims > nidc ? ndims : nidc;
34
 
 
35
 
  Array<octave_idx_type> alldims (dim_vector (maxdims, 1));
36
 
  for (int i = 0; i < maxdims; alldims(i) = i < ndims ? dv(i) : 1, i++);
37
 
 
38
 
  int nc = 1;
39
 
  Array<int> nidx (dim_vector (maxdims, 1));
40
 
  // Octave-3.2.4 reports "missing symbol" with Array<Array< > >,
41
 
  // though 3.3.54+ does not
42
 
  Array<octave_idx_type> bidc [maxdims], eidc [maxdims];
43
 
  //
44
 
  Array<octave_idx_type> step (dim_vector (maxdims, 1));
45
 
  step(0) = 1;
46
 
  for (int i = 0; i < maxdims; i++)
47
 
    {
48
 
      int cnidx;
49
 
      octave_value arg;
50
 
      if (i >= nidc || (arg = args(i + 1)).is_empty ())
51
 
        {
52
 
          Array<octave_idx_type> bidx (dim_vector (1, 1), 1);
53
 
          Array<octave_idx_type> eidx (dim_vector (1, 1), alldims(i));
54
 
          bidc[i] = bidx;
55
 
          eidc[i] = eidx;
56
 
          cnidx = 1;
57
 
        }
58
 
      else
59
 
        {
60
 
          dim_vector argdims = arg.dims ();
61
 
          if (argdims.length () > 2 || argdims(1) != 2)
62
 
            {
63
 
              error ("%s: argument %i: wrong dimensions",
64
 
                     fname.c_str (), i + 2);
65
 
              return Cell ();
66
 
            }
67
 
          cnidx =
68
 
            (bidc[i] = octave_value (arg.matrix_value ().column (0)).
69
 
             octave_idx_type_vector_value ()).length ();
70
 
          eidc[i] = octave_value (arg.matrix_value ().column (1)).
71
 
            octave_idx_type_vector_value ();
72
 
          for (int j = 0; j < cnidx; j++)
73
 
            {
74
 
              if (bidc[i](j) < 1 || eidc[i](j) > alldims(i))
75
 
                error ("%s: index given by row %i of argument %i exceeds array dimensions",
76
 
                       fname.c_str (), j, i + 2);
77
 
              if (bidc[i](j) > eidc[i](j))
78
 
                // so later length calculations yield 0
79
 
                eidc[i](j) = bidc[i](j) - 1;
80
 
            }
81
 
        }
82
 
      nc *= (nidx(i) = cnidx);
83
 
      if (i < maxdims - 1)
84
 
        step(i + 1) = step(i) * alldims(i);
85
 
    }
86
 
  if (error_state)
87
 
    return Cell ();
88
 
 
89
 
  dim_vector rdv (nc, 1);
90
 
 
91
 
  Cell retval (rdv);
92
 
 
93
 
  // preparations are done, start now; take care, indices are
94
 
  // one-based, since given by user
95
 
 
96
 
  // go through all combinations of indices into user indices
97
 
  Array<int> cidx (dim_vector (maxdims, 1), 0); // current combination
98
 
  for (int i = 0; i < nc; i++)
99
 
    {
100
 
      // set cursor to start of subarray and calculate some lengths
101
 
      octave_idx_type n = 1, cursor = 0;
102
 
      Array<octave_idx_type> lengths (dim_vector (maxdims, 1));
103
 
      for (int j = 0; j < maxdims; j++)
104
 
        {
105
 
          octave_idx_type begin = bidc[j](cidx(j));
106
 
          octave_idx_type end = eidc[j](cidx(j));
107
 
          octave_idx_type length = end + 1 - begin;
108
 
          lengths(j) = length;
109
 
          n *= length;
110
 
          cursor += (begin - 1) * step(j);
111
 
        }
112
 
      Array<octave_idx_type> starts (dim_vector (maxdims - 1, 1), cursor);
113
 
      Array<octave_idx_type> idx_cursors (dim_vector (maxdims, 1), 0);
114
 
      // copy the subarray
115
 
      dim_vector subdv;
116
 
      subdv.resize (maxdims);
117
 
      for (octave_idx_type k = 0; k < maxdims; k++)
118
 
        subdv(k) = lengths(k);
119
 
      NDA asub (subdv);
120
 
      for (octave_idx_type k = 0; k < n; k++)
121
 
        {
122
 
          asub(k) = a(cursor++);
123
 
          idx_cursors(0)++;
124
 
          for (int l = 0; l < maxdims - 1; l++)
125
 
            {
126
 
              if (idx_cursors(l) == lengths(l))
127
 
                {
128
 
                  idx_cursors(l) = 0;
129
 
                  idx_cursors(l + 1)++;
130
 
                  cursor = starts(l) + step(l + 1);
131
 
                  for (int m = 0; m <= l; starts(m) = cursor, m++);
132
 
                }
133
 
            }
134
 
        }
135
 
      // insert subarray into cell
136
 
      retval(i, 0) = octave_value (asub);
137
 
      // prepare next combination
138
 
      cidx(0)++;
139
 
      for (int j = 0; j < maxdims - 1; j++)
140
 
        if (cidx(j) >= nidx(j))
141
 
          {
142
 
            cidx(j) = 0;
143
 
            cidx(j + 1)++;
144
 
          }
145
 
    }
146
 
 
147
 
  return retval;
148
 
}
149
 
 
150
 
DEFUN_DLD (partarray, args, ,
151
 
  "-*- texinfo -*-\n\
152
 
@deftypefn {Loadable Function} {} partarray (@var{a}, @var{idx}, @dots{})\n\
153
 
Return a column cell array with subarrays of the @var{a}. Start and end indices of subarrays are given in the rows of @var{idx}. @var{idx} can be given for each dimension, empty @var{idx} means no partitioning in the respective dimension. Order of returned subarrays: rows of @var{idx} of some dimension are completely used before using the next row of @var{idx} of the higher dimension.\n\
154
 
\n\
155
 
Does not work with structure arrays at the moment.\n\
156
 
@end deftypefn")
157
 
{
158
 
  static bool warned = false;
159
 
  if (!warned){
160
 
    warning_with_id ("Octave:deprecated-function",
161
 
                     "partarray has been deprecated, and will be removed in the future. Use `mat2cell' instead.");
162
 
    warned = true;
163
 
  }
164
 
  std::string fname ("partarray");
165
 
 
166
 
  if (args.length () == 0)
167
 
    {
168
 
      print_usage ();
169
 
      return octave_value_list ();
170
 
    }
171
 
 
172
 
  octave_value array = args(0);
173
 
  octave_value retval;
174
 
 
175
 
  // The idea to use a function template was taken from Octaves
176
 
  // num2cell in src/DLD-FUNCTIONS/cellfun.cc. The following code,
177
 
  // which distinguishes the applicable types for the template, was
178
 
  // cut and pasted from there and adapted.
179
 
  if (array.is_bool_type ())
180
 
    retval = do_partarray (array.bool_array_value (), fname, args);
181
 
  else if (array.is_char_matrix ())
182
 
    retval = do_partarray (array.char_array_value (), fname, args);
183
 
  else if (array.is_numeric_type ())
184
 
    {
185
 
      if (array.is_integer_type ())
186
 
        {
187
 
          if (array.is_int8_type ())
188
 
            retval = do_partarray (array.int8_array_value (), fname, args);
189
 
          else if (array.is_int16_type ())
190
 
            retval = do_partarray (array.int16_array_value (), fname, args);
191
 
          else if (array.is_int32_type ())
192
 
            retval = do_partarray (array.int32_array_value (), fname, args);
193
 
          else if (array.is_int64_type ())
194
 
            retval = do_partarray (array.int64_array_value (), fname, args);
195
 
          else if (array.is_uint8_type ())
196
 
            retval = do_partarray (array.uint8_array_value (), fname, args);
197
 
          else if (array.is_uint16_type ())
198
 
            retval = do_partarray (array.uint16_array_value (), fname, args);
199
 
          else if (array.is_uint32_type ())
200
 
            retval = do_partarray (array.uint32_array_value (), fname, args);
201
 
          else if (array.is_uint64_type ())
202
 
            retval = do_partarray (array.uint64_array_value (), fname, args);
203
 
        }
204
 
      else if (array.is_complex_type ())
205
 
        {
206
 
          if (array.is_single_type ())
207
 
            retval = do_partarray (array.float_complex_array_value (),
208
 
                                   fname, args);
209
 
          else
210
 
            retval = do_partarray (array.complex_array_value (), fname, args);
211
 
        }
212
 
      else
213
 
        {
214
 
          if (array.is_single_type ())
215
 
            retval = do_partarray (array.float_array_value (), fname, args);
216
 
          else
217
 
            retval = do_partarray (array.array_value (), fname, args);
218
 
        }
219
 
    }
220
 
  // FIXME: This seems to work in cellfun.cc, but not here ...
221
 
  /*
222
 
  else if (array.is_map ())
223
 
    retval = do_partarray (array.map_value (), fname, args);
224
 
  */
225
 
  else if (array.is_cell ())
226
 
    retval = do_partarray (array.cell_value (), fname, args);
227
 
  else
228
 
    gripe_wrong_type_arg (fname, array);
229
 
 
230
 
  return octave_value (retval);
231
 
}