comparison liboctave/Array.cc @ 4743:754e2855a32d

[project @ 2004-02-06 04:07:22 by jwe]
author jwe
date Fri, 06 Feb 2004 04:07:22 +0000
parents e44d0ac643a5
children 537509a45ba7
comparison
equal deleted inserted replaced
4742:2527c2fd4345 4743:754e2855a32d
2549 } 2549 }
2550 2550
2551 #define MAYBE_RESIZE_ND_DIMS \ 2551 #define MAYBE_RESIZE_ND_DIMS \
2552 do \ 2552 do \
2553 { \ 2553 { \
2554 if (n_idx >= lhs_dims.length () && ! rhs_is_empty) \ 2554 if (n_idx >= lhs_dims_len && ! rhs_is_empty) \
2555 { \ 2555 { \
2556 Array<int> max_idx (n_idx); \ 2556 Array<int> max_idx (n_idx); \
2557 dim_vector new_dims; \ 2557 dim_vector new_dims; \
2558 new_dims.resize (n_idx); \ 2558 new_dims.resize (n_idx); \
2559 \ 2559 \
2560 for (int i = 0; i < n_idx; i++) \ 2560 for (int i = 0; i < n_idx; i++) \
2561 { \ 2561 { \
2562 if (lhs_dims.length () == 0 || i >= lhs_dims.length ()) \ 2562 if (lhs_dims_len == 0 || i >= lhs_dims_len) \
2563 new_dims(i) = idx(i).max () + 1; \ 2563 new_dims(i) = idx(i).max () + 1; \
2564 else \ 2564 else \
2565 { \ 2565 { \
2566 if (i < rhs_dims.length ()) \ 2566 if (i < rhs_dims.length ()) \
2567 max_idx(i) = idx(i).is_colon () ? rhs_dims(i) : idx(i).max () + 1; \ 2567 max_idx(i) = idx(i).is_colon () ? rhs_dims(i) : idx(i).max () + 1; \
2572 } \ 2572 } \
2573 } \ 2573 } \
2574 \ 2574 \
2575 lhs.resize_and_fill (new_dims, rfv); \ 2575 lhs.resize_and_fill (new_dims, rfv); \
2576 lhs_dims = lhs.dims (); \ 2576 lhs_dims = lhs.dims (); \
2577 lhs_dims_len = lhs_dims.length (); \
2577 } \ 2578 } \
2578 } \ 2579 } \
2579 while (0) 2580 while (0)
2580 2581
2581 template <class LT, class RT> 2582 template <class LT, class RT>
2593 2594
2594 Array<idx_vector> idx = conv_to_array (tmp, n_idx); 2595 Array<idx_vector> idx = conv_to_array (tmp, n_idx);
2595 2596
2596 // This needs to be defined before MAYBE_RESIZE_ND_DIMS. 2597 // This needs to be defined before MAYBE_RESIZE_ND_DIMS.
2597 2598
2598 bool rhs_is_empty = rhs_dims.length () == 0 ? true : any_zero_len (rhs_dims); 2599 int rhs_dims_len = rhs_dims.length ();
2600
2601 bool rhs_is_empty = rhs_dims_len == 0 ? true : any_zero_len (rhs_dims);
2599 2602
2600 // Maybe expand to more dimensions. 2603 // Maybe expand to more dimensions.
2604
2605 int lhs_dims_len = lhs_dims.length ();
2601 2606
2602 MAYBE_RESIZE_ND_DIMS; 2607 MAYBE_RESIZE_ND_DIMS;
2603 2608
2604 Array<int> idx_is_colon (n_idx, 0); 2609 Array<int> idx_is_colon (n_idx, 0);
2605 Array<int> idx_is_colon_equiv (n_idx, 0); 2610 Array<int> idx_is_colon_equiv (n_idx, 0);
2613 2618
2614 int resize_ok = 1; 2619 int resize_ok = 1;
2615 2620
2616 dim_vector frozen_len; 2621 dim_vector frozen_len;
2617 2622
2618 if (n_idx == lhs_dims.length ()) 2623 if (n_idx == lhs_dims_len)
2619 frozen_len = freeze (idx, lhs_dims, resize_ok); 2624 frozen_len = freeze (idx, lhs_dims, resize_ok);
2620 2625
2621 bool rhs_is_scalar = is_scalar (rhs_dims); 2626 bool rhs_is_scalar = is_scalar (rhs_dims);
2622 2627
2623 bool idx_is_empty = any_zero_len (frozen_len); 2628 bool idx_is_empty = any_zero_len (frozen_len);
2624 2629
2625 if (rhs_dims.length () == 2 && rhs_dims(0) == 0 && rhs_dims(1) == 0) 2630 if (rhs_dims_len == 2 && rhs_dims(0) == 0 && rhs_dims(1) == 0)
2626 { 2631 {
2627 lhs.maybe_delete_elements (idx, rfv); 2632 lhs.maybe_delete_elements (idx, rfv);
2633 }
2634 else if (idx_is_empty)
2635 {
2636 // Assignment to matrix with at least one empty index.
2637
2638 if (! rhs_is_empty || ! rhs_is_scalar)
2639 {
2640 (*current_liboctave_error_handler)
2641 ("A([], []) = X: X must be an empty matrix or a scalar");
2642
2643 retval = 0;
2644 }
2628 } 2645 }
2629 else if (n_idx == 1) 2646 else if (n_idx == 1)
2630 { 2647 {
2631 idx_vector iidx = idx(0); 2648 idx_vector iidx = idx(0);
2632 2649
2644 if (iidx) 2661 if (iidx)
2645 { 2662 {
2646 if (len == 0) 2663 if (len == 0)
2647 { 2664 {
2648 if (! (rhs_dims.all_ones () || rhs_dims.all_zero ())) 2665 if (! (rhs_dims.all_ones () || rhs_dims.all_zero ()))
2649 (*current_liboctave_error_handler) 2666 {
2650 ("A([]) = X: X must be an empty matrix or scalar"); 2667 (*current_liboctave_error_handler)
2668 ("A([]) = X: X must be an empty matrix or scalar");
2669
2670 retval = 0;
2671 }
2651 } 2672 }
2652 else if (len == rhs.length ()) 2673 else if (len == rhs.length ())
2653 { 2674 {
2654 for (int i = 0; i < len; i++) 2675 for (int i = 0; i < len; i++)
2655 { 2676 {
2678 } 2699 }
2679 2700
2680 // idx_vector::freeze() printed an error message for us. 2701 // idx_vector::freeze() printed an error message for us.
2681 } 2702 }
2682 } 2703 }
2683 2704 else
2684 else if (n_idx < lhs_dims.length ()) 2705 {
2685 { 2706 if (n_idx < lhs_dims_len)
2686 // Number of indices is less than dimensions. 2707 {
2687 2708 // Append 1's so that there are as many indices as
2688 if (any_ones (idx_is_colon)|| any_ones (idx_is_colon_equiv)) 2709 // dimensions on the LHS.
2689 { 2710
2690 (*current_liboctave_error_handler) 2711 idx.resize (lhs_dims_len);
2691 ("number of indices is less than number of dimensions, one or more indices are colons"); 2712
2713 for (int i = n_idx; i < lhs_dims_len; i++)
2714 idx(i) = idx_vector (1);
2715
2716 // We didn't freeze yet.
2717 frozen_len = freeze (idx, lhs_dims, resize_ok);
2718
2719 idx_is_colon.resize (lhs_dims_len);
2720
2721 idx_is_colon_equiv.resize (lhs_dims_len);
2722
2723 // Now that we have frozen, we can update these.
2724 for (int i = n_idx; i < lhs_dims_len; i++)
2725 {
2726 idx_is_colon_equiv(i) = idx(i).is_colon_equiv (lhs_dims(i), 1);
2727
2728 idx_is_colon(i) = idx(i).is_colon ();
2729 }
2730
2731 n_idx = lhs_dims_len;
2732 }
2733
2734 if (rhs_is_scalar)
2735 {
2736 // Scalar to matrix assignment with as many indices as lhs
2737 // dimensions.
2738
2739 int n = Array<LT>::get_size (frozen_len);
2740
2741 Array<int> result_idx (lhs_dims_len, 0);
2742
2743 RT scalar = rhs.elem (0);
2744
2745 for (int i = 0; i < n; i++)
2746 {
2747 Array<int> elt_idx = get_elt_idx (idx, result_idx);
2748
2749 lhs.checkelem (elt_idx) = scalar;
2750
2751 increment_index (result_idx, frozen_len);
2752 }
2692 } 2753 }
2693 else 2754 else
2694 { 2755 {
2695 // Fewer indices than dimensions, no colons. 2756 // RHS is matrix or higher dimension.
2696 2757
2697 bool resize = false; 2758 // Check that non-singleton RHS dimensions conform to
2698 2759 // non-singleton LHS index dimensions.
2699 // Subtract one since the last idx do not tell us 2760
2700 // anything about dimensionality. 2761 dim_vector t_rhs_dims = rhs_dims.squeeze ();
2701 2762 dim_vector t_frozen_len = frozen_len.squeeze ();
2702 for (int i = 0; i < idx.length () - 1; i++) 2763
2703 { 2764 // If after sqeezing out singleton dimensions, RHS is vector
2704 // Subtract one since idx counts from 0 while dims 2765 // and LHS is vector, force them to have the same orientation
2705 // count from 1. 2766 // so that operations like
2706 2767 //
2707 if (idx(i).elem (0) + 1 > lhs_dims(i)) 2768 // a = zeros (3, 3, 3);
2708 resize = true; 2769 // a(1:3,1,1) = [1,2,3];
2709 } 2770 //
2710 2771 // will work.
2711 if (resize) 2772
2773 if (t_rhs_dims.length () == 2 && t_frozen_len.length () == 2
2774 && (t_rhs_dims.elem(1) == 1 && t_frozen_len.elem(0) == 1
2775 || t_rhs_dims.elem(0) == 1 && t_frozen_len.elem(1) == 1))
2776 {
2777 int t0 = t_rhs_dims.elem(0);
2778 t_rhs_dims.elem(0) = t_rhs_dims.elem(1);
2779 t_rhs_dims.elem(1) = t0;
2780 }
2781
2782 if (t_rhs_dims != t_frozen_len)
2783 {
2784 (*current_liboctave_error_handler)
2785 ("A(IDX-LIST) = X: X must be a scalar or size of X must equal number of elements indexed by IDX-LIST");
2786
2787 retval = 0;
2788 }
2789 else
2712 { 2790 {
2713 dim_vector new_dims; 2791 dim_vector new_dims;
2714 new_dims.resize (lhs_dims.length ()); 2792 new_dims.resize (n_idx);
2715 2793
2716 for (int i = 0; i < idx.length () - 1; i++) 2794 bool resize = false;
2717 new_dims(i) = idx(i).elem (0) >= lhs_dims(i) 2795
2718 ? idx(i).elem (0) + 1 : lhs_dims (i); 2796 int ii = 0;
2719 2797
2720 for (int i = idx.length (); i < lhs_dims.length (); i++) 2798 // Update idx vectors.
2721 new_dims(i) = lhs_dims (i); 2799
2722 2800 for (int i = 0; i < n_idx; i++)
2723 lhs.resize (new_dims, rfv);
2724
2725 lhs_dims = lhs.dims ();
2726 }
2727
2728 RT scalar = rhs.elem (0);
2729
2730 Array<int> int_arr = conv_to_int_array (idx);
2731
2732 int numelem = get_scalar_idx (int_arr, lhs_dims);
2733
2734 if (numelem > lhs.length () || numelem < 0)
2735 (*current_liboctave_error_handler)
2736 ("attempt to grow array along ambiguous dimension");
2737 else
2738 lhs.checkelem (numelem) = scalar;
2739 }
2740 }
2741 else if (n_idx == lhs_dims.length () && rhs_is_scalar)
2742 {
2743 // Scalar to matrix assignment with as many indices as lhs
2744 // dimensions.
2745
2746 int n = Array<LT>::get_size (frozen_len);
2747
2748 Array<int> result_idx (lhs_dims.length (), 0);
2749
2750 RT scalar = rhs.elem (0);
2751
2752 for (int i = 0; i < n; i++)
2753 {
2754 Array<int> elt_idx = get_elt_idx (idx, result_idx);
2755
2756 lhs.checkelem (elt_idx) = scalar;
2757
2758 increment_index (result_idx, frozen_len);
2759 }
2760 }
2761 else if (rhs_dims.length () > 1)
2762 {
2763 // RHS is matrix or higher dimension.
2764
2765 // Check that non-singleton RHS dimensions conform to
2766 // non-singleton LHS index dimensions.
2767
2768 dim_vector t_rhs_dims = rhs_dims.squeeze ();
2769 dim_vector t_frozen_len = frozen_len.squeeze ();
2770
2771 // If after sqeezing out singleton dimensions, RHS is vector
2772 // and LHS is vector, force them to have the same orientation
2773 // so that operations like
2774 //
2775 // a = zeros (3, 3, 3);
2776 // a(1:3,1,1) = [1,2,3];
2777 //
2778 // will work.
2779
2780 if (t_rhs_dims.length () == 2 && t_frozen_len.length () == 2
2781 && (t_rhs_dims.elem(1) == 1 && t_frozen_len.elem(0) == 1
2782 || t_rhs_dims.elem(0) == 1 && t_frozen_len.elem(1) == 1))
2783 {
2784 int t0 = t_rhs_dims.elem(0);
2785 t_rhs_dims.elem(0) = t_rhs_dims.elem(1);
2786 t_rhs_dims.elem(1) = t0;
2787 }
2788
2789 if (t_rhs_dims != t_frozen_len)
2790 (*current_liboctave_error_handler)
2791 ("subscripted assignment dimension mismatch");
2792 else
2793 {
2794 dim_vector new_dims;
2795 new_dims.resize (n_idx);
2796
2797 bool resize = false;
2798
2799 int ii = 0;
2800
2801 // Update idx vectors.
2802
2803 for (int i = 0; i < n_idx; i++)
2804 {
2805 if (idx(i).is_colon ())
2806 { 2801 {
2807 // Add appropriate idx_vector to idx(i) since 2802 if (idx(i).is_colon ())
2808 // index with : contains no indexes. 2803 {
2809 2804 // Add appropriate idx_vector to idx(i) since
2810 frozen_len(i) 2805 // index with : contains no indexes.
2811 = lhs_dims(i) > rhs_dims(ii) ? lhs_dims(i) : rhs_dims(ii); 2806
2812 2807 if (lhs_dims(i) > rhs_dims(ii))
2813 new_dims(i) 2808 {
2814 = lhs_dims(i) > rhs_dims(ii) ? lhs_dims(i) : rhs_dims(ii); 2809 frozen_len(i) = lhs_dims(i);
2815 2810 new_dims(i) = lhs_dims(i);
2816 ii++; 2811 }
2817 2812 else
2818 Range idxrange (1, frozen_len(i), 1); 2813 {
2819 2814 frozen_len(i) = rhs_dims(ii);
2820 idx_vector idxv (idxrange); 2815 new_dims(i) = rhs_dims(ii);
2821 2816 }
2822 idx(i) = idxv; 2817
2818 ii++;
2819
2820 Range idxrange (1, frozen_len(i), 1);
2821
2822 idx_vector idxv (idxrange);
2823
2824 idx(i) = idxv;
2825 }
2826 else
2827 {
2828 if (lhs_dims(i) > idx(i).max () + 1)
2829 new_dims(i) = lhs_dims(i);
2830 else
2831 new_dims(i) = idx(i).max () + 1;
2832
2833 // Changed this from 1 to 0.
2834 if ((ii < rhs_dims_len && rhs_dims (ii) == 1)
2835 || frozen_len(i) > 1)
2836 ii++;
2837 }
2838 if (new_dims(i) != lhs_dims(i))
2839 resize = true;
2823 } 2840 }
2824 else 2841
2842 // Resize LHS if dimensions have changed.
2843
2844 if (resize)
2825 { 2845 {
2826 new_dims(i) = lhs_dims(i) > idx(i).max () + 1 ? lhs_dims(i) : idx(i).max () + 1; 2846 lhs.resize (new_dims, rfv);
2827 2847
2828 if ((ii < rhs_dims.length () && rhs_dims (ii) == 1) || frozen_len(i) > 1) //Changed this from 1 to 0 2848 lhs_dims = lhs.dims ();
2829 ii++;
2830 } 2849 }
2831 if (new_dims(i) != lhs_dims(i)) 2850
2832 resize = true; 2851 // Number of elements which need to be set.
2833 } 2852
2834 2853 int n = Array<LT>::get_size (frozen_len);
2835 // Resize LHS if dimensions have changed. 2854
2836 2855 Array<int> result_idx (lhs_dims_len, 0);
2837 if (resize) 2856 Array<int> elt_idx;
2838 { 2857
2839 lhs.resize (new_dims, rfv); 2858 Array<int> result_rhs_idx (rhs_dims_len, 0);
2840 2859
2841 lhs_dims = lhs.dims (); 2860 dim_vector frozen_rhs;
2842 } 2861 frozen_rhs.resize (rhs_dims_len);
2843 2862
2844 // Number of elements which need to be set. 2863 for (int i = 0; i < rhs_dims_len; i++)
2845 2864 frozen_rhs(i) = rhs_dims(i);
2846 int n = Array<LT>::get_size (frozen_len); 2865
2847 2866 for (int i = 0; i < n; i++)
2848 Array<int> result_idx (lhs_dims.length (), 0);
2849 Array<int> elt_idx;
2850
2851 Array<int> result_rhs_idx (rhs_dims.length (), 0);
2852
2853 dim_vector frozen_rhs;
2854 frozen_rhs.resize (rhs_dims.length ());
2855
2856 for (int i = 0; i < rhs_dims.length (); i++)
2857 frozen_rhs(i) = rhs_dims(i);
2858
2859 for (int i = 0; i < n; i++)
2860 {
2861 elt_idx = get_elt_idx (idx, result_idx);
2862
2863 if (index_in_bounds (elt_idx, lhs_dims))
2864 { 2867 {
2865 int s = compute_index (result_rhs_idx, rhs_dims); 2868 elt_idx = get_elt_idx (idx, result_idx);
2866 2869
2867 lhs.checkelem (elt_idx) = rhs.elem (s); 2870 if (index_in_bounds (elt_idx, lhs_dims))
2868 2871 {
2869 increment_index (result_rhs_idx, frozen_rhs); 2872 int s = compute_index (result_rhs_idx, rhs_dims);
2873
2874 lhs.checkelem (elt_idx) = rhs.elem (s);
2875
2876 increment_index (result_rhs_idx, frozen_rhs);
2877 }
2878 else
2879 lhs.checkelem (elt_idx) = rfv;
2880
2881 increment_index (result_idx, frozen_len);
2870 } 2882 }
2871 else 2883 }
2872 lhs.checkelem (elt_idx) = rfv; 2884 }
2873
2874 increment_index (result_idx, frozen_len);
2875 }
2876 }
2877 }
2878 else if (idx_is_empty)
2879 {
2880 // Assignment to matrix with at least one empty index.
2881
2882 if (! rhs_is_empty || ! rhs_is_scalar)
2883 {
2884 (*current_liboctave_error_handler)
2885 ("A([], []) = X: X must be an empty matrix or a scalar");
2886
2887 retval = 0;
2888 }
2889 }
2890 else if (lhs_dims.length () != rhs_dims.length ())
2891 {
2892 (*current_liboctave_error_handler)
2893 ("A(I) = X: X must be a scalar or a matrix with the same size as I");
2894 retval = 0;
2895 } 2885 }
2896 2886
2897 lhs.chop_trailing_singletons (); 2887 lhs.chop_trailing_singletons ();
2898 2888
2899 lhs.clear_index (); 2889 lhs.clear_index ();