comparison src/pt-const.cc @ 1558:297e084c3857

[project @ 1995-10-12 07:20:28 by jwe]
author jwe
date Thu, 12 Oct 1995 07:21:51 +0000
parents 4d6c168ff235
children 0d9e10d10bd7
comparison
equal deleted inserted replaced
1557:c694fe5956e3 1558:297e084c3857
27 27
28 #ifdef HAVE_CONFIG_H 28 #ifdef HAVE_CONFIG_H
29 #include <config.h> 29 #include <config.h>
30 #endif 30 #endif
31 31
32 #include <cctype>
32 #include <cstring> 33 #include <cstring>
33 34
35 #include <fstream.h>
34 #include <iostream.h> 36 #include <iostream.h>
35 #include <strstream.h> 37 #include <strstream.h>
36 38
39 #include "mx-base.h"
40 #include "Range.h"
41
42 #include "arith-ops.h"
37 #include "error.h" 43 #include "error.h"
38 #include "gripes.h" 44 #include "gripes.h"
45 #include "idx-vector.h"
39 #include "oct-map.h" 46 #include "oct-map.h"
40 #include "oct-str.h" 47 #include "oct-str.h"
41 #include "pager.h" 48 #include "pager.h"
49 #include "pr-output.h"
50 #include "sysdep.h"
42 #include "tree-const.h" 51 #include "tree-const.h"
52 #include "unwind-prot.h"
43 #include "user-prefs.h" 53 #include "user-prefs.h"
44 #include "utils.h" 54 #include "utils.h"
55 #include "variables.h"
56
57 #ifndef TC_REP
58 #define TC_REP tree_constant::tree_constant_rep
59 #endif
60
61 #ifndef MAX
62 #define MAX(a,b) ((a) > (b) ? (a) : (b))
63 #endif
64
65 #ifndef TC_REP
66 #define TC_REP tree_constant::tree_constant_rep
67 #endif
68
69 #ifndef MAX
70 #define MAX(a,b) ((a) > (b) ? (a) : (b))
71 #endif
72
73 // The following three variables could be made static members of the
74 // TC_REP class.
75
76 // Pointer to the blocks of memory we manage.
77 static TC_REP *tc_rep_newlist = 0;
78
79 // Multiplier for allocating new blocks.
80 static const int tc_rep_newlist_grow_size = 128;
81
82 // Indentation level for structures.
83 static int structure_indent_level = 0;
84
85 static void
86 increment_structure_indent_level (void)
87 {
88 structure_indent_level += 2;
89 }
90
91 static void
92 decrement_structure_indent_level (void)
93 {
94 structure_indent_level -= 2;
95 }
96
97 static int
98 any_element_is_complex (const ComplexMatrix& a)
99 {
100 int nr = a.rows ();
101 int nc = a.columns ();
102 for (int j = 0; j < nc; j++)
103 for (int i = 0; i < nr; i++)
104 if (imag (a.elem (i, j)) != 0.0)
105 return 1;
106 return 0;
107 }
45 108
46 // The following three variables could be made static members of the 109 // The following three variables could be made static members of the
47 // tree_constant class. 110 // tree_constant class.
48 111
49 // Pointer to the blocks of memory we manage. 112 // Pointer to the blocks of memory we manage.
322 385
323 int 386 int
324 print_as_structure (const tree_constant& val) 387 print_as_structure (const tree_constant& val)
325 { 388 {
326 return val.is_map (); 389 return val.is_map ();
327 }
328
329 // Construct return vector of empty matrices. Return empty matrices
330 // and/or gripe when appropriate.
331
332 Octave_object
333 vector_of_empties (int nargout, const char *fcn_name)
334 {
335 Octave_object retval;
336
337 // Got an empty argument, check if should gripe/return empty
338 // values.
339
340 int flag = user_pref.propagate_empty_matrices;
341 if (flag != 0)
342 {
343 if (flag < 0)
344 gripe_empty_arg (fcn_name, 0);
345
346 Matrix m;
347 retval.resize (nargout ? nargout : 1);
348 for (int i = 0; i < nargout; i++)
349 retval(i) = m;
350 }
351 else
352 gripe_empty_arg (fcn_name, 1);
353
354 return retval;
355 }
356
357 // -------------------------------------------------------------------
358 //
359 // Basic stuff for the tree-constant representation class.
360 //
361 // Leave the commented #includes below to make it easy to split this
362 // out again, should we want to do that.
363 //
364 // -------------------------------------------------------------------
365
366 // #ifdef HAVE_CONFIG_H
367 // #include <config.h>
368 // #endif
369
370 #include <cctype>
371 // #include <cstring>
372
373 #include <fstream.h>
374 // #include <iostream.h>
375
376 #include "mx-base.h"
377 #include "Range.h"
378
379 #include "arith-ops.h"
380 #include "variables.h"
381 #include "sysdep.h"
382 // #include "error.h"
383 // #include "gripes.h"
384 // #include "user-prefs.h"
385 #include "utils.h"
386 #include "pr-output.h"
387 // #include "tree-const.h"
388 #include "idx-vector.h"
389 #include "unwind-prot.h"
390 // #include "oct-map.h"
391
392 #include "tc-inlines.h"
393
394 // The following three variables could be made static members of the
395 // TC_REP class.
396
397 // Pointer to the blocks of memory we manage.
398 static TC_REP *tc_rep_newlist = 0;
399
400 // Multiplier for allocating new blocks.
401 static const int tc_rep_newlist_grow_size = 128;
402
403 // Indentation level for structures.
404 static int structure_indent_level = 0;
405
406 static void
407 increment_structure_indent_level (void)
408 {
409 structure_indent_level += 2;
410 }
411
412 static void
413 decrement_structure_indent_level (void)
414 {
415 structure_indent_level -= 2;
416 }
417
418 static int
419 any_element_is_complex (const ComplexMatrix& a)
420 {
421 int nr = a.rows ();
422 int nc = a.columns ();
423 for (int j = 0; j < nc; j++)
424 for (int i = 0; i < nr; i++)
425 if (imag (a.elem (i, j)) != 0.0)
426 return 1;
427 return 0;
428 } 390 }
429 391
430 // The real representation of constants. 392 // The real representation of constants.
431 393
432 TC_REP::tree_constant_rep (void) 394 TC_REP::tree_constant_rep (void)
1733 cm->elem (i, 0) = *cop_out++; 1695 cm->elem (i, 0) = *cop_out++;
1734 } 1696 }
1735 1697
1736 delete complex_matrix; 1698 delete complex_matrix;
1737 complex_matrix = cm; 1699 complex_matrix = cm;
1700 }
1701 }
1702
1703 void
1704 TC_REP::convert_to_matrix_type (void)
1705 {
1706 switch (type_tag)
1707 {
1708 case complex_scalar_constant:
1709 {
1710 Complex *old_complex = complex_scalar;
1711 complex_matrix = new ComplexMatrix (1, 1, *complex_scalar);
1712 type_tag = complex_matrix_constant;
1713 delete old_complex;
1714 }
1715 break;
1716
1717 case scalar_constant:
1718 {
1719 matrix = new Matrix (1, 1, scalar);
1720 type_tag = matrix_constant;
1721 }
1722 break;
1723
1724 case unknown_constant:
1725 {
1726 matrix = new Matrix (0, 0);
1727 type_tag = matrix_constant;
1728 }
1729 break;
1730
1731 default:
1732 panic_impossible ();
1733 break;
1738 } 1734 }
1739 } 1735 }
1740 1736
1741 void 1737 void
1742 TC_REP::force_numeric (int force_str_conv) 1738 TC_REP::force_numeric (int force_str_conv)
1960 break; 1956 break;
1961 } 1957 }
1962 } 1958 }
1963 1959
1964 void 1960 void
1965 TC_REP::maybe_resize (int i, int j)
1966 {
1967 int nr = rows ();
1968 int nc = columns ();
1969
1970 i++;
1971 j++;
1972
1973 assert (i > 0 && j > 0);
1974
1975 if (i > nr || j > nc)
1976 {
1977 if (user_pref.resize_on_range_error)
1978 resize (MAX (i, nr), MAX (j, nc), 0.0);
1979 else
1980 {
1981 if (i > nr)
1982 ::error ("row index = %d exceeds max row dimension = %d", i, nr);
1983
1984 if (j > nc)
1985 ::error ("column index = %d exceeds max column dimension = %d",
1986 j, nc);
1987 }
1988 }
1989 }
1990
1991 void
1992 TC_REP::maybe_resize (int i, force_orient f_orient)
1993 {
1994 int nr = rows ();
1995 int nc = columns ();
1996
1997 i++;
1998
1999 assert (i >= 0 && (nr <= 1 || nc <= 1));
2000
2001 // This function never reduces the size of a vector, and all vectors
2002 // have dimensions of at least 0x0. If i is 0, it is either because
2003 // a vector has been indexed with a vector of all zeros (in which
2004 // case the index vector is empty and nothing will happen) or a
2005 // vector has been indexed with 0 (an error which will be caught
2006 // elsewhere).
2007
2008 if (i == 0)
2009 return;
2010
2011 if (nr <= 1 && nc <= 1 && i >= 1)
2012 {
2013 if (user_pref.resize_on_range_error)
2014 {
2015 if (f_orient == row_orient)
2016 resize (1, i, 0.0);
2017 else if (f_orient == column_orient)
2018 resize (i, 1, 0.0);
2019 else if (user_pref.prefer_column_vectors)
2020 resize (i, 1, 0.0);
2021 else
2022 resize (1, i, 0.0);
2023 }
2024 else
2025 ::error ("matrix index = %d exceeds max dimension = %d", i, nc);
2026 }
2027 else if (nr == 1 && i > nc)
2028 {
2029 if (user_pref.resize_on_range_error)
2030 resize (1, i, 0.0);
2031 else
2032 ::error ("matrix index = %d exceeds max dimension = %d", i, nc);
2033 }
2034 else if (nc == 1 && i > nr)
2035 {
2036 if (user_pref.resize_on_range_error)
2037 resize (i, 1, 0.0);
2038 else
2039 ::error ("matrix index = %d exceeds max dimension = ", i, nc);
2040 }
2041 }
2042
2043 void
2044 TC_REP::stash_original_text (char *s) 1961 TC_REP::stash_original_text (char *s)
2045 { 1962 {
2046 orig_text = strsave (s); 1963 orig_text = strsave (s);
2047 } 1964 }
2048 1965
2049 void 1966 void
2050 TC_REP::maybe_mutate (void) 1967 TC_REP::maybe_mutate (void)
2051 { 1968 {
2052 if (error_state)
2053 return;
2054
2055 switch (type_tag) 1969 switch (type_tag)
2056 { 1970 {
2057 case complex_scalar_constant: 1971 case complex_scalar_constant:
2058 if (::imag (*complex_scalar) == 0.0) 1972 if (::imag (*complex_scalar) == 0.0)
2059 { 1973 {
2537 } 2451 }
2538 2452
2539 return retval; 2453 return retval;
2540 } 2454 }
2541 2455
2542 // -------------------------------------------------------------------
2543 //
2544 // Indexing operations for the tree-constant representation class. 2456 // Indexing operations for the tree-constant representation class.
2545 // 2457
2546 // Leave the commented #includes below to make it easy to split this 2458 void
2547 // out again, should we want to do that. 2459 TC_REP::clear_index (void)
2548 // 2460 {
2549 // ------------------------------------------------------------------- 2461 switch (type_tag)
2550 2462 {
2551 // #ifdef HAVE_CONFIG_H 2463 case matrix_constant:
2552 // #include <config.h> 2464 matrix->clear_index ();
2553 // #endif 2465 break;
2554 2466
2555 // #include <cctype> 2467 case TC_REP::complex_matrix_constant:
2556 // #include <cstring> 2468 complex_matrix->clear_index ();
2557 2469 break;
2558 // #include <fstream.h> 2470
2559 // #include <iostream.h> 2471 default:
2560 // #include <strstream.h> 2472 panic_impossible ();
2561 2473 break;
2562 // #include "mx-base.h" 2474 }
2563 // #include "Range.h" 2475 }
2564 2476
2565 // #include "arith-ops.h" 2477 #if 0
2566 // #include "variables.h" 2478 void
2567 // #include "sysdep.h" 2479 TC_REP::set_index (double d)
2568 // #include "error.h" 2480 {
2569 // #include "gripes.h" 2481 switch (type_tag)
2570 // #include "user-prefs.h" 2482 {
2571 // #include "utils.h" 2483 case matrix_constant:
2572 // #include "pager.h" 2484 matrix->set_index (d);
2573 // #include "pr-output.h" 2485 break;
2574 // #include "tree-const.h" 2486
2575 // #include "idx-vector.h" 2487 case TC_REP::complex_matrix_constant:
2576 // #include "oct-map.h" 2488 complex_matrix->set_index (d);
2577 2489 break;
2578 // #include "tc-inlines.h" 2490
2579 2491 default:
2580 // Indexing functions. 2492 panic_impossible ();
2581 2493 break;
2582 // This is the top-level indexing function. 2494 }
2495 }
2496 #endif
2497
2498 void
2499 TC_REP::set_index (const Range& r)
2500 {
2501 switch (type_tag)
2502 {
2503 case matrix_constant:
2504 matrix->set_index (r);
2505 break;
2506
2507 case TC_REP::complex_matrix_constant:
2508 complex_matrix->set_index (r);
2509 break;
2510
2511 default:
2512 panic_impossible ();
2513 break;
2514 }
2515 }
2516
2517 void
2518 TC_REP::set_index (const ColumnVector& v)
2519 {
2520 switch (type_tag)
2521 {
2522 case matrix_constant:
2523 matrix->set_index (v);
2524 break;
2525
2526 case TC_REP::complex_matrix_constant:
2527 complex_matrix->set_index (v);
2528 break;
2529
2530 default:
2531 panic_impossible ();
2532 break;
2533 }
2534 }
2535
2536 void
2537 TC_REP::set_index (const Matrix& m)
2538 {
2539 int nr = m.rows ();
2540 int nc = m.cols ();
2541
2542 if (nr <= 1 || nc <= 1
2543 || user_pref.do_fortran_indexing)
2544 {
2545 switch (type_tag)
2546 {
2547 case matrix_constant:
2548 matrix->set_index (m);
2549 break;
2550
2551 case TC_REP::complex_matrix_constant:
2552 complex_matrix->set_index (m);
2553 break;
2554
2555 default:
2556 panic_impossible ();
2557 break;
2558 }
2559 }
2560 else
2561 ::error ("invalid matrix used as index");
2562 }
2563
2564 // XXX FIXME XXX -- this should probably be handled some other way...
2565 // The arg here is expected to be ':'.
2566 void
2567 TC_REP::set_index (char c)
2568 {
2569 switch (type_tag)
2570 {
2571 case matrix_constant:
2572 matrix->set_index (c);
2573 break;
2574
2575 case TC_REP::complex_matrix_constant:
2576 complex_matrix->set_index (c);
2577 break;
2578
2579 default:
2580 panic_impossible ();
2581 break;
2582 }
2583 }
2584
2585 void
2586 TC_REP::set_index (const Octave_object& args)
2587 {
2588 switch (type_tag)
2589 {
2590 case unknown_constant:
2591 case scalar_constant:
2592 case complex_scalar_constant:
2593 case range_constant:
2594 convert_to_matrix_type ();
2595 break;
2596
2597 default:
2598 break;
2599 }
2600
2601 int n = args.length ();
2602
2603 for (int i = 0; i < n; i++)
2604 {
2605 tree_constant arg = args (i);
2606
2607 switch (arg.const_type ())
2608 {
2609 case range_constant:
2610 set_index (arg.range_value ());
2611 break;
2612
2613 case magic_colon:
2614 set_index (':');
2615 break;
2616
2617 default:
2618 set_index (arg.matrix_value ());
2619 break;
2620 }
2621
2622 if (error_state)
2623 {
2624 clear_index ();
2625 break;
2626 }
2627 }
2628 }
2629
2630 static inline int
2631 valid_scalar_indices (const Octave_object& args)
2632 {
2633 int nargin = args.length ();
2634
2635 for (int i = 0; i < nargin; i++)
2636 if (! args(i).valid_as_scalar_index ())
2637 return 0;
2638
2639 return 1;
2640 }
2583 2641
2584 tree_constant 2642 tree_constant
2585 TC_REP::do_index (const Octave_object& args) 2643 TC_REP::do_index (const Octave_object& args)
2586 { 2644 {
2587 tree_constant retval; 2645 tree_constant retval;
2588 2646
2589 if (error_state) 2647 if (error_state)
2590 return retval; 2648 return retval;
2591 2649
2592 if (rows () == 0 || columns () == 0) 2650 int originally_scalar_type = is_scalar_type ();
2593 { 2651
2594 switch (args.length ()) 2652 if (originally_scalar_type && valid_scalar_indices (args))
2595 { 2653 {
2596 case 2: 2654 switch (type_tag)
2597 if (! args(1).is_magic_colon () 2655 {
2598 && args(1).rows () != 0 && args(1).columns () != 0) 2656 case scalar_constant:
2599 goto index_error; 2657 retval = scalar;
2600 2658 break;
2601 case 1: 2659
2602 if (! args(0).is_magic_colon () 2660 case complex_scalar_constant:
2603 && args(0).rows () != 0 && args(0).columns () != 0) 2661 retval = *complex_scalar;
2604 goto index_error; 2662 break;
2605
2606 return Matrix ();
2607 2663
2608 default: 2664 default:
2609 index_error: 2665 panic_impossible ();
2610 ::error ("attempt to index empty matrix"); 2666 break;
2611 return retval; 2667 }
2612 } 2668 }
2613 } 2669 else
2614 2670 {
2671 set_index (args);
2672
2673 if (! error_state)
2674 {
2675 switch (type_tag)
2676 {
2677 case range_constant:
2678 force_numeric ();
2679 // Fall through...
2680
2681 case matrix_constant:
2682 retval = Matrix (matrix->value ());
2683 break;
2684
2685 case complex_matrix_constant:
2686 retval = ComplexMatrix (complex_matrix->value ());
2687 break;
2688
2689 default:
2690 error ("can't index %s variables", type_as_string ());
2691 break;
2692 }
2693 }
2694
2695 // This is a fairly expensive operation.
2696
2697 if (originally_scalar_type)
2698 maybe_mutate ();
2699 }
2700
2701 return retval;
2702 }
2703
2704 void
2705 TC_REP::maybe_widen (TC_REP::constant_type rhs_type)
2706 {
2615 switch (type_tag) 2707 switch (type_tag)
2616 { 2708 {
2617 case complex_scalar_constant:
2618 case scalar_constant:
2619 retval = do_scalar_index (args);
2620 break;
2621
2622 case complex_matrix_constant:
2623 case matrix_constant: 2709 case matrix_constant:
2624 retval = do_matrix_index (args); 2710 switch (rhs_type)
2625 break; 2711 {
2626 2712 case complex_scalar_constant:
2627 case string_constant: 2713 case complex_matrix_constant:
2628 gripe_string_invalid (); 2714 {
2629 // retval = do_string_index (args); 2715 ComplexMatrix *cm = new ComplexMatrix (*matrix);
2716 delete matrix;
2717 complex_matrix = cm;
2718 type_tag = complex_matrix_constant;
2719 }
2720 break;
2721
2722 default:
2723 break;
2724 }
2630 break; 2725 break;
2631 2726
2632 default: 2727 default:
2633 2728 break;
2634 // This isn't great, but it's easier than implementing a lot 2729 }
2635 // of other special indexing functions. 2730 }
2636 2731
2637 force_numeric ();
2638
2639 if (! error_state && is_numeric_type ())
2640 retval = do_index (args);
2641
2642 break;
2643 }
2644
2645 return retval;
2646 }
2647
2648 tree_constant
2649 TC_REP::do_scalar_index (const Octave_object& args) const
2650 {
2651 tree_constant retval;
2652
2653 if (valid_scalar_indices (args))
2654 {
2655 if (type_tag == scalar_constant)
2656 retval = scalar;
2657 else if (type_tag == complex_scalar_constant)
2658 retval = *complex_scalar;
2659 else
2660 panic_impossible ();
2661
2662 return retval;
2663 }
2664 else
2665 {
2666 int rows = -1;
2667 int cols = -1;
2668
2669 int nargin = args.length ();
2670
2671 switch (nargin)
2672 {
2673 case 2:
2674 {
2675 tree_constant arg = args(1);
2676
2677 if (arg.is_matrix_type ())
2678 {
2679 Matrix mj = arg.matrix_value ();
2680
2681 idx_vector j (mj, user_pref.do_fortran_indexing, "", 1);
2682 if (! j)
2683 return retval;
2684
2685 int jmax = j.max ();
2686 int len = j.length ();
2687 if (len == j.ones_count ())
2688 cols = len;
2689 else if (jmax > 0)
2690 {
2691 error ("invalid scalar index = %d", jmax+1);
2692 return retval;
2693 }
2694 }
2695 else if (arg.const_type () == magic_colon)
2696 {
2697 cols = 1;
2698 }
2699 else if (arg.is_scalar_type ())
2700 {
2701 double dval = arg.double_value ();
2702 if (! xisnan (dval))
2703 {
2704 int ival = NINT (dval);
2705 if (ival == 1)
2706 cols = 1;
2707 else if (ival == 0)
2708 cols = 0;
2709 else
2710 break;;
2711 }
2712 else
2713 break;
2714 }
2715 else
2716 break;
2717 }
2718
2719 // Fall through...
2720
2721 case 1:
2722 {
2723 tree_constant arg = args(0);
2724
2725 if (arg.is_matrix_type ())
2726 {
2727 Matrix mi = arg.matrix_value ();
2728
2729 idx_vector i (mi, user_pref.do_fortran_indexing, "", 1);
2730 if (! i)
2731 return retval;
2732
2733 int imax = i.max ();
2734 int len = i.length ();
2735 if (len == i.ones_count ())
2736 rows = len;
2737 else if (imax > 0)
2738 {
2739 error ("invalid scalar index = %d", imax+1);
2740 return retval;
2741 }
2742 }
2743 else if (arg.const_type () == magic_colon)
2744 {
2745 rows = 1;
2746 }
2747 else if (arg.is_scalar_type ())
2748 {
2749 double dval = arg.double_value ();
2750
2751 if (! xisnan (dval))
2752 {
2753 int ival = NINT (dval);
2754 if (ival == 1)
2755 rows = 1;
2756 else if (ival == 0)
2757 rows = 0;
2758 else
2759 break;
2760 }
2761 else
2762 break;
2763 }
2764 else
2765 break;
2766
2767 // If only one index, cols will not be set, so we set it.
2768 // If single index is [], rows will be zero, and we should
2769 // set cols to zero too.
2770
2771 if (cols < 0)
2772 {
2773 if (rows == 0)
2774 cols = 0;
2775 else
2776 {
2777 if (user_pref.prefer_column_vectors)
2778 cols = 1;
2779 else
2780 {
2781 cols = rows;
2782 rows = 1;
2783 }
2784 }
2785 }
2786
2787 if (type_tag == scalar_constant)
2788 {
2789 return Matrix (rows, cols, scalar);
2790 }
2791 else if (type_tag == complex_scalar_constant)
2792 {
2793 return ComplexMatrix (rows, cols, *complex_scalar);
2794 }
2795 else
2796 panic_impossible ();
2797 }
2798 break;
2799
2800 default:
2801 ::error ("invalid number of arguments for scalar type");
2802 return tree_constant ();
2803 break;
2804 }
2805 }
2806
2807 ::error ("index invalid or out of range for scalar type");
2808 return tree_constant ();
2809 }
2810
2811 tree_constant
2812 TC_REP::do_matrix_index (const Octave_object& args) const
2813 {
2814 tree_constant retval;
2815
2816 int nargin = args.length ();
2817
2818 switch (nargin)
2819 {
2820 case 1:
2821 {
2822 tree_constant arg = args(0);
2823
2824 if (arg.is_undefined ())
2825 ::error ("matrix index is a null expression");
2826 else
2827 retval = do_matrix_index (arg);
2828 }
2829 break;
2830
2831 case 2:
2832 {
2833 tree_constant arg_a = args(0);
2834 tree_constant arg_b = args(1);
2835
2836 if (arg_a.is_undefined ())
2837 ::error ("first matrix index is a null expression");
2838 else if (arg_b.is_undefined ())
2839 ::error ("second matrix index is a null expression");
2840 else
2841 retval = do_matrix_index (arg_a, arg_b);
2842 }
2843 break;
2844
2845 default:
2846 if (nargin == 0)
2847 ::error ("matrix indices expected, but none provided");
2848 else
2849 ::error ("too many indices for matrix expression");
2850 break;
2851 }
2852
2853 return retval;
2854 }
2855
2856 tree_constant
2857 TC_REP::do_matrix_index (const tree_constant& i_arg) const
2858 {
2859 tree_constant retval;
2860
2861 int nr = rows ();
2862 int nc = columns ();
2863
2864 if (user_pref.do_fortran_indexing)
2865 retval = fortran_style_matrix_index (i_arg);
2866 else if (nr <= 1 || nc <= 1)
2867 retval = do_vector_index (i_arg);
2868 else
2869 ::error ("single index only valid for row or column vector");
2870
2871 return retval;
2872 }
2873
2874 tree_constant
2875 TC_REP::do_matrix_index (const tree_constant& i_arg,
2876 const tree_constant& j_arg) const
2877 {
2878 tree_constant retval;
2879
2880 tree_constant tmp_i = i_arg.make_numeric_or_range_or_magic ();
2881
2882 if (error_state)
2883 return retval;
2884
2885 TC_REP::constant_type itype = tmp_i.const_type ();
2886
2887 switch (itype)
2888 {
2889 case complex_scalar_constant:
2890 case scalar_constant:
2891 {
2892 int i = tree_to_mat_idx (tmp_i.double_value ());
2893 retval = do_matrix_index (i, j_arg);
2894 }
2895 break;
2896
2897 case complex_matrix_constant:
2898 case matrix_constant:
2899 {
2900 Matrix mi = tmp_i.matrix_value ();
2901 idx_vector iv (mi, user_pref.do_fortran_indexing, "row", rows ());
2902 if (! iv)
2903 return tree_constant ();
2904
2905 if (iv.length () == 0)
2906 {
2907 Matrix mtmp;
2908 retval = mtmp;
2909 }
2910 else
2911 retval = do_matrix_index (iv, j_arg);
2912 }
2913 break;
2914
2915 case string_constant:
2916 gripe_string_invalid ();
2917 break;
2918
2919 case range_constant:
2920 {
2921 Range ri = tmp_i.range_value ();
2922 int nr = rows ();
2923 if (nr == 2 && is_zero_one (ri))
2924 {
2925 retval = do_matrix_index (1, j_arg);
2926 }
2927 else if (nr == 2 && is_one_zero (ri))
2928 {
2929 retval = do_matrix_index (0, j_arg);
2930 }
2931 else
2932 {
2933 if (index_check (ri, "row") < 0)
2934 return tree_constant ();
2935 retval = do_matrix_index (ri, j_arg);
2936 }
2937 }
2938 break;
2939
2940 case magic_colon:
2941 retval = do_matrix_index (magic_colon, j_arg);
2942 break;
2943
2944 default:
2945 panic_impossible ();
2946 break;
2947 }
2948
2949 return retval;
2950 }
2951
2952 tree_constant
2953 TC_REP::do_matrix_index (TC_REP::constant_type mci) const
2954 {
2955 assert (mci == magic_colon);
2956
2957 tree_constant retval;
2958 int nr = rows ();
2959 int nc = columns ();
2960 int size = nr * nc;
2961 if (size > 0)
2962 {
2963 CRMATRIX (m, cm, size, 1);
2964 int idx = 0;
2965 for (int j = 0; j < nc; j++)
2966 for (int i = 0; i < nr; i++)
2967 {
2968 CRMATRIX_ASSIGN_REP_ELEM (m, cm, idx, 0, i, j);
2969 idx++;
2970 }
2971 ASSIGN_CRMATRIX_TO (retval, m, cm);
2972 }
2973 return retval;
2974 }
2975
2976 tree_constant
2977 TC_REP::fortran_style_matrix_index (const tree_constant& i_arg) const
2978 {
2979 tree_constant retval;
2980
2981 tree_constant tmp_i = i_arg.make_numeric_or_magic ();
2982
2983 if (error_state)
2984 return retval;
2985
2986 TC_REP::constant_type itype = tmp_i.const_type ();
2987
2988 int nr = rows ();
2989 int nc = columns ();
2990
2991 switch (itype)
2992 {
2993 case complex_scalar_constant:
2994 case scalar_constant:
2995 {
2996 double dval = tmp_i.double_value ();
2997
2998 if (xisnan (dval))
2999 {
3000 ::error ("NaN is invalid as a matrix index");
3001 return tree_constant ();
3002 }
3003 else
3004 {
3005 int i = NINT (dval);
3006 int ii = fortran_row (i, nr) - 1;
3007 int jj = fortran_column (i, nr) - 1;
3008 if (index_check (i-1, "") < 0)
3009 return tree_constant ();
3010 if (range_max_check (i-1, nr * nc) < 0)
3011 return tree_constant ();
3012 retval = do_matrix_index (ii, jj);
3013 }
3014 }
3015 break;
3016
3017 case complex_matrix_constant:
3018 case matrix_constant:
3019 {
3020 Matrix mi = tmp_i.matrix_value ();
3021 if (mi.rows () == 0 || mi.columns () == 0)
3022 {
3023 Matrix mtmp;
3024 retval = mtmp;
3025 }
3026 else
3027 {
3028 // Yes, we really do want to call this with mi.
3029
3030 retval = fortran_style_matrix_index (mi);
3031 }
3032 }
3033 break;
3034
3035 case string_constant:
3036 gripe_string_invalid ();
3037 break;
3038
3039 case range_constant:
3040 gripe_range_invalid ();
3041 break;
3042
3043 case magic_colon:
3044 retval = do_matrix_index (magic_colon);
3045 break;
3046
3047 default:
3048 panic_impossible ();
3049 break;
3050 }
3051
3052 return retval;
3053 }
3054
3055 tree_constant
3056 TC_REP::fortran_style_matrix_index (const Matrix& mi) const
3057 {
3058 assert (is_matrix_type ());
3059
3060 tree_constant retval;
3061
3062 int nr = rows ();
3063 int nc = columns ();
3064
3065 int len = nr * nc;
3066
3067 int index_nr = mi.rows ();
3068 int index_nc = mi.columns ();
3069
3070 if (index_nr >= 1 && index_nc >= 1)
3071 {
3072 const double *cop_out = 0;
3073 const Complex *c_cop_out = 0;
3074 int real_type = type_tag == matrix_constant;
3075 if (real_type)
3076 cop_out = matrix->data ();
3077 else
3078 c_cop_out = complex_matrix->data ();
3079
3080 const double *cop_out_index = mi.data ();
3081
3082 idx_vector iv (mi, 1, "", len);
3083 if (! iv || range_max_check (iv.max (), len) < 0)
3084 return retval;
3085
3086 int result_size = iv.length ();
3087
3088 // XXX FIXME XXX -- there is way too much duplicate code
3089 // here...
3090
3091 if (iv.one_zero_only ())
3092 {
3093 if (iv.ones_count () == 0)
3094 {
3095 retval = Matrix ();
3096 }
3097 else
3098 {
3099 if (nr == 1)
3100 {
3101 CRMATRIX (m, cm, 1, result_size);
3102
3103 for (int i = 0; i < result_size; i++)
3104 {
3105 int idx = iv.elem (i);
3106 CRMATRIX_ASSIGN_ELEM (m, cm, 0, i, cop_out [idx],
3107 c_cop_out [idx], real_type);
3108 }
3109
3110 ASSIGN_CRMATRIX_TO (retval, m, cm);
3111 }
3112 else
3113 {
3114 CRMATRIX (m, cm, result_size, 1);
3115
3116 for (int i = 0; i < result_size; i++)
3117 {
3118 int idx = iv.elem (i);
3119 CRMATRIX_ASSIGN_ELEM (m, cm, i, 0, cop_out [idx],
3120 c_cop_out [idx], real_type);
3121 }
3122
3123 ASSIGN_CRMATRIX_TO (retval, m, cm);
3124 }
3125 }
3126 }
3127 else if (nc == 1)
3128 {
3129 CRMATRIX (m, cm, result_size, 1);
3130
3131 for (int i = 0; i < result_size; i++)
3132 {
3133 int idx = iv.elem (i);
3134 CRMATRIX_ASSIGN_ELEM (m, cm, i, 0, cop_out [idx],
3135 c_cop_out [idx], real_type);
3136 }
3137
3138 ASSIGN_CRMATRIX_TO (retval, m, cm);
3139 }
3140 else if (nr == 1)
3141 {
3142 CRMATRIX (m, cm, 1, result_size);
3143
3144 for (int i = 0; i < result_size; i++)
3145 {
3146 int idx = iv.elem (i);
3147 CRMATRIX_ASSIGN_ELEM (m, cm, 0, i, cop_out [idx],
3148 c_cop_out [idx], real_type);
3149 }
3150
3151 ASSIGN_CRMATRIX_TO (retval, m, cm);
3152 }
3153 else
3154 {
3155 CRMATRIX (m, cm, index_nr, index_nc);
3156
3157 for (int j = 0; j < index_nc; j++)
3158 for (int i = 0; i < index_nr; i++)
3159 {
3160 double tmp = *cop_out_index++;
3161 int idx = tree_to_mat_idx (tmp);
3162 CRMATRIX_ASSIGN_ELEM (m, cm, i, j, cop_out [idx],
3163 c_cop_out [idx], real_type);
3164 }
3165
3166 ASSIGN_CRMATRIX_TO (retval, m, cm);
3167 }
3168 }
3169 else
3170 {
3171 if (index_nr == 0 || index_nc == 0)
3172 ::error ("empty matrix invalid as index");
3173 else
3174 ::error ("invalid matrix index");
3175 return tree_constant ();
3176 }
3177
3178 return retval;
3179 }
3180
3181 tree_constant
3182 TC_REP::do_vector_index (const tree_constant& i_arg) const
3183 {
3184 tree_constant retval;
3185
3186 tree_constant tmp_i = i_arg.make_numeric_or_range_or_magic ();
3187
3188 if (error_state)
3189 return retval;
3190
3191 TC_REP::constant_type itype = tmp_i.const_type ();
3192
3193 int nr = rows ();
3194 int nc = columns ();
3195
3196 int len = MAX (nr, nc);
3197
3198 assert ((nr == 1 || nc == 1) && ! user_pref.do_fortran_indexing);
3199
3200 int swap_indices = (nr == 1);
3201
3202 switch (itype)
3203 {
3204 case complex_scalar_constant:
3205 case scalar_constant:
3206 {
3207 int i = tree_to_mat_idx (tmp_i.double_value ());
3208 if (index_check (i, "") < 0)
3209 return tree_constant ();
3210 if (swap_indices)
3211 {
3212 if (range_max_check (i, nc) < 0)
3213 return tree_constant ();
3214 retval = do_matrix_index (0, i);
3215 }
3216 else
3217 {
3218 if (range_max_check (i, nr) < 0)
3219 return tree_constant ();
3220 retval = do_matrix_index (i, 0);
3221 }
3222 }
3223 break;
3224
3225 case complex_matrix_constant:
3226 case matrix_constant:
3227 {
3228 Matrix mi = tmp_i.matrix_value ();
3229 if (mi.rows () == 0 || mi.columns () == 0)
3230 {
3231 Matrix mtmp;
3232 retval = mtmp;
3233 }
3234 else
3235 {
3236 idx_vector iv (mi, user_pref.do_fortran_indexing, "", len);
3237 if (! iv)
3238 return tree_constant ();
3239
3240 if (swap_indices)
3241 {
3242 if (range_max_check (iv.max (), nc) < 0)
3243 return tree_constant ();
3244 retval = do_matrix_index (0, iv);
3245 }
3246 else
3247 {
3248 if (range_max_check (iv.max (), nr) < 0)
3249 return tree_constant ();
3250 retval = do_matrix_index (iv, 0);
3251 }
3252 }
3253 }
3254 break;
3255
3256 case string_constant:
3257 gripe_string_invalid ();
3258 break;
3259
3260 case range_constant:
3261 {
3262 Range ri = tmp_i.range_value ();
3263 if (len == 2 && is_zero_one (ri))
3264 {
3265 if (swap_indices)
3266 retval = do_matrix_index (0, 1);
3267 else
3268 retval = do_matrix_index (1, 0);
3269 }
3270 else if (len == 2 && is_one_zero (ri))
3271 {
3272 retval = do_matrix_index (0, 0);
3273 }
3274 else
3275 {
3276 if (index_check (ri, "") < 0)
3277 return tree_constant ();
3278 if (swap_indices)
3279 {
3280 if (range_max_check (tree_to_mat_idx (ri.max ()), nc) < 0)
3281 return tree_constant ();
3282 retval = do_matrix_index (0, ri);
3283 }
3284 else
3285 {
3286 if (range_max_check (tree_to_mat_idx (ri.max ()), nr) < 0)
3287 return tree_constant ();
3288 retval = do_matrix_index (ri, 0);
3289 }
3290 }
3291 }
3292 break;
3293
3294 case magic_colon:
3295 if (swap_indices)
3296 retval = do_matrix_index (0, magic_colon);
3297 else
3298 retval = do_matrix_index (magic_colon, 0);
3299 break;
3300
3301 default:
3302 panic_impossible ();
3303 break;
3304 }
3305
3306 return retval;
3307 }
3308
3309 tree_constant
3310 TC_REP::do_matrix_index (int i, const tree_constant& j_arg) const
3311 {
3312 tree_constant retval;
3313
3314 tree_constant tmp_j = j_arg.make_numeric_or_range_or_magic ();
3315
3316 if (error_state)
3317 return retval;
3318
3319 TC_REP::constant_type jtype = tmp_j.const_type ();
3320
3321 int nr = rows ();
3322 int nc = columns ();
3323
3324 switch (jtype)
3325 {
3326 case complex_scalar_constant:
3327 case scalar_constant:
3328 {
3329 if (index_check (i, "row") < 0)
3330 return tree_constant ();
3331 int j = tree_to_mat_idx (tmp_j.double_value ());
3332 if (index_check (j, "column") < 0)
3333 return tree_constant ();
3334 if (range_max_check (i, j, nr, nc) < 0)
3335 return tree_constant ();
3336 retval = do_matrix_index (i, j);
3337 }
3338 break;
3339
3340 case complex_matrix_constant:
3341 case matrix_constant:
3342 {
3343 if (index_check (i, "row") < 0)
3344 return tree_constant ();
3345 Matrix mj = tmp_j.matrix_value ();
3346 idx_vector jv (mj, user_pref.do_fortran_indexing, "column", nc);
3347 if (! jv)
3348 return tree_constant ();
3349
3350 if (jv.length () == 0)
3351 {
3352 Matrix mtmp;
3353 retval = mtmp;
3354 }
3355 else
3356 {
3357 if (range_max_check (i, jv.max (), nr, nc) < 0)
3358 return tree_constant ();
3359 retval = do_matrix_index (i, jv);
3360 }
3361 }
3362 break;
3363
3364 case string_constant:
3365 gripe_string_invalid ();
3366 break;
3367
3368 case range_constant:
3369 {
3370 if (index_check (i, "row") < 0)
3371 return tree_constant ();
3372 Range rj = tmp_j.range_value ();
3373 if (nc == 2 && is_zero_one (rj))
3374 {
3375 retval = do_matrix_index (i, 1);
3376 }
3377 else if (nc == 2 && is_one_zero (rj))
3378 {
3379 retval = do_matrix_index (i, 0);
3380 }
3381 else
3382 {
3383 if (index_check (rj, "column") < 0)
3384 return tree_constant ();
3385 if (range_max_check (i, tree_to_mat_idx (rj.max ()), nr, nc) < 0)
3386 return tree_constant ();
3387 retval = do_matrix_index (i, rj);
3388 }
3389 }
3390 break;
3391
3392 case magic_colon:
3393 if (i == -1 && nr == 1)
3394 return Matrix ();
3395 if (index_check (i, "row") < 0
3396 || range_max_check (i, 0, nr, nc) < 0)
3397 return tree_constant ();
3398 retval = do_matrix_index (i, magic_colon);
3399 break;
3400
3401 default:
3402 panic_impossible ();
3403 break;
3404 }
3405
3406 return retval;
3407 }
3408
3409 tree_constant
3410 TC_REP::do_matrix_index (const idx_vector& iv,
3411 const tree_constant& j_arg) const
3412 {
3413 tree_constant retval;
3414
3415 tree_constant tmp_j = j_arg.make_numeric_or_range_or_magic ();
3416
3417 if (error_state)
3418 return retval;
3419
3420 TC_REP::constant_type jtype = tmp_j.const_type ();
3421
3422 int nr = rows ();
3423 int nc = columns ();
3424
3425 switch (jtype)
3426 {
3427 case complex_scalar_constant:
3428 case scalar_constant:
3429 {
3430 int j = tree_to_mat_idx (tmp_j.double_value ());
3431 if (index_check (j, "column") < 0)
3432 return tree_constant ();
3433 if (range_max_check (iv.max (), j, nr, nc) < 0)
3434 return tree_constant ();
3435 retval = do_matrix_index (iv, j);
3436 }
3437 break;
3438
3439 case complex_matrix_constant:
3440 case matrix_constant:
3441 {
3442 Matrix mj = tmp_j.matrix_value ();
3443 idx_vector jv (mj, user_pref.do_fortran_indexing, "column", nc);
3444 if (! jv)
3445 return tree_constant ();
3446
3447 if (jv.length () == 0)
3448 {
3449 Matrix mtmp;
3450 retval = mtmp;
3451 }
3452 else
3453 {
3454 if (range_max_check (iv.max (), jv.max (), nr, nc) < 0)
3455 return tree_constant ();
3456 retval = do_matrix_index (iv, jv);
3457 }
3458 }
3459 break;
3460
3461 case string_constant:
3462 gripe_string_invalid ();
3463 break;
3464
3465 case range_constant:
3466 {
3467 Range rj = tmp_j.range_value ();
3468 if (nc == 2 && is_zero_one (rj))
3469 {
3470 retval = do_matrix_index (iv, 1);
3471 }
3472 else if (nc == 2 && is_one_zero (rj))
3473 {
3474 retval = do_matrix_index (iv, 0);
3475 }
3476 else
3477 {
3478 if (index_check (rj, "column") < 0)
3479 return tree_constant ();
3480 if (range_max_check (iv.max (), tree_to_mat_idx (rj.max ()),
3481 nr, nc) < 0)
3482 return tree_constant ();
3483 retval = do_matrix_index (iv, rj);
3484 }
3485 }
3486 break;
3487
3488 case magic_colon:
3489 if (range_max_check (iv.max (), 0, nr, nc) < 0)
3490 return tree_constant ();
3491 retval = do_matrix_index (iv, magic_colon);
3492 break;
3493
3494 default:
3495 panic_impossible ();
3496 break;
3497 }
3498
3499 return retval;
3500 }
3501
3502 tree_constant
3503 TC_REP::do_matrix_index (const Range& ri,
3504 const tree_constant& j_arg) const
3505 {
3506 tree_constant retval;
3507
3508 tree_constant tmp_j = j_arg.make_numeric_or_range_or_magic ();
3509
3510 if (error_state)
3511 return retval;
3512
3513 TC_REP::constant_type jtype = tmp_j.const_type ();
3514
3515 int nr = rows ();
3516 int nc = columns ();
3517
3518 switch (jtype)
3519 {
3520 case complex_scalar_constant:
3521 case scalar_constant:
3522 {
3523 int j = tree_to_mat_idx (tmp_j.double_value ());
3524 if (index_check (j, "column") < 0)
3525 return tree_constant ();
3526 if (range_max_check (tree_to_mat_idx (ri.max ()), j, nr, nc) < 0)
3527 return tree_constant ();
3528 retval = do_matrix_index (ri, j);
3529 }
3530 break;
3531
3532 case complex_matrix_constant:
3533 case matrix_constant:
3534 {
3535 Matrix mj = tmp_j.matrix_value ();
3536 idx_vector jv (mj, user_pref.do_fortran_indexing, "column", nc);
3537 if (! jv)
3538 return tree_constant ();
3539
3540 if (jv.length () == 0)
3541 {
3542 Matrix mtmp;
3543 retval = mtmp;
3544 }
3545 else
3546 {
3547 if (range_max_check (tree_to_mat_idx (ri.max ()),
3548 jv.max (), nr, nc) < 0)
3549 return tree_constant ();
3550 retval = do_matrix_index (ri, jv);
3551 }
3552 }
3553 break;
3554
3555 case string_constant:
3556 gripe_string_invalid ();
3557 break;
3558
3559 case range_constant:
3560 {
3561 Range rj = tmp_j.range_value ();
3562 if (nc == 2 && is_zero_one (rj))
3563 {
3564 retval = do_matrix_index (ri, 1);
3565 }
3566 else if (nc == 2 && is_one_zero (rj))
3567 {
3568 retval = do_matrix_index (ri, 0);
3569 }
3570 else
3571 {
3572 if (index_check (rj, "column") < 0)
3573 return tree_constant ();
3574 if (range_max_check (tree_to_mat_idx (ri.max ()),
3575 tree_to_mat_idx (rj.max ()), nr, nc) < 0)
3576 return tree_constant ();
3577 retval = do_matrix_index (ri, rj);
3578 }
3579 }
3580 break;
3581
3582 case magic_colon:
3583 {
3584 if (index_check (ri, "row") < 0)
3585 return tree_constant ();
3586 if (range_max_check (tree_to_mat_idx (ri.max ()), 0, nr, nc) < 0)
3587 return tree_constant ();
3588 retval = do_matrix_index (ri, magic_colon);
3589 }
3590 break;
3591
3592 default:
3593 panic_impossible ();
3594 break;
3595 }
3596
3597 return retval;
3598 }
3599
3600 tree_constant
3601 TC_REP::do_matrix_index (TC_REP::constant_type /* mci */,
3602 const tree_constant& j_arg) const
3603 {
3604 tree_constant retval;
3605
3606 tree_constant tmp_j = j_arg.make_numeric_or_range_or_magic ();
3607
3608 if (error_state)
3609 return retval;
3610
3611 TC_REP::constant_type jtype = tmp_j.const_type ();
3612
3613 int nr = rows ();
3614 int nc = columns ();
3615
3616 switch (jtype)
3617 {
3618 case complex_scalar_constant:
3619 case scalar_constant:
3620 {
3621 int j = tree_to_mat_idx (tmp_j.double_value ());
3622 if (j == -1 && nc == 1)
3623 return Matrix ();
3624 if (index_check (j, "column") < 0)
3625 return tree_constant ();
3626 if (range_max_check (0, j, nr, nc) < 0)
3627 return tree_constant ();
3628 retval = do_matrix_index (magic_colon, j);
3629 }
3630 break;
3631
3632 case complex_matrix_constant:
3633 case matrix_constant:
3634 {
3635 Matrix mj = tmp_j.matrix_value ();
3636 idx_vector jv (mj, user_pref.do_fortran_indexing, "column", nc);
3637 if (! jv)
3638 return tree_constant ();
3639
3640 if (jv.length () == 0)
3641 {
3642 Matrix mtmp;
3643 retval = mtmp;
3644 }
3645 else
3646 {
3647 if (range_max_check (0, jv.max (), nr, nc) < 0)
3648 return tree_constant ();
3649 retval = do_matrix_index (magic_colon, jv);
3650 }
3651 }
3652 break;
3653
3654 case string_constant:
3655 gripe_string_invalid ();
3656 break;
3657
3658 case range_constant:
3659 {
3660 Range rj = tmp_j.range_value ();
3661 if (nc == 2 && is_zero_one (rj))
3662 {
3663 retval = do_matrix_index (magic_colon, 1);
3664 }
3665 else if (nc == 2 && is_one_zero (rj))
3666 {
3667 retval = do_matrix_index (magic_colon, 0);
3668 }
3669 else
3670 {
3671 if (index_check (rj, "column") < 0)
3672 return tree_constant ();
3673 if (range_max_check (0, tree_to_mat_idx (rj.max ()), nr, nc) < 0)
3674 return tree_constant ();
3675 retval = do_matrix_index (magic_colon, rj);
3676 }
3677 }
3678 break;
3679
3680 case magic_colon:
3681 retval = do_matrix_index (magic_colon, magic_colon);
3682 break;
3683
3684 default:
3685 panic_impossible ();
3686 break;
3687 }
3688
3689 return retval;
3690 }
3691
3692 tree_constant
3693 TC_REP::do_matrix_index (int i, int j) const
3694 {
3695 tree_constant retval;
3696
3697 if (type_tag == matrix_constant)
3698 retval = matrix->elem (i, j);
3699 else
3700 retval = complex_matrix->elem (i, j);
3701
3702 return retval;
3703 }
3704
3705 tree_constant
3706 TC_REP::do_matrix_index (int i, const idx_vector& jv) const
3707 {
3708 tree_constant retval;
3709
3710 int jlen = jv.capacity ();
3711
3712 CRMATRIX (m, cm, 1, jlen);
3713
3714 for (int j = 0; j < jlen; j++)
3715 {
3716 int col = jv.elem (j);
3717 CRMATRIX_ASSIGN_REP_ELEM (m, cm, 0, j, i, col);
3718 }
3719 ASSIGN_CRMATRIX_TO (retval, m, cm);
3720
3721 return retval;
3722 }
3723
3724 tree_constant
3725 TC_REP::do_matrix_index (int i, const Range& rj) const
3726 {
3727 tree_constant retval;
3728
3729 int jlen = rj.nelem ();
3730
3731 CRMATRIX (m, cm, 1, jlen);
3732
3733 double b = rj.base ();
3734 double increment = rj.inc ();
3735 for (int j = 0; j < jlen; j++)
3736 {
3737 double tmp = b + j * increment;
3738 int col = tree_to_mat_idx (tmp);
3739 CRMATRIX_ASSIGN_REP_ELEM (m, cm, 0, j, i, col);
3740 }
3741
3742 ASSIGN_CRMATRIX_TO (retval, m, cm);
3743
3744 return retval;
3745 }
3746
3747 tree_constant
3748 TC_REP::do_matrix_index (int i, TC_REP::constant_type mcj) const
3749 {
3750 assert (mcj == magic_colon);
3751
3752 tree_constant retval;
3753
3754 int nc = columns ();
3755
3756 CRMATRIX (m, cm, 1, nc);
3757
3758 for (int j = 0; j < nc; j++)
3759 {
3760 CRMATRIX_ASSIGN_REP_ELEM (m, cm, 0, j, i, j);
3761 }
3762
3763 ASSIGN_CRMATRIX_TO (retval, m, cm);
3764
3765 return retval;
3766 }
3767
3768 tree_constant
3769 TC_REP::do_matrix_index (const idx_vector& iv, int j) const
3770 {
3771 tree_constant retval;
3772
3773 int ilen = iv.capacity ();
3774
3775 CRMATRIX (m, cm, ilen, 1);
3776
3777 for (int i = 0; i < ilen; i++)
3778 {
3779 int row = iv.elem (i);
3780 CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, 0, row, j);
3781 }
3782
3783 ASSIGN_CRMATRIX_TO (retval, m, cm);
3784
3785 return retval;
3786 }
3787
3788 tree_constant
3789 TC_REP::do_matrix_index (const idx_vector& iv, const idx_vector& jv) const
3790 {
3791 tree_constant retval;
3792
3793 int ilen = iv.capacity ();
3794 int jlen = jv.capacity ();
3795
3796 CRMATRIX (m, cm, ilen, jlen);
3797
3798 for (int i = 0; i < ilen; i++)
3799 {
3800 int row = iv.elem (i);
3801 for (int j = 0; j < jlen; j++)
3802 {
3803 int col = jv.elem (j);
3804 CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, row, col);
3805 }
3806 }
3807
3808 ASSIGN_CRMATRIX_TO (retval, m, cm);
3809
3810 return retval;
3811 }
3812
3813 tree_constant
3814 TC_REP::do_matrix_index (const idx_vector& iv, const Range& rj) const
3815 {
3816 tree_constant retval;
3817
3818 int ilen = iv.capacity ();
3819 int jlen = rj.nelem ();
3820
3821 CRMATRIX (m, cm, ilen, jlen);
3822
3823 double b = rj.base ();
3824 double increment = rj.inc ();
3825
3826 for (int i = 0; i < ilen; i++)
3827 {
3828 int row = iv.elem (i);
3829 for (int j = 0; j < jlen; j++)
3830 {
3831 double tmp = b + j * increment;
3832 int col = tree_to_mat_idx (tmp);
3833 CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, row, col);
3834 }
3835 }
3836
3837 ASSIGN_CRMATRIX_TO (retval, m, cm);
3838
3839 return retval;
3840 }
3841
3842 tree_constant
3843 TC_REP::do_matrix_index (const idx_vector& iv,
3844 TC_REP::constant_type mcj) const
3845 {
3846 assert (mcj == magic_colon);
3847
3848 tree_constant retval;
3849
3850 int nc = columns ();
3851 int ilen = iv.capacity ();
3852
3853 CRMATRIX (m, cm, ilen, nc);
3854
3855 for (int j = 0; j < nc; j++)
3856 {
3857 for (int i = 0; i < ilen; i++)
3858 {
3859 int row = iv.elem (i);
3860 CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, row, j);
3861 }
3862 }
3863
3864 ASSIGN_CRMATRIX_TO (retval, m, cm);
3865
3866 return retval;
3867 }
3868
3869 tree_constant
3870 TC_REP::do_matrix_index (const Range& ri, int j) const
3871 {
3872 tree_constant retval;
3873
3874 int ilen = ri.nelem ();
3875
3876 CRMATRIX (m, cm, ilen, 1);
3877
3878 double b = ri.base ();
3879 double increment = ri.inc ();
3880 for (int i = 0; i < ilen; i++)
3881 {
3882 double tmp = b + i * increment;
3883 int row = tree_to_mat_idx (tmp);
3884 CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, 0, row, j);
3885 }
3886
3887 ASSIGN_CRMATRIX_TO (retval, m, cm);
3888
3889 return retval;
3890 }
3891
3892 tree_constant
3893 TC_REP::do_matrix_index (const Range& ri,
3894 const idx_vector& jv) const
3895 {
3896 tree_constant retval;
3897
3898 int ilen = ri.nelem ();
3899 int jlen = jv.capacity ();
3900
3901 CRMATRIX (m, cm, ilen, jlen);
3902
3903 double b = ri.base ();
3904 double increment = ri.inc ();
3905 for (int i = 0; i < ilen; i++)
3906 {
3907 double tmp = b + i * increment;
3908 int row = tree_to_mat_idx (tmp);
3909 for (int j = 0; j < jlen; j++)
3910 {
3911 int col = jv.elem (j);
3912 CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, row, col);
3913 }
3914 }
3915
3916 ASSIGN_CRMATRIX_TO (retval, m, cm);
3917
3918 return retval;
3919 }
3920
3921 tree_constant
3922 TC_REP::do_matrix_index (const Range& ri, const Range& rj) const
3923 {
3924 tree_constant retval;
3925
3926 int ilen = ri.nelem ();
3927 int jlen = rj.nelem ();
3928
3929 CRMATRIX (m, cm, ilen, jlen);
3930
3931 double ib = ri.base ();
3932 double iinc = ri.inc ();
3933 double jb = rj.base ();
3934 double jinc = rj.inc ();
3935
3936 for (int i = 0; i < ilen; i++)
3937 {
3938 double itmp = ib + i * iinc;
3939 int row = tree_to_mat_idx (itmp);
3940 for (int j = 0; j < jlen; j++)
3941 {
3942 double jtmp = jb + j * jinc;
3943 int col = tree_to_mat_idx (jtmp);
3944
3945 CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, row, col);
3946 }
3947 }
3948
3949 ASSIGN_CRMATRIX_TO (retval, m, cm);
3950
3951 return retval;
3952 }
3953
3954 tree_constant
3955 TC_REP::do_matrix_index (const Range& ri, TC_REP::constant_type mcj) const
3956 {
3957 assert (mcj == magic_colon);
3958
3959 tree_constant retval;
3960
3961 int nc = columns ();
3962
3963 int ilen = ri.nelem ();
3964
3965 CRMATRIX (m, cm, ilen, nc);
3966
3967 double ib = ri.base ();
3968 double iinc = ri.inc ();
3969
3970 for (int i = 0; i < ilen; i++)
3971 {
3972 double itmp = ib + i * iinc;
3973 int row = tree_to_mat_idx (itmp);
3974 for (int j = 0; j < nc; j++)
3975 {
3976 CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, row, j);
3977 }
3978 }
3979
3980 ASSIGN_CRMATRIX_TO (retval, m, cm);
3981
3982 return retval;
3983 }
3984
3985 tree_constant
3986 TC_REP::do_matrix_index (TC_REP::constant_type mci, int j) const
3987 {
3988 assert (mci == magic_colon);
3989
3990 tree_constant retval;
3991
3992 int nr = rows ();
3993
3994 CRMATRIX (m, cm, nr, 1);
3995
3996 for (int i = 0; i < nr; i++)
3997 {
3998 CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, 0, i, j);
3999 }
4000
4001 ASSIGN_CRMATRIX_TO (retval, m, cm);
4002
4003 return retval;
4004 }
4005
4006 tree_constant
4007 TC_REP::do_matrix_index (TC_REP::constant_type mci,
4008 const idx_vector& jv) const
4009 {
4010 assert (mci == magic_colon);
4011
4012 tree_constant retval;
4013
4014 int nr = rows ();
4015 int jlen = jv.capacity ();
4016
4017 CRMATRIX (m, cm, nr, jlen);
4018
4019 for (int i = 0; i < nr; i++)
4020 {
4021 for (int j = 0; j < jlen; j++)
4022 {
4023 int col = jv.elem (j);
4024 CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, i, col);
4025 }
4026 }
4027
4028 ASSIGN_CRMATRIX_TO (retval, m, cm);
4029
4030 return retval;
4031 }
4032
4033 tree_constant
4034 TC_REP::do_matrix_index (TC_REP::constant_type mci, const Range& rj) const
4035 {
4036 assert (mci == magic_colon);
4037
4038 tree_constant retval;
4039
4040 int nr = rows ();
4041 int jlen = rj.nelem ();
4042
4043 CRMATRIX (m, cm, nr, jlen);
4044
4045 double jb = rj.base ();
4046 double jinc = rj.inc ();
4047
4048 for (int j = 0; j < jlen; j++)
4049 {
4050 double jtmp = jb + j * jinc;
4051 int col = tree_to_mat_idx (jtmp);
4052 for (int i = 0; i < nr; i++)
4053 {
4054 CRMATRIX_ASSIGN_REP_ELEM (m, cm, i, j, i, col);
4055 }
4056 }
4057
4058 ASSIGN_CRMATRIX_TO (retval, m, cm);
4059
4060 return retval;
4061 }
4062
4063 tree_constant
4064 TC_REP::do_matrix_index (TC_REP::constant_type mci,
4065 TC_REP::constant_type mcj) const
4066 {
4067 tree_constant retval;
4068
4069 assert (mci == magic_colon && mcj == magic_colon);
4070
4071 switch (type_tag)
4072 {
4073 case complex_scalar_constant:
4074 retval = *complex_scalar;
4075 break;
4076
4077 case scalar_constant:
4078 retval = scalar;
4079 break;
4080
4081 case complex_matrix_constant:
4082 retval = *complex_matrix;
4083 break;
4084
4085 case matrix_constant:
4086 retval = *matrix;
4087 break;
4088
4089 case range_constant:
4090 retval = *range;
4091 break;
4092
4093 case string_constant:
4094 retval = *str_obj;
4095 break;
4096
4097 case magic_colon:
4098 default:
4099 panic_impossible ();
4100 break;
4101 }
4102
4103 return retval;
4104 }
4105
4106 // -------------------------------------------------------------------
4107 //
4108 // Assignment operations for the tree-constant representation class. 2732 // Assignment operations for the tree-constant representation class.
4109 //
4110 // Leave the commented #includes below to make it easy to split this
4111 // out again, should we want to do that.
4112 //
4113 // -------------------------------------------------------------------
4114
4115 // #ifdef HAVE_CONFIG_H
4116 // #include <config.h>
4117 // #endif
4118
4119 // #include <cctype>
4120 // #include <cstring>
4121
4122 // #include <fstream.h>
4123 // #include <iostream.h>
4124 // #include <strstream.h>
4125
4126 // #include "mx-base.h"
4127 // #include "Range.h"
4128
4129 // #include "arith-ops.h"
4130 // #include "variables.h"
4131 // #include "sysdep.h"
4132 // #include "error.h"
4133 // #include "gripes.h"
4134 // #include "user-prefs.h"
4135 // #include "utils.h"
4136 // #include "pager.h"
4137 // #include "pr-output.h"
4138 // #include "tree-const.h"
4139 // #include "idx-vector.h"
4140 // #include "oct-map.h"
4141
4142 // #include "tc-inlines.h"
4143 2733
4144 // Top-level tree-constant function that handles assignments. Only 2734 // Top-level tree-constant function that handles assignments. Only
4145 // decide if the left-hand side is currently a scalar or a matrix and 2735 // decide if the left-hand side is currently a scalar or a matrix and
4146 // hand off to other functions to do the real work. 2736 // hand off to other functions to do the real work.
2737
2738 extern void assign (Array2<Complex>&, const Array2<Complex>&);
2739 extern void assign (Array2<Complex>&, const Array2<double>&);
2740 extern void assign (Array2<double>&, const Array2<double>&);
4147 2741
4148 void 2742 void
4149 TC_REP::assign (tree_constant& rhs, const Octave_object& args) 2743 TC_REP::assign (tree_constant& rhs, const Octave_object& args)
4150 { 2744 {
4151 tree_constant rhs_tmp = rhs.make_numeric (); 2745 tree_constant rhs_tmp = rhs.make_numeric ();
4162 force_numeric (); 2756 force_numeric ();
4163 2757
4164 if (error_state) 2758 if (error_state)
4165 return; 2759 return;
4166 2760
4167 switch (type_tag) 2761 // Do this before setting the index so that we don't have to copy
4168 { 2762 // indices in the Array class.
4169 case complex_scalar_constant: 2763
4170 case scalar_constant: 2764 maybe_widen (rhs.const_type ());
4171 case unknown_constant: 2765
4172 do_scalar_assignment (rhs_tmp, args); 2766 set_index (args);
4173 break; 2767
4174 2768 if (! error_state)
4175 case complex_matrix_constant: 2769 {
4176 case matrix_constant: 2770 switch (type_tag)
4177 do_matrix_assignment (rhs_tmp, args); 2771 {
4178 break; 2772 case complex_matrix_constant:
4179
4180 default:
4181 ::error ("invalid assignment to %s", type_as_string ());
4182 break;
4183 }
4184 }
4185
4186 // Assignments to scalars. If resize_on_range_error is true,
4187 // this can convert the left-hand side to a matrix.
4188
4189 void
4190 TC_REP::do_scalar_assignment (const tree_constant& rhs,
4191 const Octave_object& args)
4192 {
4193 assert (type_tag == unknown_constant
4194 || type_tag == scalar_constant
4195 || type_tag == complex_scalar_constant);
4196
4197 int nargin = args.length ();
4198
4199 if (rhs.is_zero_by_zero ())
4200 {
4201 if (valid_scalar_indices (args))
4202 {
4203 if (type_tag == complex_scalar_constant)
4204 delete complex_scalar;
4205
4206 matrix = new Matrix (0, 0);
4207 type_tag = matrix_constant;
4208 }
4209 else if (! valid_zero_index (args))
4210 {
4211 ::error ("invalid assigment of empty matrix to scalar");
4212 return;
4213 }
4214 }
4215 else if (rhs.is_scalar_type () && valid_scalar_indices (args))
4216 {
4217 if (type_tag == unknown_constant || type_tag == scalar_constant)
4218 {
4219 if (rhs.const_type () == scalar_constant)
4220 {
4221 scalar = rhs.double_value ();
4222 type_tag = scalar_constant;
4223 }
4224 else if (rhs.const_type () == complex_scalar_constant)
4225 {
4226 complex_scalar = new Complex (rhs.complex_value ());
4227 type_tag = complex_scalar_constant;
4228 }
4229 else
4230 {
4231 ::error ("invalid assignment to scalar");
4232 return;
4233 }
4234 }
4235 else
4236 {
4237 if (rhs.const_type () == scalar_constant)
4238 {
4239 delete complex_scalar;
4240 scalar = rhs.double_value ();
4241 type_tag = scalar_constant;
4242 }
4243 else if (rhs.const_type () == complex_scalar_constant)
4244 {
4245 *complex_scalar = rhs.complex_value ();
4246 type_tag = complex_scalar_constant;
4247 }
4248 else
4249 {
4250 ::error ("invalid assignment to scalar");
4251 return;
4252 }
4253 }
4254 }
4255 else if (user_pref.resize_on_range_error)
4256 {
4257 TC_REP::constant_type old_type_tag = type_tag;
4258
4259 if (type_tag == complex_scalar_constant)
4260 {
4261 Complex *old_complex = complex_scalar;
4262 complex_matrix = new ComplexMatrix (1, 1, *complex_scalar);
4263 type_tag = complex_matrix_constant;
4264 delete old_complex;
4265 }
4266 else if (type_tag == scalar_constant)
4267 {
4268 matrix = new Matrix (1, 1, scalar);
4269 type_tag = matrix_constant;
4270 }
4271
4272 // If there is an error, the call to do_matrix_assignment should
4273 // not destroy the current value. TC_REP::eval(int) will take
4274 // care of converting single element matrices back to scalars.
4275
4276 do_matrix_assignment (rhs, args);
4277
4278 // I don't think there's any other way to revert back to unknown
4279 // constant types, so here it is.
4280
4281 if (old_type_tag == unknown_constant && error_state)
4282 {
4283 if (type_tag == matrix_constant)
4284 delete matrix;
4285 else if (type_tag == complex_matrix_constant)
4286 delete complex_matrix;
4287
4288 type_tag = unknown_constant;
4289 }
4290 }
4291 else if (nargin > 2 || nargin < 1)
4292 ::error ("invalid index expression for scalar type");
4293 else
4294 ::error ("index invalid or out of range for scalar type");
4295 }
4296
4297 // Assignments to matrices (and vectors).
4298 //
4299 // For compatibility with Matlab, we allow assignment of an empty
4300 // matrix to an expression with empty indices to do nothing.
4301
4302 void
4303 TC_REP::do_matrix_assignment (const tree_constant& rhs,
4304 const Octave_object& args)
4305 {
4306 assert (type_tag == unknown_constant
4307 || type_tag == matrix_constant
4308 || type_tag == complex_matrix_constant);
4309
4310 if (type_tag == matrix_constant && rhs.is_complex_type ())
4311 {
4312 Matrix *old_matrix = matrix;
4313 complex_matrix = new ComplexMatrix (*matrix);
4314 type_tag = complex_matrix_constant;
4315 delete old_matrix;
4316 }
4317 else if (type_tag == unknown_constant)
4318 {
4319 if (rhs.is_complex_type ())
4320 {
4321 complex_matrix = new ComplexMatrix ();
4322 type_tag = complex_matrix_constant;
4323 }
4324 else
4325 {
4326 matrix = new Matrix ();
4327 type_tag = matrix_constant;
4328 }
4329 }
4330
4331 int nargin = args.length ();
4332
4333 // The do_matrix_assignment functions can't handle empty matrices,
4334 // so don't let any pass through here.
4335
4336 switch (nargin)
4337 {
4338 case 1:
4339 {
4340 tree_constant arg = args(0);
4341
4342 if (arg.is_undefined ())
4343 ::error ("matrix index is undefined");
4344 else
4345 do_matrix_assignment (rhs, arg);
4346 }
4347 break;
4348
4349 case 2:
4350 {
4351 tree_constant arg_a = args(0);
4352 tree_constant arg_b = args(1);
4353
4354 if (arg_a.is_undefined ())
4355 ::error ("first matrix index is undefined");
4356 else if (arg_b.is_undefined ())
4357 ::error ("second matrix index is undefined");
4358 else if (arg_a.is_empty () || arg_b.is_empty ())
4359 { 2773 {
4360 if (! rhs.is_empty ()) 2774 switch (rhs.const_type ())
4361 { 2775 {
4362 ::error ("in assignment expression, a matrix index is empty"); 2776 case complex_scalar_constant:
4363 ::error ("but the right hand side is not an empty matrix"); 2777 case complex_matrix_constant:
4364 } 2778 ::assign (*complex_matrix, rhs.complex_matrix_value ());
4365 2779 break;
4366 // XXX FIXME XXX -- to really be correct here, we should 2780
4367 // probably check to see if the assignment conforms, but 2781 case scalar_constant:
4368 // that seems like more work than it's worth right now... 2782 case matrix_constant:
4369 } 2783 ::assign (*complex_matrix, rhs.matrix_value ());
4370 else 2784 break;
4371 do_matrix_assignment (rhs, arg_a, arg_b); 2785
4372 } 2786 default:
4373 break; 2787 panic_impossible ();;
4374 2788 break;
4375 default:
4376 if (nargin == 0)
4377 ::error ("matrix indices expected, but none provided");
4378 else
4379 ::error ("too many indices for matrix expression");
4380 break;
4381 }
4382 }
4383
4384 // Matrix assignments indexed by a single value.
4385
4386 void
4387 TC_REP::do_matrix_assignment (const tree_constant& rhs,
4388 const tree_constant& i_arg)
4389 {
4390 int nr = rows ();
4391 int nc = columns ();
4392
4393 if (user_pref.do_fortran_indexing || nr <= 1 || nc <= 1)
4394 {
4395 if (i_arg.is_empty ())
4396 {
4397 if (! rhs.is_empty ())
4398 {
4399 ::error ("in assignment expression, matrix index is empty but");
4400 ::error ("right hand side is not an empty matrix");
4401 }
4402
4403 // XXX FIXME XXX -- to really be correct here, we should
4404 // probably check to see if the assignment conforms, but
4405 // that seems like more work than it's worth right now...
4406
4407 // The assignment functions can't handle empty matrices, so
4408 // don't let any pass through here.
4409
4410 return;
4411 }
4412
4413 // We can't handle the case of assigning to a vector first,
4414 // since even then, the two operations are not equivalent. For
4415 // example, the expression V(:) = M is handled differently
4416 // depending on whether the user specified do_fortran_indexing =
4417 // "true".
4418
4419 if (user_pref.do_fortran_indexing)
4420 fortran_style_matrix_assignment (rhs, i_arg);
4421 else if (nr <= 1 || nc <= 1)
4422 vector_assignment (rhs, i_arg);
4423 else
4424 panic_impossible ();
4425 }
4426 else
4427 ::error ("single index only valid for row or column vector");
4428 }
4429
4430 // Fortran-style assignments. Matrices are assumed to be stored in
4431 // column-major order and it is ok to use a single index for
4432 // multi-dimensional matrices.
4433
4434 void
4435 TC_REP::fortran_style_matrix_assignment (const tree_constant& rhs,
4436 const tree_constant& i_arg)
4437 {
4438 tree_constant tmp_i = i_arg.make_numeric_or_magic ();
4439
4440 if (error_state)
4441 return;
4442
4443 TC_REP::constant_type itype = tmp_i.const_type ();
4444
4445 int nr = rows ();
4446 int nc = columns ();
4447
4448 int rhs_nr = rhs.rows ();
4449 int rhs_nc = rhs.columns ();
4450
4451 switch (itype)
4452 {
4453 case complex_scalar_constant:
4454 case scalar_constant:
4455 {
4456 double dval = tmp_i.double_value ();
4457
4458 if (xisnan (dval))
4459 {
4460 error ("NaN is invalid as a matrix index");
4461 return;
4462 }
4463
4464 int i = NINT (dval);
4465 int idx = i - 1;
4466
4467 if (rhs_nr == 0 && rhs_nc == 0)
4468 {
4469 int len = nr * nc;
4470
4471 if (idx < len && len > 0)
4472 {
4473 convert_to_row_or_column_vector ();
4474
4475 nr = rows ();
4476 nc = columns ();
4477
4478 if (nr == 1)
4479 delete_column (idx);
4480 else if (nc == 1)
4481 delete_row (idx);
4482 else
4483 panic_impossible ();
4484 }
4485 else if (idx < 0)
4486 {
4487 error ("invalid index = %d", idx+1);
4488 }
4489
4490 return;
4491 }
4492
4493 if (index_check (idx, "") < 0)
4494 return;
4495
4496 if (nr <= 1 || nc <= 1)
4497 {
4498 maybe_resize (idx);
4499 if (error_state)
4500 return;
4501 }
4502 else if (range_max_check (idx, nr * nc) < 0)
4503 return;
4504
4505 nr = rows ();
4506 nc = columns ();
4507
4508 if (! indexed_assign_conforms (1, 1, rhs_nr, rhs_nc))
4509 {
4510 ::error ("for A(int) = X: X must be a scalar");
4511 return;
4512 }
4513 int ii = fortran_row (i, nr) - 1;
4514 int jj = fortran_column (i, nr) - 1;
4515 do_matrix_assignment (rhs, ii, jj);
4516 }
4517 break;
4518
4519 case complex_matrix_constant:
4520 case matrix_constant:
4521 {
4522 Matrix mi = tmp_i.matrix_value ();
4523 int len = nr * nc;
4524 idx_vector ii (mi, 1, "", len); // Always do fortran indexing here...
4525 if (! ii)
4526 return;
4527
4528 if (rhs_nr == 0 && rhs_nc == 0)
4529 {
4530 ii.sort_uniq ();
4531 int num_to_delete = 0;
4532 for (int i = 0; i < ii.length (); i++)
4533 {
4534 if (ii.elem (i) < len)
4535 num_to_delete++;
4536 else
4537 break;
4538 }
4539
4540 if (num_to_delete > 0)
4541 {
4542 if (num_to_delete != ii.length ())
4543 ii.shorten (num_to_delete);
4544
4545 convert_to_row_or_column_vector ();
4546
4547 nr = rows ();
4548 nc = columns ();
4549
4550 if (nr == 1)
4551 delete_columns (ii);
4552 else if (nc == 1)
4553 delete_rows (ii);
4554 else
4555 panic_impossible ();
4556 }
4557 return;
4558 }
4559
4560 if (nr <= 1 || nc <= 1)
4561 {
4562 maybe_resize (ii.max ());
4563 if (error_state)
4564 return;
4565 }
4566 else if (range_max_check (ii.max (), len) < 0)
4567 return;
4568
4569 int ilen = ii.capacity ();
4570
4571 if (ilen != rhs_nr * rhs_nc)
4572 {
4573 ::error ("A(matrix) = X: X and matrix must have the same number");
4574 ::error ("of elements");
4575 }
4576 else if (ilen == 1 && rhs.is_scalar_type ())
4577 {
4578 int nr = rows ();
4579 int idx = ii.elem (0);
4580 int ii = fortran_row (idx + 1, nr) - 1;
4581 int jj = fortran_column (idx + 1, nr) - 1;
4582
4583 if (rhs.const_type () == scalar_constant)
4584 matrix->elem (ii, jj) = rhs.double_value ();
4585 else if (rhs.const_type () == complex_scalar_constant)
4586 complex_matrix->elem (ii, jj) = rhs.complex_value ();
4587 else
4588 panic_impossible ();
4589 }
4590 else
4591 fortran_style_matrix_assignment (rhs, ii);
4592 }
4593 break;
4594
4595 case string_constant:
4596 gripe_string_invalid ();
4597 break;
4598
4599 case range_constant:
4600 gripe_range_invalid ();
4601 break;
4602
4603 case magic_colon:
4604
4605 // a(:) = [] is equivalent to a(:,:) = [].
4606
4607 if (rhs_nr == 0 && rhs_nc == 0)
4608 do_matrix_assignment (rhs, magic_colon, magic_colon);
4609 else
4610 fortran_style_matrix_assignment (rhs, magic_colon);
4611 break;
4612
4613 default:
4614 panic_impossible ();
4615 break;
4616 }
4617 }
4618
4619 // Fortran-style assignment for vector index.
4620
4621 void
4622 TC_REP::fortran_style_matrix_assignment (const tree_constant& rhs,
4623 idx_vector& i)
4624 {
4625 assert (rhs.is_matrix_type ());
4626
4627 int ilen = i.capacity ();
4628
4629 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
4630
4631 int len = rhs_nr * rhs_nc;
4632
4633 if (len == ilen)
4634 {
4635 int nr = rows ();
4636 if (rhs.const_type () == matrix_constant)
4637 {
4638 double *cop_out = rhs_m.fortran_vec ();
4639
4640 if (type_tag == matrix_constant)
4641 {
4642 for (int k = 0; k < len; k++)
4643 {
4644 int ii = fortran_row (i.elem (k) + 1, nr) - 1;
4645 int jj = fortran_column (i.elem (k) + 1, nr) - 1;
4646
4647 matrix->elem (ii, jj) = *cop_out++;
4648 }
4649 }
4650 else if (type_tag == complex_matrix_constant)
4651 {
4652 for (int k = 0; k < len; k++)
4653 {
4654 int ii = fortran_row (i.elem (k) + 1, nr) - 1;
4655 int jj = fortran_column (i.elem (k) + 1, nr) - 1;
4656
4657 complex_matrix->elem (ii, jj) = *cop_out++;
4658 }
4659 }
4660 else
4661 panic_impossible ();
4662 }
4663 else
4664 {
4665 Complex *cop_out = rhs_cm.fortran_vec ();
4666 for (int k = 0; k < len; k++)
4667 {
4668 int ii = fortran_row (i.elem (k) + 1, nr) - 1;
4669 int jj = fortran_column (i.elem (k) + 1, nr) - 1;
4670
4671 complex_matrix->elem (ii, jj) = *cop_out++;
4672 }
4673 }
4674 }
4675 else
4676 ::error ("number of rows and columns must match for indexed assignment");
4677 }
4678
4679 // Fortran-style assignment for colon index.
4680
4681 void
4682 TC_REP::fortran_style_matrix_assignment (const tree_constant& rhs,
4683 TC_REP::constant_type mci)
4684 {
4685 assert (rhs.is_matrix_type () && mci == TC_REP::magic_colon);
4686
4687 int nr = rows ();
4688 int nc = columns ();
4689
4690 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
4691
4692 int rhs_size = rhs_nr * rhs_nc;
4693 if (rhs_size == 0)
4694 {
4695 if (rhs.const_type () == matrix_constant)
4696 {
4697 delete matrix;
4698 matrix = new Matrix (0, 0);
4699 return;
4700 }
4701 else
4702 panic_impossible ();
4703 }
4704 else if (nr*nc != rhs_size)
4705 {
4706 ::error ("A(:) = X: X and A must have the same number of elements");
4707 return;
4708 }
4709
4710 if (rhs.const_type () == matrix_constant)
4711 {
4712 double *cop_out = rhs_m.fortran_vec ();
4713 if (type_tag == matrix_constant)
4714 {
4715 for (int j = 0; j < nc; j++)
4716 for (int i = 0; i < nr; i++)
4717 matrix->elem (i, j) = *cop_out++;
4718 }
4719 else if (type_tag == complex_matrix_constant)
4720 {
4721 for (int j = 0; j < nc; j++)
4722 for (int i = 0; i < nr; i++)
4723 complex_matrix->elem (i, j) = *cop_out++;
4724 }
4725 else
4726 panic_impossible ();
4727 }
4728 else
4729 {
4730 Complex *cop_out = rhs_cm.fortran_vec ();
4731 for (int j = 0; j < nc; j++)
4732 for (int i = 0; i < nr; i++)
4733 complex_matrix->elem (i, j) = *cop_out++;
4734 }
4735 }
4736
4737 // Assignments to vectors. Hand off to other functions once we know
4738 // what kind of index we have. For a colon, it is the same as
4739 // assignment to a matrix indexed by two colons.
4740
4741 void
4742 TC_REP::vector_assignment (const tree_constant& rhs,
4743 const tree_constant& i_arg)
4744 {
4745 int nr = rows ();
4746 int nc = columns ();
4747
4748 assert ((nr <= 1 || nc <= 1) && ! user_pref.do_fortran_indexing);
4749
4750 tree_constant tmp_i = i_arg.make_numeric_or_range_or_magic ();
4751
4752 if (error_state)
4753 return;
4754
4755 TC_REP::constant_type itype = tmp_i.const_type ();
4756
4757 switch (itype)
4758 {
4759 case complex_scalar_constant:
4760 case scalar_constant:
4761 {
4762 int i = tree_to_mat_idx (tmp_i.double_value ());
4763 if (index_check (i, "") < 0)
4764 return;
4765 do_vector_assign (rhs, i);
4766 }
4767 break;
4768
4769 case complex_matrix_constant:
4770 case matrix_constant:
4771 {
4772 Matrix mi = tmp_i.matrix_value ();
4773 int len = nr * nc;
4774 idx_vector iv (mi, user_pref.do_fortran_indexing, "", len);
4775 if (! iv)
4776 return;
4777
4778 do_vector_assign (rhs, iv);
4779 }
4780 break;
4781
4782 case string_constant:
4783 gripe_string_invalid ();
4784 break;
4785
4786 case range_constant:
4787 {
4788 Range ri = tmp_i.range_value ();
4789 int len = nr * nc;
4790 if (len == 2 && is_zero_one (ri))
4791 {
4792 do_vector_assign (rhs, 1);
4793 }
4794 else if (len == 2 && is_one_zero (ri))
4795 {
4796 do_vector_assign (rhs, 0);
4797 }
4798 else
4799 {
4800 if (index_check (ri, "") < 0)
4801 return;
4802 do_vector_assign (rhs, ri);
4803 }
4804 }
4805 break;
4806
4807 case magic_colon:
4808 {
4809 int rhs_nr = rhs.rows ();
4810 int rhs_nc = rhs.columns ();
4811
4812 if (! indexed_assign_conforms (nr, nc, rhs_nr, rhs_nc))
4813 {
4814 ::error ("A(:) = X: X and A must have the same dimensions");
4815 return;
4816 }
4817 do_matrix_assignment (rhs, magic_colon, magic_colon);
4818 }
4819 break;
4820
4821 default:
4822 panic_impossible ();
4823 break;
4824 }
4825 }
4826
4827 // Check whether an indexed assignment to a vector is valid.
4828
4829 void
4830 TC_REP::check_vector_assign (int rhs_nr, int rhs_nc, int ilen, const char *rm)
4831 {
4832 int nr = rows ();
4833 int nc = columns ();
4834
4835 if ((nr == 1 && nc == 1) || nr == 0 || nc == 0) // No orientation.
4836 {
4837 if (! (ilen == rhs_nr || ilen == rhs_nc))
4838 {
4839 ::error ("A(%s) = X: X and %s must have the same number of elements",
4840 rm, rm);
4841 }
4842 }
4843 else if (nr == 1) // Preserve current row orientation.
4844 {
4845 if (! (rhs_nr == 1 && rhs_nc == ilen))
4846 {
4847 ::error ("A(%s) = X: where A is a row vector, X must also be a", rm);
4848 ::error ("row vector with the same number of elements as %s", rm);
4849 }
4850 }
4851 else if (nc == 1) // Preserve current column orientation.
4852 {
4853 if (! (rhs_nc == 1 && rhs_nr == ilen))
4854 {
4855 ::error ("A(%s) = X: where A is a column vector, X must also be", rm);
4856 ::error ("a column vector with the same number of elements as %s", rm);
4857 }
4858 }
4859 else
4860 panic_impossible ();
4861 }
4862
4863 // Assignment to a vector with an integer index.
4864
4865 void
4866 TC_REP::do_vector_assign (const tree_constant& rhs, int i)
4867 {
4868 int rhs_nr = rhs.rows ();
4869 int rhs_nc = rhs.columns ();
4870
4871 if (indexed_assign_conforms (1, 1, rhs_nr, rhs_nc))
4872 {
4873 maybe_resize (i);
4874 if (error_state)
4875 return;
4876
4877 int nr = rows ();
4878 int nc = columns ();
4879
4880 if (nr == 1)
4881 {
4882 REP_ELEM_ASSIGN (0, i, rhs.double_value (), rhs.complex_value (),
4883 rhs.is_real_type ());
4884 }
4885 else if (nc == 1)
4886 {
4887 REP_ELEM_ASSIGN (i, 0, rhs.double_value (), rhs.complex_value (),
4888 rhs.is_real_type ());
4889 }
4890 else
4891 panic_impossible ();
4892 }
4893 else if (rhs_nr == 0 && rhs_nc == 0)
4894 {
4895 int nr = rows ();
4896 int nc = columns ();
4897
4898 int len = MAX (nr, nc);
4899
4900 if (i < 0 || i >= len || (nr == 0 && nc == 0))
4901 {
4902 ::error ("A(int) = []: index out of range");
4903 return;
4904 }
4905
4906 if (nr == 0 && nc > 0)
4907 resize (0, nc - 1);
4908 else if (nc == 0 && nr > 0)
4909 resize (nr - 1, 0);
4910 else if (nr == 1)
4911 delete_column (i);
4912 else if (nc == 1)
4913 delete_row (i);
4914 else
4915 panic_impossible ();
4916 }
4917 else
4918 {
4919 ::error ("for A(int) = X: X must be a scalar");
4920 return;
4921 }
4922 }
4923
4924 // Assignment to a vector with a vector index.
4925
4926 void
4927 TC_REP::do_vector_assign (const tree_constant& rhs, idx_vector& iv)
4928 {
4929 if (rhs.is_zero_by_zero ())
4930 {
4931 int nr = rows ();
4932 int nc = columns ();
4933
4934 int len = MAX (nr, nc);
4935
4936 if (iv.max () >= len)
4937 {
4938 ::error ("A(matrix) = []: index out of range");
4939 return;
4940 }
4941
4942 if (nr == 1)
4943 delete_columns (iv);
4944 else if (nc == 1)
4945 delete_rows (iv);
4946 else
4947 panic_impossible ();
4948 }
4949 else if (rhs.is_scalar_type ())
4950 {
4951 int nr = rows ();
4952 int nc = columns ();
4953
4954 if (iv.capacity () == 1)
4955 {
4956 int idx = iv.elem (0);
4957
4958 if (nr == 1)
4959 {
4960 REP_ELEM_ASSIGN (0, idx, rhs.double_value (),
4961 rhs.complex_value (), rhs.is_real_type ());
4962 }
4963 else if (nc == 1)
4964 {
4965 REP_ELEM_ASSIGN (idx, 0, rhs.double_value (),
4966 rhs.complex_value (), rhs.is_real_type ());
4967 }
4968 else
4969 panic_impossible ();
4970 }
4971 else
4972 {
4973 if (nr == 1)
4974 {
4975 ::error ("A(matrix) = X: where A is a row vector, X must also be a");
4976 ::error ("row vector with the same number of elements as matrix");
4977 }
4978 else if (nc == 1)
4979 {
4980 ::error ("A(matrix) = X: where A is a column vector, X must also be a");
4981 ::error ("column vector with the same number of elements as matrix");
4982 }
4983 else if (nr == 0 || nc == 0)
4984 {
4985 ::error ("A(matrix) = X: X must be a vector with the same");
4986 ::error ("number of elements as matrix");
4987 }
4988 else
4989 panic_impossible ();
4990 }
4991 }
4992 else if (rhs.is_matrix_type ())
4993 {
4994 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
4995
4996 int ilen = iv.capacity ();
4997 check_vector_assign (rhs_nr, rhs_nc, ilen, "matrix");
4998 if (error_state)
4999 return;
5000
5001 force_orient f_orient = no_orient;
5002 if (rhs_nr == 1 && rhs_nc != 1)
5003 f_orient = row_orient;
5004 else if (rhs_nc == 1 && rhs_nr != 1)
5005 f_orient = column_orient;
5006
5007 maybe_resize (iv.max (), f_orient);
5008 if (error_state)
5009 return;
5010
5011 int nr = rows ();
5012 int nc = columns ();
5013
5014 if (nr == 1 && rhs_nr == 1)
5015 {
5016 for (int i = 0; i < iv.capacity (); i++)
5017 REP_ELEM_ASSIGN (0, iv.elem (i), rhs_m.elem (0, i),
5018 rhs_cm.elem (0, i), rhs.is_real_type ());
5019 }
5020 else if (nc == 1 && rhs_nc == 1)
5021 {
5022 for (int i = 0; i < iv.capacity (); i++)
5023 REP_ELEM_ASSIGN (iv.elem (i), 0, rhs_m.elem (i, 0),
5024 rhs_cm.elem (i, 0), rhs.is_real_type ());
5025 }
5026 else
5027 ::error ("A(vector) = X: X must be the same size as vector");
5028 }
5029 else
5030 panic_impossible ();
5031 }
5032
5033 // Assignment to a vector with a range index.
5034
5035 void
5036 TC_REP::do_vector_assign (const tree_constant& rhs, Range& ri)
5037 {
5038 if (rhs.is_zero_by_zero ())
5039 {
5040 int nr = rows ();
5041 int nc = columns ();
5042
5043 int len = MAX (nr, nc);
5044
5045 int b = tree_to_mat_idx (ri.min ());
5046 int l = tree_to_mat_idx (ri.max ());
5047 if (b < 0 || l >= len)
5048 {
5049 ::error ("A(range) = []: index out of range");
5050 return;
5051 }
5052
5053 if (nr == 1)
5054 delete_columns (ri);
5055 else if (nc == 1)
5056 delete_rows (ri);
5057 else
5058 panic_impossible ();
5059 }
5060 else if (rhs.is_scalar_type ())
5061 {
5062 int nr = rows ();
5063 int nc = columns ();
5064
5065 if (nr == 1)
5066 {
5067 ::error ("A(range) = X: where A is a row vector, X must also be a");
5068 ::error ("row vector with the same number of elements as range");
5069 }
5070 else if (nc == 1)
5071 {
5072 ::error ("A(range) = X: where A is a column vector, X must also be a");
5073 ::error ("column vector with the same number of elements as range");
5074 }
5075 else if (nr == 0 || nc == 0)
5076 {
5077 ::error ("A(range) = X: X must be a vector with the same");
5078 ::error ("number of elements as range");
5079 }
5080 else
5081 panic_impossible ();
5082 }
5083 else if (rhs.is_matrix_type ())
5084 {
5085 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
5086
5087 int ilen = ri.nelem ();
5088 check_vector_assign (rhs_nr, rhs_nc, ilen, "range");
5089 if (error_state)
5090 return;
5091
5092 force_orient f_orient = no_orient;
5093 if (rhs_nr == 1 && rhs_nc != 1)
5094 f_orient = row_orient;
5095 else if (rhs_nc == 1 && rhs_nr != 1)
5096 f_orient = column_orient;
5097
5098 maybe_resize (tree_to_mat_idx (ri.max ()), f_orient);
5099 if (error_state)
5100 return;
5101
5102 int nr = rows ();
5103 int nc = columns ();
5104
5105 double b = ri.base ();
5106 double increment = ri.inc ();
5107
5108 if (nr == 1)
5109 {
5110 for (int i = 0; i < ri.nelem (); i++)
5111 {
5112 double tmp = b + i * increment;
5113 int col = tree_to_mat_idx (tmp);
5114 REP_ELEM_ASSIGN (0, col, rhs_m.elem (0, i), rhs_cm.elem (0, i),
5115 rhs.is_real_type ());
5116 }
5117 }
5118 else if (nc == 1)
5119 {
5120 for (int i = 0; i < ri.nelem (); i++)
5121 {
5122 double tmp = b + i * increment;
5123 int row = tree_to_mat_idx (tmp);
5124 REP_ELEM_ASSIGN (row, 0, rhs_m.elem (i, 0), rhs_cm.elem (i, 0),
5125 rhs.is_real_type ());
5126 }
5127 }
5128 else
5129 panic_impossible ();
5130 }
5131 else
5132 panic_impossible ();
5133 }
5134
5135 // Matrix assignment indexed by two values. This function determines
5136 // the type of the first arugment, checks as much as possible, and
5137 // then calls one of a set of functions to handle the specific cases:
5138 //
5139 // M (integer, arg2) = RHS (MA1)
5140 // M (vector, arg2) = RHS (MA2)
5141 // M (range, arg2) = RHS (MA3)
5142 // M (colon, arg2) = RHS (MA4)
5143 //
5144 // Each of those functions determines the type of the second argument
5145 // and calls another function to handle the real work of doing the
5146 // assignment.
5147
5148 void
5149 TC_REP::do_matrix_assignment (const tree_constant& rhs,
5150 const tree_constant& i_arg,
5151 const tree_constant& j_arg)
5152 {
5153 tree_constant tmp_i = i_arg.make_numeric_or_range_or_magic ();
5154
5155 if (error_state)
5156 return;
5157
5158 TC_REP::constant_type itype = tmp_i.const_type ();
5159
5160 switch (itype)
5161 {
5162 case complex_scalar_constant:
5163 case scalar_constant:
5164 {
5165 int i = tree_to_mat_idx (tmp_i.double_value ());
5166 do_matrix_assignment (rhs, i, j_arg);
5167 }
5168 break;
5169
5170 case complex_matrix_constant:
5171 case matrix_constant:
5172 {
5173 Matrix mi = tmp_i.matrix_value ();
5174 idx_vector iv (mi, user_pref.do_fortran_indexing, "row", rows ());
5175 if (! iv)
5176 return;
5177
5178 do_matrix_assignment (rhs, iv, j_arg);
5179 }
5180 break;
5181
5182 case string_constant:
5183 gripe_string_invalid ();
5184 break;
5185
5186 case range_constant:
5187 {
5188 Range ri = tmp_i.range_value ();
5189 int nr = rows ();
5190 if (nr == 2 && is_zero_one (ri))
5191 {
5192 do_matrix_assignment (rhs, 1, j_arg);
5193 }
5194 else if (nr == 2 && is_one_zero (ri))
5195 {
5196 do_matrix_assignment (rhs, 0, j_arg);
5197 }
5198 else
5199 {
5200 if (index_check (ri, "row") < 0)
5201 return;
5202 do_matrix_assignment (rhs, ri, j_arg);
5203 }
5204 }
5205 break;
5206
5207 case magic_colon:
5208 do_matrix_assignment (rhs, magic_colon, j_arg);
5209 break;
5210
5211 default:
5212 panic_impossible ();
5213 break;
5214 }
5215 }
5216
5217 // -*- MA1 -*-
5218 void
5219 TC_REP::do_matrix_assignment (const tree_constant& rhs, int i,
5220 const tree_constant& j_arg)
5221 {
5222 tree_constant tmp_j = j_arg.make_numeric_or_range_or_magic ();
5223
5224 if (error_state)
5225 return;
5226
5227 TC_REP::constant_type jtype = tmp_j.const_type ();
5228
5229 int rhs_nr = rhs.rows ();
5230 int rhs_nc = rhs.columns ();
5231
5232 switch (jtype)
5233 {
5234 case complex_scalar_constant:
5235 case scalar_constant:
5236 {
5237 if (index_check (i, "row") < 0)
5238 return;
5239 int j = tree_to_mat_idx (tmp_j.double_value ());
5240 if (index_check (j, "column") < 0)
5241 return;
5242 if (! indexed_assign_conforms (1, 1, rhs_nr, rhs_nc))
5243 {
5244 ::error ("A(int,int) = X, X must be a scalar");
5245 return;
5246 }
5247 maybe_resize (i, j);
5248 if (error_state)
5249 return;
5250
5251 do_matrix_assignment (rhs, i, j);
5252 }
5253 break;
5254
5255 case complex_matrix_constant:
5256 case matrix_constant:
5257 {
5258 if (index_check (i, "row") < 0)
5259 return;
5260 Matrix mj = tmp_j.matrix_value ();
5261 idx_vector jv (mj, user_pref.do_fortran_indexing, "column",
5262 columns ());
5263 if (! jv)
5264 return;
5265
5266 if (! indexed_assign_conforms (1, jv.capacity (), rhs_nr, rhs_nc))
5267 {
5268 ::error ("A(int,matrix) = X: X must be a row vector with the same");
5269 ::error ("number of elements as matrix");
5270 return;
5271 }
5272 maybe_resize (i, jv.max ());
5273 if (error_state)
5274 return;
5275
5276 do_matrix_assignment (rhs, i, jv);
5277 }
5278 break;
5279
5280 case string_constant:
5281 gripe_string_invalid ();
5282 break;
5283
5284 case range_constant:
5285 {
5286 if (index_check (i, "row") < 0)
5287 return;
5288 Range rj = tmp_j.range_value ();
5289 if (! indexed_assign_conforms (1, rj.nelem (), rhs_nr, rhs_nc))
5290 {
5291 ::error ("A(int,range) = X: X must be a row vector with the same");
5292 ::error ("number of elements as range");
5293 return;
5294 }
5295
5296 int nc = columns ();
5297 if (nc == 2 && is_zero_one (rj) && rhs_nc == 1)
5298 {
5299 do_matrix_assignment (rhs, i, 1);
5300 }
5301 else if (nc == 2 && is_one_zero (rj) && rhs_nc == 1)
5302 {
5303 do_matrix_assignment (rhs, i, 0);
5304 }
5305 else
5306 {
5307 if (index_check (rj, "column") < 0)
5308 return;
5309 maybe_resize (i, tree_to_mat_idx (rj.max ()));
5310 if (error_state)
5311 return;
5312
5313 do_matrix_assignment (rhs, i, rj);
5314 }
5315 }
5316 break;
5317
5318 case magic_colon:
5319 {
5320 int nc = columns ();
5321 int nr = rows ();
5322 if (i == -1 && nr == 1 && rhs_nr == 0 && rhs_nc == 0
5323 || index_check (i, "row") < 0)
5324 return;
5325 else if (nc == 0 && nr == 0 && rhs_nr == 1)
5326 {
5327 if (rhs.is_complex_type ())
5328 {
5329 complex_matrix = new ComplexMatrix ();
5330 type_tag = complex_matrix_constant;
5331 }
5332 else
5333 {
5334 matrix = new Matrix ();
5335 type_tag = matrix_constant;
5336 }
5337 maybe_resize (i, rhs_nc-1);
5338 if (error_state)
5339 return;
5340 }
5341 else if (indexed_assign_conforms (1, nc, rhs_nr, rhs_nc))
5342 {
5343 maybe_resize (i, nc-1);
5344 if (error_state)
5345 return;
5346 }
5347 else if (rhs_nr == 0 && rhs_nc == 0)
5348 {
5349 if (i < 0 || i >= nr)
5350 {
5351 ::error ("A(int,:) = []: row index out of range");
5352 return;
5353 } 2789 }
5354 } 2790 }
5355 else 2791 break;
5356 { 2792
5357 ::error ("A(int,:) = X: X must be a row vector with the same"); 2793 case scalar_constant:
5358 ::error ("number of columns as A"); 2794 case matrix_constant:
5359 return; 2795 ::assign (*matrix, rhs.matrix_value ());
5360 } 2796 break;
5361 2797
5362 do_matrix_assignment (rhs, i, magic_colon); 2798 default:
5363 } 2799 panic_impossible ();
5364 break; 2800 break;
5365 2801 }
5366 default: 2802 }
5367 panic_impossible ();
5368 break;
5369 }
5370 }
5371
5372 // -*- MA2 -*-
5373 void
5374 TC_REP::do_matrix_assignment (const tree_constant& rhs,
5375 idx_vector& iv, const tree_constant& j_arg)
5376 {
5377 tree_constant tmp_j = j_arg.make_numeric_or_range_or_magic ();
5378
5379 if (error_state)
5380 return;
5381
5382 TC_REP::constant_type jtype = tmp_j.const_type ();
5383
5384 int rhs_nr = rhs.rows ();
5385 int rhs_nc = rhs.columns ();
5386
5387 switch (jtype)
5388 {
5389 case complex_scalar_constant:
5390 case scalar_constant:
5391 {
5392 int j = tree_to_mat_idx (tmp_j.double_value ());
5393 if (index_check (j, "column") < 0)
5394 return;
5395 if (! indexed_assign_conforms (iv.capacity (), 1, rhs_nr, rhs_nc))
5396 {
5397 ::error ("A(matrix,int) = X: X must be a column vector with the");
5398 ::error ("same number of elements as matrix");
5399 return;
5400 }
5401 maybe_resize (iv.max (), j);
5402 if (error_state)
5403 return;
5404
5405 do_matrix_assignment (rhs, iv, j);
5406 }
5407 break;
5408
5409 case complex_matrix_constant:
5410 case matrix_constant:
5411 {
5412 Matrix mj = tmp_j.matrix_value ();
5413 idx_vector jv (mj, user_pref.do_fortran_indexing, "column",
5414 columns ());
5415 if (! jv)
5416 return;
5417
5418 if (! indexed_assign_conforms (iv.capacity (), jv.capacity (),
5419 rhs_nr, rhs_nc))
5420 {
5421 ::error ("A(r_mat,c_mat) = X: the number of rows in X must match");
5422 ::error ("the number of elements in r_mat and the number of");
5423 ::error ("columns in X must match the number of elements in c_mat");
5424 return;
5425 }
5426 maybe_resize (iv.max (), jv.max ());
5427 if (error_state)
5428 return;
5429
5430 do_matrix_assignment (rhs, iv, jv);
5431 }
5432 break;
5433
5434 case string_constant:
5435 gripe_string_invalid ();
5436 break;
5437
5438 case range_constant:
5439 {
5440 Range rj = tmp_j.range_value ();
5441 if (! indexed_assign_conforms (iv.capacity (), rj.nelem (),
5442 rhs_nr, rhs_nc))
5443 {
5444 ::error ("A(matrix,range) = X: the number of rows in X must match");
5445 ::error ("the number of elements in matrix and the number of");
5446 ::error ("columns in X must match the number of elements in range");
5447 return;
5448 }
5449
5450 int nc = columns ();
5451 if (nc == 2 && is_zero_one (rj) && rhs_nc == 1)
5452 {
5453 do_matrix_assignment (rhs, iv, 1);
5454 }
5455 else if (nc == 2 && is_one_zero (rj) && rhs_nc == 1)
5456 {
5457 do_matrix_assignment (rhs, iv, 0);
5458 }
5459 else
5460 {
5461 if (index_check (rj, "column") < 0)
5462 return;
5463 maybe_resize (iv.max (), tree_to_mat_idx (rj.max ()));
5464 if (error_state)
5465 return;
5466
5467 do_matrix_assignment (rhs, iv, rj);
5468 }
5469 }
5470 break;
5471
5472 case magic_colon:
5473 {
5474 int nc = columns ();
5475 int new_nc = nc;
5476 if (nc == 0)
5477 new_nc = rhs_nc;
5478
5479 if (indexed_assign_conforms (iv.capacity (), new_nc,
5480 rhs_nr, rhs_nc))
5481 {
5482 maybe_resize (iv.max (), new_nc-1);
5483 if (error_state)
5484 return;
5485 }
5486 else if (rhs_nr == 0 && rhs_nc == 0)
5487 {
5488 if (iv.max () >= rows ())
5489 {
5490 ::error ("A(matrix,:) = []: row index out of range");
5491 return;
5492 }
5493 }
5494 else
5495 {
5496 ::error ("A(matrix,:) = X: the number of rows in X must match the");
5497 ::error ("number of elements in matrix, and the number of columns");
5498 ::error ("in X must match the number of columns in A");
5499 return;
5500 }
5501
5502 do_matrix_assignment (rhs, iv, magic_colon);
5503 }
5504 break;
5505
5506 default:
5507 panic_impossible ();
5508 break;
5509 }
5510 }
5511
5512 // -*- MA3 -*-
5513 void
5514 TC_REP::do_matrix_assignment (const tree_constant& rhs, Range& ri,
5515 const tree_constant& j_arg)
5516 {
5517 tree_constant tmp_j = j_arg.make_numeric_or_range_or_magic ();
5518
5519 if (error_state)
5520 return;
5521
5522 TC_REP::constant_type jtype = tmp_j.const_type ();
5523
5524 int rhs_nr = rhs.rows ();
5525 int rhs_nc = rhs.columns ();
5526
5527 switch (jtype)
5528 {
5529 case complex_scalar_constant:
5530 case scalar_constant:
5531 {
5532 int j = tree_to_mat_idx (tmp_j.double_value ());
5533 if (index_check (j, "column") < 0)
5534 return;
5535 if (! indexed_assign_conforms (ri.nelem (), 1, rhs_nr, rhs_nc))
5536 {
5537 ::error ("A(range,int) = X: X must be a column vector with the");
5538 ::error ("same number of elements as range");
5539 return;
5540 }
5541 maybe_resize (tree_to_mat_idx (ri.max ()), j);
5542 if (error_state)
5543 return;
5544
5545 do_matrix_assignment (rhs, ri, j);
5546 }
5547 break;
5548
5549 case complex_matrix_constant:
5550 case matrix_constant:
5551 {
5552 Matrix mj = tmp_j.matrix_value ();
5553 idx_vector jv (mj, user_pref.do_fortran_indexing, "column",
5554 columns ());
5555 if (! jv)
5556 return;
5557
5558 if (! indexed_assign_conforms (ri.nelem (), jv.capacity (),
5559 rhs_nr, rhs_nc))
5560 {
5561 ::error ("A(range,matrix) = X: the number of rows in X must match");
5562 ::error ("the number of elements in range and the number of");
5563 ::error ("columns in X must match the number of elements in matrix");
5564 return;
5565 }
5566 maybe_resize (tree_to_mat_idx (ri.max ()), jv.max ());
5567 if (error_state)
5568 return;
5569
5570 do_matrix_assignment (rhs, ri, jv);
5571 }
5572 break;
5573
5574 case string_constant:
5575 gripe_string_invalid ();
5576 break;
5577
5578 case range_constant:
5579 {
5580 Range rj = tmp_j.range_value ();
5581 if (! indexed_assign_conforms (ri.nelem (), rj.nelem (),
5582 rhs_nr, rhs_nc))
5583 {
5584 ::error ("A(r_range,c_range) = X: the number of rows in X must");
5585 ::error ("match the number of elements in r_range and the number");
5586 ::error ("of columns in X must match the number of elements in");
5587 ::error ("c_range");
5588 return;
5589 }
5590
5591 int nc = columns ();
5592 if (nc == 2 && is_zero_one (rj) && rhs_nc == 1)
5593 {
5594 do_matrix_assignment (rhs, ri, 1);
5595 }
5596 else if (nc == 2 && is_one_zero (rj) && rhs_nc == 1)
5597 {
5598 do_matrix_assignment (rhs, ri, 0);
5599 }
5600 else
5601 {
5602 if (index_check (rj, "column") < 0)
5603 return;
5604
5605 maybe_resize (tree_to_mat_idx (ri.max ()),
5606 tree_to_mat_idx (rj.max ()));
5607
5608 if (error_state)
5609 return;
5610
5611 do_matrix_assignment (rhs, ri, rj);
5612 }
5613 }
5614 break;
5615
5616 case magic_colon:
5617 {
5618 int nc = columns ();
5619 int new_nc = nc;
5620 if (nc == 0)
5621 new_nc = rhs_nc;
5622
5623 if (indexed_assign_conforms (ri.nelem (), new_nc, rhs_nr, rhs_nc))
5624 {
5625 maybe_resize (tree_to_mat_idx (ri.max ()), new_nc-1);
5626 if (error_state)
5627 return;
5628 }
5629 else if (rhs_nr == 0 && rhs_nc == 0)
5630 {
5631 int b = tree_to_mat_idx (ri.min ());
5632 int l = tree_to_mat_idx (ri.max ());
5633 if (b < 0 || l >= rows ())
5634 {
5635 ::error ("A(range,:) = []: row index out of range");
5636 return;
5637 }
5638 }
5639 else
5640 {
5641 ::error ("A(range,:) = X: the number of rows in X must match the");
5642 ::error ("number of elements in range, and the number of columns");
5643 ::error ("in X must match the number of columns in A");
5644 return;
5645 }
5646
5647 do_matrix_assignment (rhs, ri, magic_colon);
5648 }
5649 break;
5650
5651 default:
5652 panic_impossible ();
5653 break;
5654 }
5655 }
5656
5657 // -*- MA4 -*-
5658 void
5659 TC_REP::do_matrix_assignment (const tree_constant& rhs,
5660 TC_REP::constant_type /* i */,
5661 const tree_constant& j_arg)
5662 {
5663 tree_constant tmp_j = j_arg.make_numeric_or_range_or_magic ();
5664
5665 if (error_state)
5666 return;
5667
5668 TC_REP::constant_type jtype = tmp_j.const_type ();
5669
5670 int rhs_nr = rhs.rows ();
5671 int rhs_nc = rhs.columns ();
5672
5673 switch (jtype)
5674 {
5675 case complex_scalar_constant:
5676 case scalar_constant:
5677 {
5678 int j = tree_to_mat_idx (tmp_j.double_value ());
5679 int nr = rows ();
5680 int nc = columns ();
5681 if (j == -1 && nc == 1 && rhs_nr == 0 && rhs_nc == 0
5682 || index_check (j, "column") < 0)
5683 return;
5684 if (nr == 0 && nc == 0 && rhs_nc == 1)
5685 {
5686 if (rhs.is_complex_type ())
5687 {
5688 complex_matrix = new ComplexMatrix ();
5689 type_tag = complex_matrix_constant;
5690 }
5691 else
5692 {
5693 matrix = new Matrix ();
5694 type_tag = matrix_constant;
5695 }
5696 maybe_resize (rhs_nr-1, j);
5697 if (error_state)
5698 return;
5699 }
5700 else if (indexed_assign_conforms (nr, 1, rhs_nr, rhs_nc))
5701 {
5702 maybe_resize (nr-1, j);
5703 if (error_state)
5704 return;
5705 }
5706 else if (rhs_nr == 0 && rhs_nc == 0)
5707 {
5708 if (j < 0 || j >= nc)
5709 {
5710 ::error ("A(:,int) = []: column index out of range");
5711 return;
5712 }
5713 }
5714 else
5715 {
5716 ::error ("A(:,int) = X: X must be a column vector with the same");
5717 ::error ("number of rows as A");
5718 return;
5719 }
5720
5721 do_matrix_assignment (rhs, magic_colon, j);
5722 }
5723 break;
5724
5725 case complex_matrix_constant:
5726 case matrix_constant:
5727 {
5728 Matrix mj = tmp_j.matrix_value ();
5729 idx_vector jv (mj, user_pref.do_fortran_indexing, "column",
5730 columns ());
5731 if (! jv)
5732 return;
5733
5734 int nr = rows ();
5735 int new_nr = nr;
5736 if (nr == 0)
5737 new_nr = rhs_nr;
5738
5739 if (indexed_assign_conforms (new_nr, jv.capacity (),
5740 rhs_nr, rhs_nc))
5741 {
5742 maybe_resize (new_nr-1, jv.max ());
5743 if (error_state)
5744 return;
5745 }
5746 else if (rhs_nr == 0 && rhs_nc == 0)
5747 {
5748 if (jv.max () >= columns ())
5749 {
5750 ::error ("A(:,matrix) = []: column index out of range");
5751 return;
5752 }
5753 }
5754 else
5755 {
5756 ::error ("A(:,matrix) = X: the number of rows in X must match the");
5757 ::error ("number of rows in A, and the number of columns in X must");
5758 ::error ("match the number of elements in matrix");
5759 return;
5760 }
5761
5762 do_matrix_assignment (rhs, magic_colon, jv);
5763 }
5764 break;
5765
5766 case string_constant:
5767 gripe_string_invalid ();
5768 break;
5769
5770 case range_constant:
5771 {
5772 Range rj = tmp_j.range_value ();
5773 int nr = rows ();
5774 int new_nr = nr;
5775 if (nr == 0)
5776 new_nr = rhs_nr;
5777
5778 if (indexed_assign_conforms (new_nr, rj.nelem (), rhs_nr, rhs_nc))
5779 {
5780 int nc = columns ();
5781 if (nc == 2 && is_zero_one (rj) && rhs_nc == 1)
5782 {
5783 do_matrix_assignment (rhs, magic_colon, 1);
5784 }
5785 else if (nc == 2 && is_one_zero (rj) && rhs_nc == 1)
5786 {
5787 do_matrix_assignment (rhs, magic_colon, 0);
5788 }
5789 else
5790 {
5791 if (index_check (rj, "column") < 0)
5792 return;
5793 maybe_resize (new_nr-1, tree_to_mat_idx (rj.max ()));
5794 if (error_state)
5795 return;
5796 }
5797 }
5798 else if (rhs_nr == 0 && rhs_nc == 0)
5799 {
5800 int b = tree_to_mat_idx (rj.min ());
5801 int l = tree_to_mat_idx (rj.max ());
5802 if (b < 0 || l >= columns ())
5803 {
5804 ::error ("A(:,range) = []: column index out of range");
5805 return;
5806 }
5807 }
5808 else
5809 {
5810 ::error ("A(:,range) = X: the number of rows in X must match the");
5811 ::error ("number of rows in A, and the number of columns in X");
5812 ::error ("must match the number of elements in range");
5813 return;
5814 }
5815
5816 do_matrix_assignment (rhs, magic_colon, rj);
5817 }
5818 break;
5819
5820 case magic_colon:
5821 // a(:,:) = foo is equivalent to a = foo.
5822 do_matrix_assignment (rhs, magic_colon, magic_colon);
5823 break;
5824
5825 default:
5826 panic_impossible ();
5827 break;
5828 }
5829 }
5830
5831 // Functions that actually handle assignment to a matrix using two
5832 // index values.
5833 //
5834 // idx2
5835 // +---+---+----+----+
5836 // idx1 | i | v | r | c |
5837 // ---------+---+---+----+----+
5838 // integer | 1 | 5 | 9 | 13 |
5839 // ---------+---+---+----+----+
5840 // vector | 2 | 6 | 10 | 14 |
5841 // ---------+---+---+----+----+
5842 // range | 3 | 7 | 11 | 15 |
5843 // ---------+---+---+----+----+
5844 // colon | 4 | 8 | 12 | 16 |
5845 // ---------+---+---+----+----+
5846
5847 // -*- 1 -*-
5848 void
5849 TC_REP::do_matrix_assignment (const tree_constant& rhs, int i, int j)
5850 {
5851 REP_ELEM_ASSIGN (i, j, rhs.double_value (), rhs.complex_value (),
5852 rhs.is_real_type ());
5853 }
5854
5855 // -*- 2 -*-
5856 void
5857 TC_REP::do_matrix_assignment (const tree_constant& rhs, int i, idx_vector& jv)
5858 {
5859 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
5860
5861 for (int j = 0; j < jv.capacity (); j++)
5862 REP_ELEM_ASSIGN (i, jv.elem (j), rhs_m.elem (0, j),
5863 rhs_cm.elem (0, j), rhs.is_real_type ());
5864 }
5865
5866 // -*- 3 -*-
5867 void
5868 TC_REP::do_matrix_assignment (const tree_constant& rhs, int i, Range& rj)
5869 {
5870 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
5871
5872 double b = rj.base ();
5873 double increment = rj.inc ();
5874
5875 for (int j = 0; j < rj.nelem (); j++)
5876 {
5877 double tmp = b + j * increment;
5878 int col = tree_to_mat_idx (tmp);
5879 REP_ELEM_ASSIGN (i, col, rhs_m.elem (0, j), rhs_cm.elem (0, j),
5880 rhs.is_real_type ());
5881 }
5882 }
5883
5884 // -*- 4 -*-
5885 void
5886 TC_REP::do_matrix_assignment (const tree_constant& rhs, int i,
5887 TC_REP::constant_type mcj)
5888 {
5889 assert (mcj == magic_colon);
5890
5891 int nc = columns ();
5892
5893 if (rhs.is_zero_by_zero ())
5894 {
5895 delete_row (i);
5896 }
5897 else if (rhs.is_matrix_type ())
5898 {
5899 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
5900
5901 for (int j = 0; j < nc; j++)
5902 REP_ELEM_ASSIGN (i, j, rhs_m.elem (0, j), rhs_cm.elem (0, j),
5903 rhs.is_real_type ());
5904 }
5905 else if (rhs.is_scalar_type () && nc == 1)
5906 {
5907 REP_ELEM_ASSIGN (i, 0, rhs.double_value (),
5908 rhs.complex_value (), rhs.is_real_type ());
5909 }
5910 else
5911 panic_impossible ();
5912 }
5913
5914 // -*- 5 -*-
5915 void
5916 TC_REP::do_matrix_assignment (const tree_constant& rhs,
5917 idx_vector& iv, int j)
5918 {
5919 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
5920
5921 for (int i = 0; i < iv.capacity (); i++)
5922 {
5923 int row = iv.elem (i);
5924 REP_ELEM_ASSIGN (row, j, rhs_m.elem (i, 0),
5925 rhs_cm.elem (i, 0), rhs.is_real_type ());
5926 }
5927 }
5928
5929 // -*- 6 -*-
5930 void
5931 TC_REP::do_matrix_assignment (const tree_constant& rhs,
5932 idx_vector& iv, idx_vector& jv)
5933 {
5934 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
5935
5936 for (int i = 0; i < iv.capacity (); i++)
5937 {
5938 int row = iv.elem (i);
5939 for (int j = 0; j < jv.capacity (); j++)
5940 {
5941 int col = jv.elem (j);
5942 REP_ELEM_ASSIGN (row, col, rhs_m.elem (i, j),
5943 rhs_cm.elem (i, j), rhs.is_real_type ());
5944 }
5945 }
5946 }
5947
5948 // -*- 7 -*-
5949 void
5950 TC_REP::do_matrix_assignment (const tree_constant& rhs,
5951 idx_vector& iv, Range& rj)
5952 {
5953 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
5954
5955 double b = rj.base ();
5956 double increment = rj.inc ();
5957
5958 for (int i = 0; i < iv.capacity (); i++)
5959 {
5960 int row = iv.elem (i);
5961 for (int j = 0; j < rj.nelem (); j++)
5962 {
5963 double tmp = b + j * increment;
5964 int col = tree_to_mat_idx (tmp);
5965 REP_ELEM_ASSIGN (row, col, rhs_m.elem (i, j),
5966 rhs_cm.elem (i, j), rhs.is_real_type ());
5967 }
5968 }
5969 }
5970
5971 // -*- 8 -*-
5972 void
5973 TC_REP::do_matrix_assignment (const tree_constant& rhs,
5974 idx_vector& iv, TC_REP::constant_type mcj)
5975 {
5976 assert (mcj == magic_colon);
5977
5978 if (rhs.is_zero_by_zero ())
5979 {
5980 delete_rows (iv);
5981 }
5982 else
5983 {
5984 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
5985
5986 int nc = columns ();
5987
5988 for (int j = 0; j < nc; j++)
5989 {
5990 for (int i = 0; i < iv.capacity (); i++)
5991 {
5992 int row = iv.elem (i);
5993 REP_ELEM_ASSIGN (row, j, rhs_m.elem (i, j),
5994 rhs_cm.elem (i, j), rhs.is_real_type ());
5995 }
5996 }
5997 }
5998 }
5999
6000 // -*- 9 -*-
6001 void
6002 TC_REP::do_matrix_assignment (const tree_constant& rhs, Range& ri, int j)
6003 {
6004 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
6005
6006 double b = ri.base ();
6007 double increment = ri.inc ();
6008
6009 for (int i = 0; i < ri.nelem (); i++)
6010 {
6011 double tmp = b + i * increment;
6012 int row = tree_to_mat_idx (tmp);
6013 REP_ELEM_ASSIGN (row, j, rhs_m.elem (i, 0),
6014 rhs_cm.elem (i, 0), rhs.is_real_type ());
6015 }
6016 }
6017
6018 // -*- 10 -*-
6019 void
6020 TC_REP::do_matrix_assignment (const tree_constant& rhs,
6021 Range& ri, idx_vector& jv)
6022 {
6023 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
6024
6025 double b = ri.base ();
6026 double increment = ri.inc ();
6027
6028 for (int j = 0; j < jv.capacity (); j++)
6029 {
6030 int col = jv.elem (j);
6031 for (int i = 0; i < ri.nelem (); i++)
6032 {
6033 double tmp = b + i * increment;
6034 int row = tree_to_mat_idx (tmp);
6035 REP_ELEM_ASSIGN (row, col, rhs_m.elem (i, j),
6036 rhs_m.elem (i, j), rhs.is_real_type ());
6037 }
6038 }
6039 }
6040
6041 // -*- 11 -*-
6042 void
6043 TC_REP::do_matrix_assignment (const tree_constant& rhs,
6044 Range& ri, Range& rj)
6045 {
6046 double ib = ri.base ();
6047 double iinc = ri.inc ();
6048 double jb = rj.base ();
6049 double jinc = rj.inc ();
6050
6051 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
6052
6053 for (int i = 0; i < ri.nelem (); i++)
6054 {
6055 double itmp = ib + i * iinc;
6056 int row = tree_to_mat_idx (itmp);
6057 for (int j = 0; j < rj.nelem (); j++)
6058 {
6059 double jtmp = jb + j * jinc;
6060 int col = tree_to_mat_idx (jtmp);
6061 REP_ELEM_ASSIGN (row, col, rhs_m.elem (i, j),
6062 rhs_cm.elem (i, j), rhs.is_real_type ());
6063 }
6064 }
6065 }
6066
6067 // -*- 12 -*-
6068 void
6069 TC_REP::do_matrix_assignment (const tree_constant& rhs,
6070 Range& ri, TC_REP::constant_type mcj)
6071 {
6072 assert (mcj == magic_colon);
6073
6074 if (rhs.is_zero_by_zero ())
6075 {
6076 delete_rows (ri);
6077 }
6078 else
6079 {
6080 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
6081
6082 double ib = ri.base ();
6083 double iinc = ri.inc ();
6084
6085 int nc = columns ();
6086
6087 for (int i = 0; i < ri.nelem (); i++)
6088 {
6089 double itmp = ib + i * iinc;
6090 int row = tree_to_mat_idx (itmp);
6091 for (int j = 0; j < nc; j++)
6092 REP_ELEM_ASSIGN (row, j, rhs_m.elem (i, j),
6093 rhs_cm.elem (i, j), rhs.is_real_type ());
6094 }
6095 }
6096 }
6097
6098 // -*- 13 -*-
6099 void
6100 TC_REP::do_matrix_assignment (const tree_constant& rhs,
6101 TC_REP::constant_type mci, int j)
6102 {
6103 assert (mci == magic_colon);
6104
6105 int nr = rows ();
6106
6107 if (rhs.is_zero_by_zero ())
6108 {
6109 delete_column (j);
6110 }
6111 else if (rhs.is_matrix_type ())
6112 {
6113 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
6114
6115 for (int i = 0; i < nr; i++)
6116 REP_ELEM_ASSIGN (i, j, rhs_m.elem (i, 0),
6117 rhs_cm.elem (i, 0), rhs.is_real_type ());
6118 }
6119 else if (rhs.is_scalar_type () && nr == 1)
6120 {
6121 REP_ELEM_ASSIGN (0, j, rhs.double_value (),
6122 rhs.complex_value (), rhs.is_real_type ());
6123 }
6124 else
6125 panic_impossible ();
6126 }
6127
6128 // -*- 14 -*-
6129 void
6130 TC_REP::do_matrix_assignment (const tree_constant& rhs,
6131 TC_REP::constant_type mci, idx_vector& jv)
6132 {
6133 assert (mci == magic_colon);
6134
6135 if (rhs.is_zero_by_zero ())
6136 {
6137 delete_columns (jv);
6138 }
6139 else
6140 {
6141 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
6142
6143 int nr = rows ();
6144
6145 for (int i = 0; i < nr; i++)
6146 {
6147 for (int j = 0; j < jv.capacity (); j++)
6148 {
6149 int col = jv.elem (j);
6150 REP_ELEM_ASSIGN (i, col, rhs_m.elem (i, j),
6151 rhs_cm.elem (i, j), rhs.is_real_type ());
6152 }
6153 }
6154 }
6155 }
6156
6157 // -*- 15 -*-
6158 void
6159 TC_REP::do_matrix_assignment (const tree_constant& rhs,
6160 TC_REP::constant_type mci, Range& rj)
6161 {
6162 assert (mci == magic_colon);
6163
6164 if (rhs.is_zero_by_zero ())
6165 {
6166 delete_columns (rj);
6167 }
6168 else
6169 {
6170 REP_RHS_MATRIX (rhs, rhs_m, rhs_cm, rhs_nr, rhs_nc);
6171
6172 int nr = rows ();
6173
6174 double jb = rj.base ();
6175 double jinc = rj.inc ();
6176
6177 for (int j = 0; j < rj.nelem (); j++)
6178 {
6179 double jtmp = jb + j * jinc;
6180 int col = tree_to_mat_idx (jtmp);
6181 for (int i = 0; i < nr; i++)
6182 {
6183 REP_ELEM_ASSIGN (i, col, rhs_m.elem (i, j),
6184 rhs_cm.elem (i, j), rhs.is_real_type ());
6185 }
6186 }
6187 }
6188 }
6189
6190 // -*- 16 -*-
6191 void
6192 TC_REP::do_matrix_assignment (const tree_constant& rhs,
6193 TC_REP::constant_type mci,
6194 TC_REP::constant_type mcj)
6195 {
6196 assert (mci == magic_colon && mcj == magic_colon);
6197
6198 switch (type_tag)
6199 {
6200 case scalar_constant:
6201 break;
6202
6203 case matrix_constant:
6204 delete matrix;
6205 break;
6206
6207 case complex_scalar_constant:
6208 delete complex_scalar;
6209 break;
6210
6211 case complex_matrix_constant:
6212 delete complex_matrix;
6213 break;
6214
6215 case string_constant:
6216 delete str_obj;
6217 break;
6218
6219 case range_constant:
6220 delete range;
6221 break;
6222
6223 case magic_colon:
6224 default:
6225 panic_impossible ();
6226 break;
6227 }
6228
6229 type_tag = rhs.const_type ();
6230
6231 switch (type_tag)
6232 {
6233 case scalar_constant:
6234 scalar = rhs.double_value ();
6235 break;
6236
6237 case matrix_constant:
6238 matrix = new Matrix (rhs.matrix_value ());
6239 break;
6240
6241 case string_constant:
6242 str_obj = new Octave_str_obj (rhs.string_value ());
6243 break;
6244
6245 case complex_matrix_constant:
6246 complex_matrix = new ComplexMatrix (rhs.complex_matrix_value ());
6247 break;
6248
6249 case complex_scalar_constant:
6250 complex_scalar = new Complex (rhs.complex_value ());
6251 break;
6252
6253 case range_constant:
6254 range = new Range (rhs.range_value ());
6255 break;
6256
6257 case magic_colon:
6258 default:
6259 panic_impossible ();
6260 break;
6261 }
6262 }
6263
6264 // Functions for deleting rows or columns of a matrix. These are used
6265 // to handle statements like
6266 //
6267 // M (i, j) = []
6268
6269 void
6270 TC_REP::delete_row (int idx)
6271 {
6272 if (type_tag == matrix_constant)
6273 {
6274 int nr = matrix->rows ();
6275 int nc = matrix->columns ();
6276 Matrix *new_matrix = new Matrix (nr-1, nc);
6277 int ii = 0;
6278 for (int i = 0; i < nr; i++)
6279 {
6280 if (i != idx)
6281 {
6282 for (int j = 0; j < nc; j++)
6283 new_matrix->elem (ii, j) = matrix->elem (i, j);
6284 ii++;
6285 }
6286 }
6287 delete matrix;
6288 matrix = new_matrix;
6289 }
6290 else if (type_tag == complex_matrix_constant)
6291 {
6292 int nr = complex_matrix->rows ();
6293 int nc = complex_matrix->columns ();
6294 ComplexMatrix *new_matrix = new ComplexMatrix (nr-1, nc);
6295 int ii = 0;
6296 for (int i = 0; i < nr; i++)
6297 {
6298 if (i != idx)
6299 {
6300 for (int j = 0; j < nc; j++)
6301 new_matrix->elem (ii, j) = complex_matrix->elem (i, j);
6302 ii++;
6303 }
6304 }
6305 delete complex_matrix;
6306 complex_matrix = new_matrix;
6307 }
6308 else
6309 panic_impossible ();
6310 }
6311
6312 void
6313 TC_REP::delete_rows (idx_vector& iv)
6314 {
6315 iv.sort_uniq ();
6316 int num_to_delete = iv.length ();
6317
6318 if (num_to_delete == 0)
6319 return;
6320
6321 int nr = rows ();
6322 int nc = columns ();
6323
6324 // If deleting all rows of a column vector, make result 0x0.
6325 if (nc == 1 && num_to_delete == nr)
6326 nc = 0;
6327
6328 if (type_tag == matrix_constant)
6329 {
6330 Matrix *new_matrix = new Matrix (nr-num_to_delete, nc);
6331 if (nr > num_to_delete)
6332 {
6333 int ii = 0;
6334 int idx = 0;
6335 for (int i = 0; i < nr; i++)
6336 {
6337 if (i == iv.elem (idx))
6338 idx++;
6339 else
6340 {
6341 for (int j = 0; j < nc; j++)
6342 new_matrix->elem (ii, j) = matrix->elem (i, j);
6343 ii++;
6344 }
6345 }
6346 }
6347 delete matrix;
6348 matrix = new_matrix;
6349 }
6350 else if (type_tag == complex_matrix_constant)
6351 {
6352 ComplexMatrix *new_matrix = new ComplexMatrix (nr-num_to_delete, nc);
6353 if (nr > num_to_delete)
6354 {
6355 int ii = 0;
6356 int idx = 0;
6357 for (int i = 0; i < nr; i++)
6358 {
6359 if (i == iv.elem (idx))
6360 idx++;
6361 else
6362 {
6363 for (int j = 0; j < nc; j++)
6364 new_matrix->elem (ii, j) = complex_matrix->elem (i, j);
6365 ii++;
6366 }
6367 }
6368 }
6369 delete complex_matrix;
6370 complex_matrix = new_matrix;
6371 }
6372 else
6373 panic_impossible ();
6374 }
6375
6376 void
6377 TC_REP::delete_rows (Range& ri)
6378 {
6379 ri.sort ();
6380 int num_to_delete = ri.nelem ();
6381
6382 if (num_to_delete == 0)
6383 return;
6384
6385 int nr = rows ();
6386 int nc = columns ();
6387
6388 // If deleting all rows of a column vector, make result 0x0.
6389
6390 if (nc == 1 && num_to_delete == nr)
6391 nc = 0;
6392
6393 double ib = ri.base ();
6394 double iinc = ri.inc ();
6395
6396 int max_idx = tree_to_mat_idx (ri.max ());
6397
6398 if (type_tag == matrix_constant)
6399 {
6400 Matrix *new_matrix = new Matrix (nr-num_to_delete, nc);
6401 if (nr > num_to_delete)
6402 {
6403 int ii = 0;
6404 int idx = 0;
6405 for (int i = 0; i < nr; i++)
6406 {
6407 double itmp = ib + idx * iinc;
6408 int row = tree_to_mat_idx (itmp);
6409
6410 if (i == row && row <= max_idx)
6411 idx++;
6412 else
6413 {
6414 for (int j = 0; j < nc; j++)
6415 new_matrix->elem (ii, j) = matrix->elem (i, j);
6416 ii++;
6417 }
6418 }
6419 }
6420 delete matrix;
6421 matrix = new_matrix;
6422 }
6423 else if (type_tag == complex_matrix_constant)
6424 {
6425 ComplexMatrix *new_matrix = new ComplexMatrix (nr-num_to_delete, nc);
6426 if (nr > num_to_delete)
6427 {
6428 int ii = 0;
6429 int idx = 0;
6430 for (int i = 0; i < nr; i++)
6431 {
6432 double itmp = ib + idx * iinc;
6433 int row = tree_to_mat_idx (itmp);
6434
6435 if (i == row && row <= max_idx)
6436 idx++;
6437 else
6438 {
6439 for (int j = 0; j < nc; j++)
6440 new_matrix->elem (ii, j) = complex_matrix->elem (i, j);
6441 ii++;
6442 }
6443 }
6444 }
6445 delete complex_matrix;
6446 complex_matrix = new_matrix;
6447 }
6448 else
6449 panic_impossible ();
6450 }
6451
6452 void
6453 TC_REP::delete_column (int idx)
6454 {
6455 if (type_tag == matrix_constant)
6456 {
6457 int nr = matrix->rows ();
6458 int nc = matrix->columns ();
6459 Matrix *new_matrix = new Matrix (nr, nc-1);
6460 int jj = 0;
6461 for (int j = 0; j < nc; j++)
6462 {
6463 if (j != idx)
6464 {
6465 for (int i = 0; i < nr; i++)
6466 new_matrix->elem (i, jj) = matrix->elem (i, j);
6467 jj++;
6468 }
6469 }
6470 delete matrix;
6471 matrix = new_matrix;
6472 }
6473 else if (type_tag == complex_matrix_constant)
6474 {
6475 int nr = complex_matrix->rows ();
6476 int nc = complex_matrix->columns ();
6477 ComplexMatrix *new_matrix = new ComplexMatrix (nr, nc-1);
6478 int jj = 0;
6479 for (int j = 0; j < nc; j++)
6480 {
6481 if (j != idx)
6482 {
6483 for (int i = 0; i < nr; i++)
6484 new_matrix->elem (i, jj) = complex_matrix->elem (i, j);
6485 jj++;
6486 }
6487 }
6488 delete complex_matrix;
6489 complex_matrix = new_matrix;
6490 }
6491 else
6492 panic_impossible ();
6493 }
6494
6495 void
6496 TC_REP::delete_columns (idx_vector& jv)
6497 {
6498 jv.sort_uniq ();
6499 int num_to_delete = jv.length ();
6500
6501 if (num_to_delete == 0)
6502 return;
6503
6504 int nr = rows ();
6505 int nc = columns ();
6506
6507 // If deleting all columns of a row vector, make result 0x0.
6508
6509 if (nr == 1 && num_to_delete == nc)
6510 nr = 0;
6511
6512 if (type_tag == matrix_constant)
6513 {
6514 Matrix *new_matrix = new Matrix (nr, nc-num_to_delete);
6515 if (nc > num_to_delete)
6516 {
6517 int jj = 0;
6518 int idx = 0;
6519 for (int j = 0; j < nc; j++)
6520 {
6521 if (j == jv.elem (idx))
6522 idx++;
6523 else
6524 {
6525 for (int i = 0; i < nr; i++)
6526 new_matrix->elem (i, jj) = matrix->elem (i, j);
6527 jj++;
6528 }
6529 }
6530 }
6531 delete matrix;
6532 matrix = new_matrix;
6533 }
6534 else if (type_tag == complex_matrix_constant)
6535 {
6536 ComplexMatrix *new_matrix = new ComplexMatrix (nr, nc-num_to_delete);
6537 if (nc > num_to_delete)
6538 {
6539 int jj = 0;
6540 int idx = 0;
6541 for (int j = 0; j < nc; j++)
6542 {
6543 if (j == jv.elem (idx))
6544 idx++;
6545 else
6546 {
6547 for (int i = 0; i < nr; i++)
6548 new_matrix->elem (i, jj) = complex_matrix->elem (i, j);
6549 jj++;
6550 }
6551 }
6552 }
6553 delete complex_matrix;
6554 complex_matrix = new_matrix;
6555 }
6556 else
6557 panic_impossible ();
6558 }
6559
6560 void
6561 TC_REP::delete_columns (Range& rj)
6562 {
6563 rj.sort ();
6564 int num_to_delete = rj.nelem ();
6565
6566 if (num_to_delete == 0)
6567 return;
6568
6569 int nr = rows ();
6570 int nc = columns ();
6571
6572 // If deleting all columns of a row vector, make result 0x0.
6573
6574 if (nr == 1 && num_to_delete == nc)
6575 nr = 0;
6576
6577 double jb = rj.base ();
6578 double jinc = rj.inc ();
6579
6580 int max_idx = tree_to_mat_idx (rj.max ());
6581
6582 if (type_tag == matrix_constant)
6583 {
6584 Matrix *new_matrix = new Matrix (nr, nc-num_to_delete);
6585 if (nc > num_to_delete)
6586 {
6587 int jj = 0;
6588 int idx = 0;
6589 for (int j = 0; j < nc; j++)
6590 {
6591 double jtmp = jb + idx * jinc;
6592 int col = tree_to_mat_idx (jtmp);
6593
6594 if (j == col && col <= max_idx)
6595 idx++;
6596 else
6597 {
6598 for (int i = 0; i < nr; i++)
6599 new_matrix->elem (i, jj) = matrix->elem (i, j);
6600 jj++;
6601 }
6602 }
6603 }
6604 delete matrix;
6605 matrix = new_matrix;
6606 }
6607 else if (type_tag == complex_matrix_constant)
6608 {
6609 ComplexMatrix *new_matrix = new ComplexMatrix (nr, nc-num_to_delete);
6610 if (nc > num_to_delete)
6611 {
6612 int jj = 0;
6613 int idx = 0;
6614 for (int j = 0; j < nc; j++)
6615 {
6616 double jtmp = jb + idx * jinc;
6617 int col = tree_to_mat_idx (jtmp);
6618
6619 if (j == col && col <= max_idx)
6620 idx++;
6621 else
6622 {
6623 for (int i = 0; i < nr; i++)
6624 new_matrix->elem (i, jj) = complex_matrix->elem (i, j);
6625 jj++;
6626 }
6627 }
6628 }
6629 delete complex_matrix;
6630 complex_matrix = new_matrix;
6631 }
6632 else
6633 panic_impossible ();
6634 } 2803 }
6635 2804
6636 /* 2805 /*
6637 ;;; Local Variables: *** 2806 ;;; Local Variables: ***
6638 ;;; mode: C++ *** 2807 ;;; mode: C++ ***