Mercurial > octave
changeset 32129:13fbc97f9362
new functions to initialize a tree_matrix matrix object
* pt-tm-const.h, pt-tm-const.cc (tm_row_const::tm_row_const,
tm_const::tm_const, tm_row_const::init, tm_const::init):
New constructors and overloaded init methods that accept pointers to the
beginning and end of a contiguous range of octave_value objects.
author | Petter T. <petter.vilhelm@gmail.com> |
---|---|
date | Thu, 15 Jun 2023 14:08:45 -0400 |
parents | d3023141b792 |
children | dedc746ecd58 |
files | libinterp/parse-tree/pt-tm-const.cc libinterp/parse-tree/pt-tm-const.h |
diffstat | 2 files changed, 361 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-tm-const.cc Thu Jun 15 15:46:59 2023 -0400 +++ b/libinterp/parse-tree/pt-tm-const.cc Thu Jun 15 14:08:45 2023 -0400 @@ -160,6 +160,13 @@ m_all_1x1 = m_all_1x1 && ! val.issparse () && val.numel () == 1; } +// FIXME: This function is mostly a duplicate of +// +// void tm_row_const::init (const octave_value *, const octave_value *) +// +// The common parts should be factored out into a single function that +// is used by the others. + void tm_row_const::init (const tree_argument_list& row, tree_evaluator& tw) { bool first_elem = true; @@ -214,6 +221,68 @@ } } +// FIXME: This function is mostly a duplicate of +// +// void tm_row_const::init (const tree_argument_list&, tree_evaluator&) +// +// The common parts should be factored out into a single function that +// is used by the others. + +void tm_row_const::init (const octave_value *beg, const octave_value *end) +{ + bool first_elem = true; + + for (; beg != end; beg++) + { + octave_quit (); + + octave_value tmp = *beg; + + if (tmp.is_undefined ()) + error ("undefined element in matrix list"); + + if (tmp.is_cs_list ()) + { + octave_value_list tlst = tmp.list_value (); + + for (octave_idx_type i = 0; i < tlst.length (); i++) + { + octave_quit (); + + init_element (tlst(i), first_elem); + } + } + else + init_element (tmp, first_elem); + } + + if (m_any_cell && ! m_any_class && ! m_first_elem_is_struct) + cellify (); + + first_elem = true; + + for (const auto& val : m_values) + { + octave_quit (); + + dim_vector this_elt_dv = val.dims (); + + if (! this_elt_dv.zero_by_zero ()) + { + m_all_empty = false; + + if (first_elem) + { + first_elem = false; + m_dv = this_elt_dv; + } + else if ((! m_any_class) && (! m_dv.hvcat (this_elt_dv, 1))) + eval_error ("horizontal dimensions mismatch", m_dv, this_elt_dv); + } + } +} + + octave_value tm_const::concat (char string_fill_char) const { if (m_tm_rows.empty ()) @@ -295,6 +364,16 @@ return generic_concat (); } +// FIXME: This function is mostly a duplicate of both of the functions +// +// void tm_const::init (const octave_value *, const octave_value *, +// const std::vector<int>&) +// void tm_const::init (const octave_value *, const octave_value *, +// octave_idx_type) +// +// The common parts should be factored out into a single function that +// is used by the others. + void tm_const::init (const tree_matrix& tm) { bool first_elem = true; @@ -410,6 +489,261 @@ } } +// FIXME: This function is mostly a duplicate of both of the functions +// +// void tm_const::init (const tree_matrix&) +// void tm_const::init (const octave_value *, const octave_value *, +// octave_idx_type) +// +// The common parts should be factored out into a single function that +// is used by the others. + +// For variable length rows +void tm_const::init (const octave_value *beg, const octave_value *end, + const std::vector<int>& row_lengths) +{ + bool first_elem = true; + bool first_elem_is_struct = false; + + // Just eval and figure out if what we have is complex or all strings. + // We can't check columns until we know that this is a numeric matrix -- + // collections of strings can have elements of different lengths. + + for (int i = 0; beg != end; beg += row_lengths[i++]) + { + octave_quit (); + + if (beg + row_lengths[i] > end) + error ("invalid call to tm_const::init"); + + tm_row_const row (beg, beg + row_lengths[i]); + + if (first_elem) + { + first_elem_is_struct = row.first_elem_struct_p (); + + first_elem = false; + } + + if (row.empty ()) + continue; + + if (m_all_strings && ! row.all_strings_p ()) + m_all_strings = false; + + if (m_all_sq_strings && ! row.all_sq_strings_p ()) + m_all_sq_strings = false; + + if (m_all_dq_strings && ! row.all_dq_strings_p ()) + m_all_dq_strings = false; + + if (! m_some_strings && row.some_strings_p ()) + m_some_strings = true; + + if (m_all_real && ! row.all_real_p ()) + m_all_real = false; + + if (m_all_complex && ! row.all_complex_p ()) + m_all_complex = false; + + if (m_all_empty && ! row.all_empty_p ()) + m_all_empty = false; + + if (! m_any_cell && row.any_cell_p ()) + m_any_cell = true; + + if (! m_any_sparse && row.any_sparse_p ()) + m_any_sparse = true; + + if (! m_any_class && row.any_class_p ()) + m_any_class = true; + + m_all_1x1 = m_all_1x1 && row.all_1x1_p (); + + m_tm_rows.push_back (row); + } + + if (m_any_cell && ! m_any_class && ! first_elem_is_struct) + { + for (auto& elt : m_tm_rows) + { + octave_quit (); + + elt.cellify (); + } + } + + first_elem = true; + + for (const auto& elt : m_tm_rows) + { + octave_quit (); + + octave_idx_type this_elt_nr = elt.rows (); + octave_idx_type this_elt_nc = elt.cols (); + + std::string this_elt_class_name = elt.class_name (); + m_class_name = get_concat_class (m_class_name, this_elt_class_name); + + dim_vector this_elt_dv = elt.dims (); + + m_all_empty = false; + + if (first_elem) + { + first_elem = false; + + m_dv = this_elt_dv; + } + else if (m_all_strings && m_dv.ndims () == 2 + && this_elt_dv.ndims () == 2) + { + // This is Octave's specialty. + // Character matrices support rows of unequal length. + if (m_dv.any_zero ()) + { + // Empty existing element (bug #52542). + // Replace empty element with non-empty one. + m_dv = this_elt_dv; + } + else + { + if (this_elt_nc > cols ()) + m_dv(1) = this_elt_nc; + m_dv(0) += this_elt_nr; + } + } + else if ((! m_any_class) && (! m_dv.hvcat (this_elt_dv, 0))) + eval_error ("vertical dimensions mismatch", m_dv, this_elt_dv); + } +} + +// FIXME: This function is mostly a duplicate of both of the functions +// +// void tm_const::init (const tree_matrix&) +// void tm_const::init (const octave_value *, const octave_value *, +// const std::vector<int>&) +// +// The common parts should be factored out into a single function that +// is used by the others. + +// Fixed row size +void tm_const::init (const octave_value *beg, const octave_value *end, + octave_idx_type row_length) +{ + bool first_elem = true; + bool first_elem_is_struct = false; + + // Just eval and figure out if what we have is complex or all strings. + // We can't check columns until we know that this is a numeric matrix -- + // collections of strings can have elements of different lengths. + + for (;beg != end; beg += row_length) + { + octave_quit (); + + tm_row_const row (beg, beg + row_length); + + if (first_elem) + { + first_elem_is_struct = row.first_elem_struct_p (); + + first_elem = false; + } + + if (row.empty ()) + continue; + + if (m_all_strings && ! row.all_strings_p ()) + m_all_strings = false; + + if (m_all_sq_strings && ! row.all_sq_strings_p ()) + m_all_sq_strings = false; + + if (m_all_dq_strings && ! row.all_dq_strings_p ()) + m_all_dq_strings = false; + + if (! m_some_strings && row.some_strings_p ()) + m_some_strings = true; + + if (m_all_real && ! row.all_real_p ()) + m_all_real = false; + + if (m_all_complex && ! row.all_complex_p ()) + m_all_complex = false; + + if (m_all_empty && ! row.all_empty_p ()) + m_all_empty = false; + + if (! m_any_cell && row.any_cell_p ()) + m_any_cell = true; + + if (! m_any_sparse && row.any_sparse_p ()) + m_any_sparse = true; + + if (! m_any_class && row.any_class_p ()) + m_any_class = true; + + m_all_1x1 = m_all_1x1 && row.all_1x1_p (); + + m_tm_rows.push_back (row); + } + + if (m_any_cell && ! m_any_class && ! first_elem_is_struct) + { + for (auto& elt : m_tm_rows) + { + octave_quit (); + + elt.cellify (); + } + } + + first_elem = true; + + for (const auto& elt : m_tm_rows) + { + octave_quit (); + + octave_idx_type this_elt_nr = elt.rows (); + octave_idx_type this_elt_nc = elt.cols (); + + std::string this_elt_class_name = elt.class_name (); + m_class_name = get_concat_class (m_class_name, this_elt_class_name); + + dim_vector this_elt_dv = elt.dims (); + + m_all_empty = false; + + if (first_elem) + { + first_elem = false; + + m_dv = this_elt_dv; + } + else if (m_all_strings && m_dv.ndims () == 2 + && this_elt_dv.ndims () == 2) + { + // This is Octave's specialty. + // Character matrices support rows of unequal length. + if (m_dv.any_zero ()) + { + // Empty existing element (bug #52542). + // Replace empty element with non-empty one. + m_dv = this_elt_dv; + } + else + { + if (this_elt_nc > cols ()) + m_dv(1) = this_elt_nc; + m_dv(0) += this_elt_nr; + } + } + else if ((! m_any_class) && (! m_dv.hvcat (this_elt_dv, 0))) + eval_error ("vertical dimensions mismatch", m_dv, this_elt_dv); + } +} + octave_value tm_const::char_array_concat (char string_fill_char) const { char type = (m_all_dq_strings ? '"' : '\'');
--- a/libinterp/parse-tree/pt-tm-const.h Thu Jun 15 15:46:59 2023 -0400 +++ b/libinterp/parse-tree/pt-tm-const.h Thu Jun 15 14:08:45 2023 -0400 @@ -157,6 +157,12 @@ init (row, tw); } + tm_row_const (const octave_value *beg, const octave_value *end) + : tm_info (beg == end), m_values () + { + init (beg, end); + } + tm_row_const (const tm_row_const&) = default; tm_row_const& operator = (const tm_row_const&) = delete; @@ -182,6 +188,7 @@ void init_element (const octave_value&, bool&); void init (const tree_argument_list&, tree_evaluator& tw); + void init (const octave_value *beg, const octave_value *end); }; class tm_const : public tm_info @@ -199,6 +206,20 @@ init (tm); } + tm_const (const octave_value *beg, const octave_value *end, + octave_idx_type n_rows, tree_evaluator& tw) + : tm_info (beg == end), m_evaluator (tw), m_tm_rows () + { + init (beg, end, n_rows); + } + + tm_const (const octave_value *beg, const octave_value *end, + const std::vector<int>& row_lengths, tree_evaluator& tw) + : tm_info (beg == end), m_evaluator (tw), m_tm_rows () + { + init (beg, end, row_lengths); + } + OCTAVE_DISABLE_COPY_MOVE (tm_const) ~tm_const () = default; @@ -217,6 +238,12 @@ void init (const tree_matrix& tm); + void init (const octave_value *beg, const octave_value *end, + octave_idx_type row_length); + + void init (const octave_value *beg, const octave_value *end, + const std::vector<int>& row_lengths); + octave_value char_array_concat (char string_fill_char) const; octave_value class_concat () const;