Mercurial > hg > octave-nkf
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 (); |