Mercurial > hg > octave-nkf
comparison liboctave/ArrayN-idx.h @ 4513:508238e65af7
[project @ 2003-09-19 21:40:57 by jwe]
author | jwe |
---|---|
date | Fri, 19 Sep 2003 21:41:21 +0000 |
parents | e944fbe3fff2 |
children | 4c8a2e4e0717 |
comparison
equal
deleted
inserted
replaced
4512:b55eaa010770 | 4513:508238e65af7 |
---|---|
24 #include "Array-flags.h" | 24 #include "Array-flags.h" |
25 #include "Range.h" | 25 #include "Range.h" |
26 #include "idx-vector.h" | 26 #include "idx-vector.h" |
27 #include "lo-error.h" | 27 #include "lo-error.h" |
28 | 28 |
29 template <class T> | 29 #if 0 |
30 void | |
31 ArrayN<T>::maybe_delete_elements (Array<idx_vector>& idx, const T& rfv) | |
32 { | |
33 int n_idx = idx.length (); | |
34 | |
35 Array<int> lhs_dims = dims (); | |
36 | |
37 Array<int> idx_is_colon (n_idx, 0); | |
38 Array<int> idx_is_colon_equiv (n_idx, 0); | |
39 | |
40 // Initialization of colon arrays. | |
41 | |
42 for (int i = 0; i < n_idx; i++) | |
43 { | |
44 idx_is_colon_equiv(i) = idx(i).is_colon_equiv (lhs_dims(i), 1); | |
45 | |
46 idx_is_colon(i) = idx(i).is_colon (); | |
47 } | |
48 | |
49 if (all_ones (idx_is_colon) || all_ones (idx_is_colon_equiv)) | |
50 { | |
51 // A(:,:,:) -- we are deleting elements in all dimensions, so | |
52 // the result is [](0x0x0). | |
53 | |
54 Array<int> zeros (n_idx, 0); | |
55 | |
56 resize (zeros, rfv); | |
57 } | |
58 | |
59 else if (num_ones (idx_is_colon) == n_idx - 1 | |
60 && num_ones (idx_is_colon_equiv) == n_idx) | |
61 { | |
62 // A(:,:,j) -- we are deleting elements in one dimension by | |
63 // enumerating them. | |
64 // | |
65 // If we enumerate all of the elements, we should have zero | |
66 // elements in that dimension with the same number of elements | |
67 // in the other dimensions that we started with. | |
68 | |
69 Array<int> temp_dims (n_idx,0); | |
70 | |
71 for (int i = 0; i < n_idx; i++) | |
72 { | |
73 if (idx_is_colon (i)) | |
74 temp_dims (i) = lhs_dims (i); | |
75 | |
76 else | |
77 temp_dims (i) = 0; | |
78 } | |
79 resize (temp_dims); | |
80 } | |
81 else if (num_ones (idx_is_colon) == n_idx - 1) | |
82 { | |
83 // We have colons in all indices except for one. | |
84 // This index tells us which slice to delete | |
85 | |
86 int non_col = 0; | |
87 | |
88 // Find the non-colon column. | |
89 | |
90 for (int i = 0; i < n_idx; i++) | |
91 { | |
92 if (! idx_is_colon (i)) | |
93 non_col = i; | |
94 } | |
95 | |
96 // The length of the non-colon dimension. | |
97 | |
98 int non_col_dim = lhs_dims (non_col); | |
99 | |
100 idx(non_col).sort (true); | |
101 | |
102 int num_to_delete = idx(non_col).length (lhs_dims (non_col)); | |
103 | |
104 if (num_to_delete > 0) | |
105 { | |
106 int temp = num_ones(lhs_dims); | |
107 | |
108 if (non_col_dim == 1) | |
109 temp--; | |
110 | |
111 if (temp == n_idx - 1 && num_to_delete == non_col_dim) | |
112 { | |
113 // We have A with (1x1x4), where A(1,:,1:4) | |
114 // Delete all (0x0x0) | |
115 | |
116 Array<int> zero_dims (n_idx, 0); | |
117 | |
118 resize (zero_dims, rfv); | |
119 } | |
120 else | |
121 { | |
122 // New length of non-colon dimension | |
123 // (calculated in the next for loop) | |
124 | |
125 int new_dim = non_col_dim; | |
126 | |
127 int iidx = 0; | |
128 | |
129 for (int j = 0; j < non_col_dim; j++) | |
130 if (j == idx(non_col).elem (iidx)) | |
131 { | |
132 iidx++; | |
133 | |
134 new_dim--; | |
135 | |
136 if (iidx == num_to_delete) | |
137 break; | |
138 } | |
139 | |
140 // Creating the new nd array after deletions. | |
141 | |
142 if (new_dim > 0) | |
143 { | |
144 // Calculate number of elements in new array. | |
145 | |
146 int num_new_elem=1; | |
147 | |
148 for (int i = 0; i < n_idx; i++) | |
149 { | |
150 if (i == non_col) | |
151 num_new_elem *= new_dim; | |
152 | |
153 else | |
154 num_new_elem *= lhs_dims(i); | |
155 } | |
156 | |
157 T *new_data = new T [num_new_elem]; | |
158 | |
159 Array<int> result_idx (lhs_dims.length (), 0); | |
160 Array<int> elt_idx; | |
161 | |
162 Array<int> lhs_inc (lhs_dims.length ()); | |
163 | |
164 for (int i = 0; i < lhs_dims.length (); i++) | |
165 lhs_inc(i) = lhs_dims(i) + 1; | |
166 | |
167 Array<int> new_lhs_dim = lhs_dims; | |
168 | |
169 new_lhs_dim(non_col) = new_dim; | |
170 | |
171 int num_elem = 1; | |
172 | |
173 int numidx = 0; | |
174 | |
175 int n = length (); | |
176 | |
177 for (int i =0; i < lhs_dims.length (); i++) | |
178 if (i != non_col) | |
179 num_elem *= lhs_dims (i); | |
180 | |
181 num_elem *= idx(non_col).capacity (); | |
182 | |
183 for (int i = 0; i < n; i++) | |
184 { | |
185 if (numidx < num_elem | |
186 && is_in (result_idx(non_col), idx(non_col))) | |
187 numidx++; | |
188 | |
189 else | |
190 { | |
191 Array<int> temp_result_idx = result_idx; | |
192 | |
193 int num_lgt | |
194 = how_many_lgt (result_idx(non_col), idx(non_col)); | |
195 | |
196 temp_result_idx(non_col) -= num_lgt; | |
197 | |
198 int kidx | |
199 = ::compute_index (temp_result_idx, new_lhs_dim); | |
200 | |
201 new_data[kidx] = elem (result_idx); | |
202 } | |
203 | |
204 increment_index (result_idx, lhs_dims); | |
205 } | |
206 | |
207 if (--(Array<T>::rep)->count <= 0) | |
208 delete Array<T>::rep; | |
209 | |
210 Array<T>::rep = | |
211 new typename Array<T>::ArrayRep (new_data, num_new_elem); | |
212 | |
213 dimensions = new_lhs_dim; | |
214 | |
215 set_max_indices (new_lhs_dim.length ()); | |
216 } | |
217 } | |
218 } | |
219 } | |
220 else if (num_ones(idx_is_colon) < n_idx) | |
221 { | |
222 (*current_liboctave_error_handler) | |
223 ("A null assignment can have only one non-colon index."); | |
224 } | |
225 } | |
226 | 30 |
227 template <class T> | 31 template <class T> |
228 ArrayN<T> | 32 ArrayN<T> |
229 ArrayN<T>::value (void) | 33 ArrayN<T>::value (void) |
230 { | 34 { |
258 clear_index (); | 62 clear_index (); |
259 | 63 |
260 return retval; | 64 return retval; |
261 } | 65 } |
262 | 66 |
263 template <class T> | 67 #endif |
264 ArrayN<T> | |
265 ArrayN<T>::index (idx_vector& ra_idx, int resize_ok, const T& rfv) const | |
266 { | |
267 ArrayN<T> retval; | |
268 assert (0); | |
269 return retval; | |
270 } | |
271 | 68 |
272 static inline Array<int> | |
273 freeze (Array<idx_vector>& ra_idx, const Array<int>& dimensions, int resize_ok) | |
274 { | |
275 Array<int> retval; | |
276 | |
277 int n = ra_idx.length (); | |
278 | |
279 assert (n == dimensions.length ()); | |
280 | |
281 retval.resize (n); | |
282 | |
283 for (int i = 0; i < n; i++) | |
284 retval(i) = ra_idx(i).freeze (dimensions(i), "XXX FIXME XXX", resize_ok); | |
285 | |
286 return retval; | |
287 } | |
288 | |
289 static inline bool | |
290 vector_equivalent (const Array<int>& ra_idx) | |
291 { | |
292 int n = ra_idx.length (); | |
293 | |
294 bool found_first = false; | |
295 | |
296 for (int i = 0; i < n; i++) | |
297 { | |
298 if (ra_idx(i) != 1) | |
299 { | |
300 if (! found_first) | |
301 found_first = true; | |
302 else | |
303 return false; | |
304 } | |
305 } | |
306 | |
307 return true; | |
308 } | |
309 | |
310 static inline bool | |
311 equal_arrays (const Array<int> a, const Array<int> b) | |
312 { | |
313 bool retval = true; | |
314 | |
315 if (a.length () != b.length ()) | |
316 retval = false; | |
317 else | |
318 { | |
319 for (int i = 0; i < a.length (); i++) | |
320 { | |
321 if (a(i) != b(i)) | |
322 retval = false; | |
323 } | |
324 } | |
325 | |
326 return retval; | |
327 } | |
328 | |
329 static inline bool | |
330 all_ok (const Array<idx_vector>& ra_idx) | |
331 { | |
332 bool retval = true; | |
333 | |
334 int n = ra_idx.length (); | |
335 | |
336 for (int i = 0; i < n; i++) | |
337 { | |
338 if (! ra_idx(i)) | |
339 { | |
340 retval = false; | |
341 break; | |
342 } | |
343 } | |
344 | |
345 return retval; | |
346 } | |
347 | |
348 static inline bool | |
349 any_orig_empty (const Array<idx_vector>& ra_idx) | |
350 { | |
351 bool retval = false; | |
352 | |
353 int n = ra_idx.length (); | |
354 | |
355 for (int i = 0; i < n; i++) | |
356 { | |
357 if (ra_idx(i).orig_empty ()) | |
358 { | |
359 retval = true; | |
360 break; | |
361 } | |
362 } | |
363 | |
364 return retval; | |
365 } | |
366 | |
367 static inline bool | |
368 any_zero_len (const Array<int>& frozen_lengths) | |
369 { | |
370 bool retval = false; | |
371 | |
372 int n = frozen_lengths.length (); | |
373 | |
374 for (int i = 0; i < n; i++) | |
375 { | |
376 if (frozen_lengths(i) == 0) | |
377 { | |
378 retval = true; | |
379 break; | |
380 } | |
381 } | |
382 | |
383 return retval; | |
384 } | |
385 | |
386 static inline Array<int> | |
387 get_zero_len_size (const Array<int>& frozen_lengths, | |
388 const Array<int>& dimensions) | |
389 { | |
390 Array<int> retval; | |
391 assert (0); | |
392 return retval; | |
393 } | |
394 | |
395 static inline bool | |
396 all_colon_equiv (const Array<idx_vector>& ra_idx, | |
397 const Array<int>& frozen_lengths) | |
398 { | |
399 bool retval = true; | |
400 | |
401 int idx_n = ra_idx.length (); | |
402 | |
403 int n = frozen_lengths.length (); | |
404 | |
405 assert (idx_n == n); | |
406 | |
407 for (int i = 0; i < n; i++) | |
408 { | |
409 if (! ra_idx(i).is_colon_equiv (frozen_lengths(i))) | |
410 { | |
411 retval = false; | |
412 break; | |
413 } | |
414 } | |
415 | |
416 return retval; | |
417 } | |
418 | |
419 static inline bool | |
420 is_in (int num, const idx_vector& idx) | |
421 { | |
422 int n = idx.capacity (); | |
423 | |
424 for (int i = 0; i < n; i++) | |
425 if (idx.elem (i) == num) | |
426 return true; | |
427 | |
428 return false; | |
429 } | |
430 | |
431 static inline int | |
432 how_many_lgt (const int num, idx_vector& idxv) | |
433 { | |
434 int retval = 0; | |
435 | |
436 int n = idxv.capacity (); | |
437 | |
438 for (int i = 0; i < n; i++) | |
439 if (num > idxv.elem (i)) | |
440 retval++; | |
441 | |
442 return retval; | |
443 } | |
444 | |
445 static inline bool | |
446 all_ones (const Array<int> arr) | |
447 { | |
448 bool retval = true; | |
449 | |
450 for (int i = 0; i < arr.length (); i++) | |
451 { | |
452 if (arr(i) != 1) | |
453 { | |
454 retval = false; | |
455 break; | |
456 } | |
457 } | |
458 | |
459 return retval; | |
460 } | |
461 | |
462 static Array<int> | |
463 get_elt_idx (const Array<idx_vector>& ra_idx, const Array<int>& result_idx) | |
464 { | |
465 int n = ra_idx.length (); | |
466 | |
467 Array<int> retval (n); | |
468 | |
469 for (int i = 0; i < n; i++) | |
470 retval(i) = ra_idx(i).elem (result_idx(i)); | |
471 | |
472 return retval; | |
473 } | |
474 | |
475 template <class T> | |
476 ArrayN<T> | |
477 ArrayN<T>::index (Array<idx_vector>& ra_idx, int resize_ok, const T& rfv) const | |
478 { | |
479 ArrayN<T> retval; | |
480 | |
481 int n_dims = dimensions.length (); | |
482 | |
483 Array<int> frozen_lengths = freeze (ra_idx, dimensions, resize_ok); | |
484 | |
485 if (frozen_lengths.length () == n_dims) | |
486 { | |
487 if (all_ok (ra_idx)) | |
488 { | |
489 if (any_orig_empty (ra_idx)) | |
490 { | |
491 retval.resize (frozen_lengths); | |
492 } | |
493 else if (any_zero_len (frozen_lengths)) | |
494 { | |
495 Array<int> new_size = get_zero_len_size (frozen_lengths, | |
496 dimensions); | |
497 | |
498 retval.resize (new_size); | |
499 } | |
500 else if (all_colon_equiv (ra_idx, frozen_lengths)) | |
501 { | |
502 retval = *this; | |
503 } | |
504 else | |
505 { | |
506 #if 0 | |
507 retval.resize (frozen_lengths); | |
508 | |
509 int n = Array<T>::get_size (frozen_lengths); | |
510 | |
511 Array<int> result_idx (n_dims, 0); | |
512 | |
513 for (int i = 0; i < n; i++) | |
514 { | |
515 Array<int> elt_idx = get_elt_idx (result_idx); | |
516 | |
517 if (elt_idx > orig_len) | |
518 retval.elem (result_idx) = rfv; | |
519 else | |
520 retval.elem (result_idx) = elem (elt_idx); | |
521 | |
522 increment_index (result_idx, frozen_lengths); | |
523 } | |
524 #endif | |
525 } | |
526 } | |
527 // idx_vector::freeze() printed an error message for us. | |
528 } | |
529 else | |
530 (*current_liboctave_error_handler) | |
531 ("invalid number of dimensions for N-dimensional array index"); | |
532 | |
533 return retval; | |
534 } | |
535 | |
536 #define MAYBE_RESIZE_ND_DIMS \ | |
537 do \ | |
538 { \ | |
539 if (n_idx >= lhs_dims.length () && ! rhs_is_empty) \ | |
540 { \ | |
541 Array<int> max_idx (n_idx); \ | |
542 Array<int> new_idx (n_idx); \ | |
543 \ | |
544 for (int i = 0; i < n_idx; i++) \ | |
545 { \ | |
546 if (lhs_dims.length () == 0 || i >= lhs_dims.length ()) \ | |
547 new_idx(i) = idx(i).max () + 1; \ | |
548 else \ | |
549 { \ | |
550 if (i < rhs_dims.length ()) \ | |
551 max_idx(i) = idx(i).is_colon () ? rhs_dims(i) : idx(i).max () + 1; \ | |
552 else \ | |
553 max_idx(i) = idx(i).max () + 1; \ | |
554 \ | |
555 new_idx(i) = max_idx(i) > lhs_dims(i) ? max_idx(i) : lhs_dims(i); \ | |
556 } \ | |
557 } \ | |
558 \ | |
559 lhs.resize (new_idx, rfv); \ | |
560 lhs_dims = lhs.dims (); \ | |
561 } \ | |
562 } \ | |
563 while (0) | |
564 | |
565 template <class LT, class RT> | |
566 int | |
567 assign (ArrayN<LT>& lhs, const ArrayN<RT>& rhs, const LT& rfv) | |
568 { | |
569 int retval = 1; | |
570 | |
571 int n_idx = lhs.index_count (); | |
572 | |
573 Array<int> lhs_dims = lhs.dims (); | |
574 Array<int> rhs_dims = rhs.dims (); | |
575 | |
576 idx_vector *tmp = lhs.get_idx (); | |
577 | |
578 Array<idx_vector> idx = conv_to_array (tmp, n_idx); | |
579 | |
580 // This needs to be defined before MAYBE_RESIZE_ND_DIMS. | |
581 | |
582 bool rhs_is_empty = rhs_dims.length () == 0 ? true : any_zero_len (rhs_dims); | |
583 | |
584 // Maybe expand to more dimensions. | |
585 | |
586 MAYBE_RESIZE_ND_DIMS; | |
587 | |
588 Array<int> idx_is_colon (n_idx, 0); | |
589 Array<int> idx_is_colon_equiv (n_idx, 0); | |
590 | |
591 for (int i = 0; i < n_idx; i++) | |
592 { | |
593 idx_is_colon_equiv(i) = idx(i).is_colon_equiv (lhs_dims(i), 1); | |
594 | |
595 idx_is_colon(i) = idx(i).is_colon (); | |
596 } | |
597 | |
598 int resize_ok = 1; | |
599 | |
600 Array<int> frozen_len; | |
601 | |
602 if (n_idx == lhs_dims.length ()) | |
603 frozen_len = freeze (idx, lhs_dims, resize_ok); | |
604 | |
605 bool rhs_is_scalar = is_scalar (rhs_dims); | |
606 | |
607 bool idx_is_empty = any_zero_len (frozen_len); | |
608 | |
609 if (rhs_is_empty) | |
610 { | |
611 lhs.maybe_delete_elements (idx, rfv); | |
612 } | |
613 else if (rhs_is_scalar) | |
614 { | |
615 if (n_idx == 0) | |
616 (*current_liboctave_error_handler) | |
617 ("number of indices is zero."); | |
618 | |
619 else if (n_idx < lhs_dims.length ()) | |
620 { | |
621 // Number of indices is less than dimensions. | |
622 | |
623 if (any_ones (idx_is_colon)|| any_ones (idx_is_colon_equiv)) | |
624 { | |
625 (*current_liboctave_error_handler) | |
626 ("number of indices is less than number of dimensions, one or more indices are colons."); | |
627 } | |
628 else | |
629 { | |
630 // Fewer indices than dimensions, no colons. | |
631 | |
632 bool resize = false; | |
633 | |
634 // Subtract one since the last idx do not tell us | |
635 // anything about dimensionality. | |
636 | |
637 for (int i = 0; i < idx.length () - 1; i++) | |
638 { | |
639 // Subtract one since idx counts from 0 while dims | |
640 // count from 1. | |
641 | |
642 if (idx(i).elem (0) + 1 > lhs_dims(i)) | |
643 resize = true; | |
644 } | |
645 | |
646 if (resize) | |
647 { | |
648 Array<int> new_dims (lhs_dims.length ()); | |
649 | |
650 for (int i = 0; i < lhs_dims.length (); i++) | |
651 { | |
652 if (i < idx.length () - 1 | |
653 && idx(i).elem (0) + 1 > lhs_dims(i)) | |
654 new_dims(i) = idx(i).elem (0)+1; | |
655 else | |
656 new_dims(i) = lhs_dims(i); | |
657 } | |
658 | |
659 lhs.resize (new_dims, rfv); | |
660 | |
661 lhs_dims = lhs.dims (); | |
662 } | |
663 | |
664 Array<int> one_arg_temp (1, 0); | |
665 | |
666 RT scalar = rhs.elem (one_arg_temp); | |
667 | |
668 Array<int> int_arr = conv_to_int_array (idx); | |
669 | |
670 int numelem = get_scalar_idx (int_arr, lhs_dims); | |
671 | |
672 if (numelem > lhs.length () || numelem < 0) | |
673 (*current_liboctave_error_handler) | |
674 ("attempt to grow array along ambiguous dimension."); | |
675 else | |
676 lhs.Array<LT>::checkelem (numelem) = scalar; | |
677 } | |
678 } | |
679 else | |
680 { | |
681 // Scalar to matrix assignment with as many indices as lhs | |
682 // dimensions. | |
683 | |
684 int n = ArrayN<LT>::get_size (frozen_len); | |
685 | |
686 Array<int> result_idx (lhs_dims.length (), 0); | |
687 | |
688 Array<int> elt_idx; | |
689 | |
690 Array<int> one_arg_temp(1,0); | |
691 RT scalar = rhs.elem (one_arg_temp); | |
692 | |
693 for (int i = 0; i < n; i++) | |
694 { | |
695 elt_idx = get_elt_idx (idx, result_idx); | |
696 | |
697 Array<int> lhs_inc(lhs_dims.length()); | |
698 | |
699 for (int i = 0; i < lhs_dims.length (); i++) | |
700 lhs_inc(i) = lhs_dims(i) + 1; | |
701 | |
702 if (index_in_bounds(elt_idx, lhs_inc)) | |
703 lhs.checkelem (elt_idx) = scalar; | |
704 else | |
705 lhs.checkelem (elt_idx) = rfv; | |
706 | |
707 increment_index (result_idx, frozen_len); | |
708 } | |
709 } | |
710 } | |
711 else if (rhs_dims.length () >= 2) | |
712 { | |
713 // RHS is matrix or higher dimension. | |
714 | |
715 // Subtracting number of dimensions of length 1 will catch | |
716 // cases where: A(2,1,2)=3 A(:,1,:)=[2,3;4,5] | |
717 | |
718 if (rhs_dims.length () != num_ones(idx_is_colon_equiv) - num_ones(lhs_dims)) | |
719 { | |
720 (*current_liboctave_error_handler) | |
721 ("dimensions do not match in matrix assignment."); | |
722 } | |
723 else | |
724 { | |
725 bool dim_ok(true); | |
726 | |
727 int jj = 0; | |
728 | |
729 // Check that RHS dimensions are the same length as the | |
730 // corresponding LHS dimensions. | |
731 | |
732 for (int j = 0; j < idx_is_colon.length (); j++) | |
733 { | |
734 if (idx_is_colon(j) || idx_is_colon_equiv(j)) | |
735 { | |
736 if (rhs_dims(jj) < lhs_dims(j)) | |
737 { | |
738 dim_ok = false; | |
739 | |
740 break; | |
741 } | |
742 | |
743 jj++; | |
744 } | |
745 } | |
746 | |
747 if (! dim_ok) | |
748 (*current_liboctave_error_handler) | |
749 ("subscripted assignment dimension mismatch."); | |
750 else | |
751 { | |
752 Array<int> new_dims (n_idx); | |
753 | |
754 bool resize = false; | |
755 | |
756 int ii = 0; | |
757 | |
758 // Update idx vectors. | |
759 | |
760 for (int i = 0; i < n_idx; i++) | |
761 { | |
762 if (idx(i).is_colon ()) | |
763 { | |
764 // Add appropriate idx_vector to idx(i) since | |
765 // index with : contains no indexes. | |
766 | |
767 frozen_len(i) = lhs_dims(i) > rhs_dims(ii) ? lhs_dims(i) : rhs_dims(ii); | |
768 | |
769 new_dims(i) = lhs_dims(i) > rhs_dims(ii) ? lhs_dims(i) : rhs_dims(ii); | |
770 | |
771 ii++; | |
772 | |
773 Range idxrange (1, frozen_len(i), 1); | |
774 | |
775 idx_vector idxv (idxrange); | |
776 | |
777 idx(i) = idxv; | |
778 } | |
779 else | |
780 { | |
781 new_dims(i) = lhs_dims(i) > idx(i).max () + 1 ? lhs_dims(i) : idx(i).max () + 1; | |
782 | |
783 if (frozen_len(i) > 1) | |
784 ii++; | |
785 } | |
786 if (new_dims(i) != lhs_dims(i)) | |
787 resize = true; | |
788 } | |
789 | |
790 // Resize LHS if dimensions have changed. | |
791 | |
792 if (resize) | |
793 { | |
794 lhs.resize (new_dims, rfv); | |
795 | |
796 lhs_dims = lhs.dims (); | |
797 } | |
798 | |
799 // Number of elements which need to be set. | |
800 | |
801 int n = ArrayN<LT>::get_size (frozen_len); | |
802 | |
803 Array<int> result_idx (lhs_dims.length (), 0); | |
804 Array<int> elt_idx; | |
805 | |
806 Array<int> result_rhs_idx (rhs_dims.length (), 0); | |
807 Array<int> frozen_rhs (rhs_dims.length(), 0); | |
808 | |
809 for (int i = 0; i < rhs_dims.length (); i++) | |
810 frozen_rhs(i) = rhs_dims(i); | |
811 | |
812 Array<int> lhs_inc (lhs_dims.length ()); | |
813 | |
814 for (int i = 0; i < lhs_dims.length (); i++) | |
815 lhs_inc(i) = lhs_dims(i) + 1; | |
816 | |
817 for (int i = 0; i < n; i++) | |
818 { | |
819 elt_idx = get_elt_idx (idx, result_idx); | |
820 | |
821 if (index_in_bounds (elt_idx, lhs_inc)) | |
822 { | |
823 int s = compute_index (result_rhs_idx,rhs_dims); | |
824 | |
825 lhs.checkelem (elt_idx) = rhs.Array<RT>::elem (s); | |
826 | |
827 increment_index (result_rhs_idx, frozen_rhs); | |
828 } | |
829 else | |
830 lhs.checkelem (elt_idx) = rfv; | |
831 | |
832 increment_index (result_idx, frozen_len); | |
833 } | |
834 } | |
835 } | |
836 } | |
837 else if (idx_is_empty) | |
838 { | |
839 // Assignment to matrix with at least one empty index. | |
840 | |
841 if (! rhs_is_empty || ! rhs_is_scalar) | |
842 { | |
843 (*current_liboctave_error_handler) | |
844 ("A([], []) = X: X must be an empty matrix or a scalar"); | |
845 | |
846 retval = 0; | |
847 } | |
848 } | |
849 else if (lhs_dims.length () != rhs_dims.length ()) | |
850 { | |
851 (*current_liboctave_error_handler) | |
852 ("A(I) = X: X must be a scalar or a matrix with the same size as I"); | |
853 retval = 0; | |
854 } | |
855 | |
856 return retval; | |
857 } | |
858 | |
859 static inline int | |
860 get_scalar_idx (Array<int>& idx, Array<int>& dims) | |
861 { | |
862 int retval (-1); | |
863 | |
864 int n = idx.length (); | |
865 | |
866 if (n > 0) | |
867 { | |
868 retval = idx(--n); | |
869 | |
870 while (--n >= 0) | |
871 { | |
872 retval *= dims (n); | |
873 | |
874 retval += idx(n); | |
875 } | |
876 } | |
877 return retval; | |
878 } | |
879 | |
880 static inline int | |
881 num_ones (const Array<int> ra_idx) | |
882 { | |
883 int retval (0); | |
884 for (int i = 0; i < ra_idx.length (); i++) | |
885 { | |
886 if (ra_idx (i) == 1) | |
887 retval++; | |
888 } | |
889 return retval; | |
890 } | |
891 | |
892 static inline bool | |
893 is_scalar (const Array<int>& dim) | |
894 { | |
895 bool retval = true; | |
896 | |
897 int n = dim.length (); | |
898 | |
899 if (n == 0) | |
900 { | |
901 retval = false; | |
902 } | |
903 else | |
904 { | |
905 for (int i = 0; i < n; i ++) | |
906 { | |
907 if (dim (i) != 1) | |
908 { | |
909 retval = false; | |
910 | |
911 break; | |
912 } | |
913 } | |
914 } | |
915 return retval; | |
916 } | |
917 | |
918 static inline bool | |
919 any_ones (const Array<int> arr) | |
920 { | |
921 bool retval = false; | |
922 | |
923 for (int i = 0; i < arr.length (); i++) | |
924 { | |
925 if (arr (i) == 1) | |
926 { | |
927 retval = true; | |
928 | |
929 break; | |
930 } | |
931 } | |
932 return retval; | |
933 } | |
934 | |
935 static inline int | |
936 compute_index (const Array<int>& ra_idx, const Array<int>& dims) | |
937 { | |
938 int retval = -1; | |
939 | |
940 int n = dims.length (); | |
941 | |
942 if (n > 0 && n == ra_idx.length ()) | |
943 { | |
944 retval = ra_idx(--n); | |
945 | |
946 while (--n >= 0) | |
947 { | |
948 retval *= dims(n); | |
949 | |
950 retval += ra_idx(n); | |
951 } | |
952 } | |
953 else | |
954 (*current_liboctave_error_handler) | |
955 ("ArrayN<T>::compute_index: invalid ra_idxing operation"); | |
956 | |
957 return retval; | |
958 } | |
959 | |
960 static inline Array<int> | |
961 conv_to_int_array (const Array<idx_vector>& a) | |
962 { | |
963 Array<int> retval (a.length ()); | |
964 | |
965 for (int i = 0; i < a.length (); i++) | |
966 retval (i) = a(i).elem (0); | |
967 | |
968 return retval; | |
969 } | |
970 | |
971 static inline Array<idx_vector> | |
972 conv_to_array (const idx_vector *tmp, const int len) | |
973 { | |
974 Array<idx_vector> retval (len); | |
975 | |
976 for (int i = 0; i < len; i++) | |
977 retval (i) = tmp[i]; | |
978 | |
979 return retval; | |
980 } | |
981 /* | 69 /* |
982 ;;; Local Variables: *** | 70 ;;; Local Variables: *** |
983 ;;; mode: C++ *** | 71 ;;; mode: C++ *** |
984 ;;; End: *** | 72 ;;; End: *** |
985 */ | 73 */ |