comparison src/ov-base-mat.cc @ 8679:280fae940bb0

optimize scalar indexing
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 05 Feb 2009 13:58:11 +0100
parents 1dce30ab0e72
children c141078e083a
comparison
equal deleted inserted replaced
8678:e2b4c19c455c 8679:280fae940bb0
1 /* 1 /*
2 2
3 Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006, 3 Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006,
4 2007 John W. Eaton 4 2007 John W. Eaton
5 Copyright (C) 2009 VZLU Prague
5 6
6 This file is part of Octave. 7 This file is part of Octave.
7 8
8 Octave is free software; you can redistribute it and/or modify it 9 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the 10 under the terms of the GNU General Public License as published by the
145 case 1: 146 case 1:
146 { 147 {
147 idx_vector i = idx (0).index_vector (); 148 idx_vector i = idx (0).index_vector ();
148 149
149 if (! error_state) 150 if (! error_state)
150 retval = MT (matrix.index (i, resize_ok, MT::resize_fill_value ())); 151 {
152 // optimize single scalar index.
153 if (i.is_scalar () && i(0) < matrix.numel ())
154 retval = const_cast<const MT&> (matrix)(i(0));
155 else
156 retval = MT (matrix.index (i, resize_ok));
157 }
158 }
159 break;
160
161 case 2:
162 {
163 idx_vector i = idx (0).index_vector ();
164
165 if (! error_state)
166 {
167 idx_vector j = idx (1).index_vector ();
168
169 if (! error_state)
170 {
171 // optimize two scalar indices.
172 if (i.is_scalar () && j.is_scalar () && nd == 2
173 && i(0) < matrix.rows () && j(0) < matrix.columns ())
174 retval = const_cast<const MT&> (matrix)(i(0), j(0));
175 else
176 retval = MT (matrix.index (i, j, resize_ok));
177 }
178 }
151 } 179 }
152 break; 180 break;
153 181
154 default: 182 default:
155 { 183 {
156 if (n_idx == 2 && nd == 2) 184 Array<idx_vector> idx_vec (n_idx);
157 { 185 bool scalar_opt = n_idx == nd;
158 idx_vector i = idx (0).index_vector (); 186 const dim_vector dv = matrix.dims ();
159 187
160 if (! error_state) 188 for (octave_idx_type i = 0; i < n_idx; i++)
161 { 189 {
162 idx_vector j = idx (1).index_vector (); 190 idx_vec(i) = idx(i).index_vector ();
163 191
164 if (! error_state) 192 if (error_state)
165 retval = MT (matrix.index (i, j, resize_ok, 193 break;
166 MT::resize_fill_value ())); 194
167 } 195 scalar_opt = (scalar_opt && idx_vec(i).is_scalar ()
168 } 196 && idx_vec(i)(0) < dv(0));
169 else 197 }
170 { 198
171 Array<idx_vector> idx_vec (n_idx); 199 if (! error_state)
172 200 {
173 for (octave_idx_type i = 0; i < n_idx; i++) 201 if (scalar_opt)
174 { 202 {
175 idx_vec(i) = idx(i).index_vector (); 203 // optimize all scalar indices. Don't construct an index array,
176 204 // but rather calc a scalar index directly.
177 if (error_state) 205 octave_idx_type k = 1, j = 0;
178 break; 206 for (octave_idx_type i = 0; i < n_idx; i++)
179 } 207 {
180 208 j += i * k;
181 if (! error_state) 209 k *= dv (i);
182 retval = MT (matrix.index (idx_vec, resize_ok, 210 }
183 MT::resize_fill_value ())); 211 retval = const_cast<const MT&> (matrix)(j);
184 } 212 }
213 else
214 retval = MT (matrix.index (idx_vec, resize_ok));
215 }
185 } 216 }
186 break; 217 break;
187 } 218 }
188 219
189 return retval; 220 return retval;
191 222
192 template <class MT> 223 template <class MT>
193 void 224 void
194 octave_base_matrix<MT>::assign (const octave_value_list& idx, const MT& rhs) 225 octave_base_matrix<MT>::assign (const octave_value_list& idx, const MT& rhs)
195 { 226 {
196 octave_idx_type len = idx.length (); 227 octave_idx_type n_idx = idx.length ();
197 228
198 Array<idx_vector> ra_idx (len); 229 switch (n_idx)
199 230 {
200 for (octave_idx_type i = 0; i < len; i++) 231 case 0:
201 ra_idx(i) = idx(i).index_vector (); 232 panic_impossible ();
202 233 break;
203 matrix.assign (ra_idx, rhs, MT::resize_fill_value ()); 234
235 case 1:
236 {
237 idx_vector i = idx (0).index_vector ();
238
239 if (! error_state)
240 matrix.assign (i, rhs);
241 }
242 break;
243
244 case 2:
245 {
246 idx_vector i = idx (0).index_vector ();
247
248 if (! error_state)
249 {
250 idx_vector j = idx (1).index_vector ();
251
252 if (! error_state)
253 matrix.assign (i, j, rhs);
254 }
255 }
256 break;
257
258 default:
259 {
260 Array<idx_vector> idx_vec (n_idx);
261
262 for (octave_idx_type i = 0; i < n_idx; i++)
263 {
264 idx_vec(i) = idx(i).index_vector ();
265
266 if (error_state)
267 break;
268 }
269
270 if (! error_state)
271 matrix.assign (idx_vec, rhs);
272 }
273 break;
274 }
275
276 // Invalidate the matrix type
277 typ.invalidate_type ();
278 }
279
280 template <class MT>
281 void
282 octave_base_matrix<MT>::assign (const octave_value_list& idx,
283 typename MT::element_type rhs)
284 {
285 octave_idx_type n_idx = idx.length ();
286
287 int nd = matrix.ndims ();
288
289 MT mrhs (dim_vector (1), rhs);
290
291 switch (n_idx)
292 {
293 case 0:
294 panic_impossible ();
295 break;
296
297 case 1:
298 {
299 idx_vector i = idx (0).index_vector ();
300
301 if (! error_state)
302 {
303 // optimize single scalar index.
304 if (i.is_scalar () && i(0) < matrix.numel ())
305 matrix(i(0)) = rhs;
306 else
307 matrix.assign (i, mrhs);
308 }
309 }
310 break;
311
312 case 2:
313 {
314 idx_vector i = idx (0).index_vector ();
315
316 if (! error_state)
317 {
318 idx_vector j = idx (1).index_vector ();
319
320 if (! error_state)
321 {
322 // optimize two scalar indices.
323 if (i.is_scalar () && j.is_scalar () && nd == 2
324 && i(0) < matrix.rows () && j(0) < matrix.columns ())
325 matrix(i(0), j(0)) = rhs;
326 else
327 matrix.assign (i, j, mrhs);
328 }
329 }
330 }
331 break;
332
333 default:
334 {
335 Array<idx_vector> idx_vec (n_idx);
336 bool scalar_opt = n_idx == nd;
337 const dim_vector dv = matrix.dims ();
338
339 for (octave_idx_type i = 0; i < n_idx; i++)
340 {
341 idx_vec(i) = idx(i).index_vector ();
342
343 if (error_state)
344 break;
345
346 scalar_opt = (scalar_opt && idx_vec(i).is_scalar ()
347 && idx_vec(i)(0) < dv(0));
348 }
349
350 if (! error_state)
351 {
352 if (scalar_opt)
353 {
354 // optimize all scalar indices. Don't construct an index array,
355 // but rather calc a scalar index directly.
356 octave_idx_type k = 1, j = 0;
357 for (octave_idx_type i = 0; i < n_idx; i++)
358 {
359 j += i * k;
360 k *= dv (i);
361 }
362 matrix(k) = rhs;
363 }
364 else
365 matrix.assign (idx_vec, mrhs);
366 }
367 }
368 break;
369 }
204 370
205 // Invalidate the matrix type 371 // Invalidate the matrix type
206 typ.invalidate_type (); 372 typ.invalidate_type ();
207 } 373 }
208 374