# HG changeset patch # User John W. Eaton # Date 1632948188 14400 # Node ID f3ffb4596bd86d583358129735bff443b9b4b6d8 # Parent 3a988323d5d7cdcc7b0a6796850927d5be866acc move ptr to imag data in mxArray to separate_full and separate_sparse classes * mex.cc (class mxArray_separate_full): Move separate pointer to imaginary array data here from mxArray_base_full along with all functions that operate on the on the separate array. (class mxArray_separate_sparse): Move separate pointer to imaginary array data here from mxArray_base_sparse along with all functions that operate on the on the separate array. (mxArray_base_full::fp_to_ov): New template to simplify the as_octave_value function. (mxArray_base_sparse::to_ov): New template to simplify the as_octave_value function. diff -r 3a988323d5d7 -r f3ffb4596bd8 libinterp/corefcn/mex.cc --- a/libinterp/corefcn/mex.cc Fri Oct 01 13:45:04 2021 -0400 +++ b/libinterp/corefcn/mex.cc Wed Sep 29 16:43:08 2021 -0400 @@ -1547,53 +1547,33 @@ public: mxArray_base_full (bool interleaved, mxClassID id, mwSize ndims, - const mwSize *dims, mxComplexity flag = mxREAL, - bool init = true) + const mwSize *dims, bool init = true) : mxArray_matlab (interleaved, id, ndims, dims), - m_complex (flag == mxCOMPLEX), - m_pr (mxArray::alloc (init, get_number_of_elements (), get_element_size ())), - m_pi (m_interleaved - ? nullptr - : (m_complex - ? mxArray::alloc (init, get_number_of_elements (), get_element_size ()) - : nullptr)) + m_pr (mxArray::alloc (init, get_number_of_elements (), get_element_size ())) { } - mxArray_base_full (bool interleaved, mxClassID id, const dim_vector& dv, - mxComplexity flag = mxREAL) - : mxArray_matlab (interleaved, id, dv), m_complex (flag == mxCOMPLEX), - m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), - m_pi (m_interleaved - ? nullptr - : (m_complex - ? mxArray::calloc (get_number_of_elements (), get_element_size ()) - : nullptr)) + mxArray_base_full (bool interleaved, mxClassID id, const dim_vector& dv) + : mxArray_matlab (interleaved, id, dv), + m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())) { } mxArray_base_full (bool interleaved, mxClassID id, mwSize m, mwSize n, - mxComplexity flag = mxREAL, bool init = true) - : mxArray_matlab (interleaved, id, m, n), m_complex (flag == mxCOMPLEX), - m_pr (mxArray::alloc (init, get_number_of_elements (), get_element_size ())), - m_pi (m_interleaved - ? nullptr - : (m_complex - ? (mxArray::alloc (init, get_number_of_elements (), get_element_size ())) - : nullptr)) + bool init = true) + : mxArray_matlab (interleaved, id, m, n), + m_pr (mxArray::alloc (init, get_number_of_elements (), get_element_size ())) { } mxArray_base_full (bool interleaved, mxClassID id, double val) - : mxArray_matlab (interleaved, id, 1, 1), m_complex (false), - m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), - m_pi (nullptr) + : mxArray_matlab (interleaved, id, 1, 1), + m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())) { double *dpr = static_cast (m_pr); dpr[0] = val; } mxArray_base_full (bool interleaved, mxClassID id, mxLogical val) - : mxArray_matlab (interleaved, id, 1, 1), m_complex (false), - m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), - m_pi (nullptr) + : mxArray_matlab (interleaved, id, 1, 1), + m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())) { mxLogical *lpr = static_cast (m_pr); lpr[0] = val; @@ -1603,9 +1583,7 @@ : mxArray_matlab (interleaved, mxCHAR_CLASS, str ? (strlen (str) ? 1 : 0) : 0, str ? strlen (str) : 0), - m_complex (false), - m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), - m_pi (nullptr) + m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())) { mxChar *cpr = static_cast (m_pr); mwSize nel = get_number_of_elements (); @@ -1616,9 +1594,7 @@ // FIXME: ??? mxArray_base_full (bool interleaved, mwSize m, const char **str) : mxArray_matlab (interleaved, mxCHAR_CLASS, m, max_str_len (m, str)), - m_complex (false), - m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), - m_pi (nullptr) + m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())) { mxChar *cpr = static_cast (m_pr); @@ -1653,12 +1629,6 @@ ~mxArray_base_full (void) { mxFree (m_pr); - mxFree (m_pi); - } - - int is_complex (void) const - { - return m_interleaved ? m_complex : (m_pi != nullptr); } double get_scalar (void) const @@ -1726,24 +1696,8 @@ void * get_data (void) const { return m_pr; } - void * get_imag_data (void) const - { - if (m_interleaved) - panic_impossible (); - - return m_pi; - } - void set_data (void *pr) { m_pr = pr; } - void set_imag_data (void *pi) - { - if (m_interleaved) - panic_impossible (); - - m_pi = pi; - } - // The typed get and set functions only work for interleaved data but // they are defined here because this class owns PR. There are // definitions in the mxArray_separate_full class that override these @@ -2041,157 +1995,40 @@ switch (get_class_id ()) { case mxDOUBLE_CLASS: - { - mwSize nel = get_number_of_elements (); - - if (is_complex ()) - { - if (m_interleaved) - { - Complex *ppr = static_cast (m_pr); - - ComplexNDArray val (dv); - Complex *ptr = val.fortran_vec (); - - for (mwIndex i = 0; i < nel; i++) - ptr[i] = ppr[i]; - - retval = val; - } - else - { - double *ppr = static_cast (m_pr); - - ComplexNDArray val (dv); - - Complex *ptr = val.fortran_vec (); - - double *ppi = static_cast (m_pi); - - for (mwIndex i = 0; i < nel; i++) - ptr[i] = Complex (ppr[i], ppi[i]); - - retval = val; - } - } - else - { - double *ppr = static_cast (m_pr); - - NDArray val (dv); - - double *ptr = val.fortran_vec (); - - for (mwIndex i = 0; i < nel; i++) - ptr[i] = ppr[i]; - - retval = val; - } - } - break; + return fp_to_ov (dv); case mxSINGLE_CLASS: - { - mwSize nel = get_number_of_elements (); - - if (is_complex ()) - { - if (m_interleaved) - { - FloatComplex *ppr = static_cast (m_pr); - - FloatComplexNDArray val (dv); - FloatComplex *ptr = val.fortran_vec (); - - for (mwIndex i = 0; i < nel; i++) - ptr[i] = ppr[i]; - - retval = val; - } - else - { - float *ppr = static_cast (m_pr); - - FloatComplexNDArray val (dv); - - FloatComplex *ptr = val.fortran_vec (); - - float *ppi = static_cast (m_pi); - - for (mwIndex i = 0; i < nel; i++) - ptr[i] = FloatComplex (ppr[i], ppi[i]); - - retval = val; - } - } - else - { - float *ppr = static_cast (m_pr); - - FloatNDArray val (dv); - - float *ptr = val.fortran_vec (); - - for (mwIndex i = 0; i < nel; i++) - ptr[i] = ppr[i]; - - retval = val; - } - } - break; + return fp_to_ov (dv); case mxCHAR_CLASS: - { - mwSize nel = get_number_of_elements (); - - mxChar *ppr = static_cast (m_pr); - - charNDArray val (dv); - - char *ptr = val.fortran_vec (); - - for (mwIndex i = 0; i < nel; i++) - ptr[i] = static_cast (ppr[i]); - - retval = val; - } - break; + return int_to_ov (dv); case mxLOGICAL_CLASS: - retval = int_to_ov (dv); - break; + return int_to_ov (dv); case mxINT8_CLASS: - retval = int_to_ov (dv); - break; + return int_to_ov (dv); case mxUINT8_CLASS: - retval = int_to_ov (dv); - break; + return int_to_ov (dv); case mxINT16_CLASS: - retval = int_to_ov (dv); - break; + return int_to_ov (dv); case mxUINT16_CLASS: - retval = int_to_ov (dv); - break; + return int_to_ov (dv); case mxINT32_CLASS: - retval = int_to_ov (dv); - break; + return int_to_ov (dv); case mxUINT32_CLASS: - retval = int_to_ov (dv); - break; + return int_to_ov (dv); case mxINT64_CLASS: - retval = int_to_ov (dv); - break; + return int_to_ov (dv); case mxUINT64_CLASS: - retval = int_to_ov (dv); - break; + return int_to_ov (dv); default: panic_impossible (); @@ -2203,21 +2040,47 @@ protected: mxArray_base_full (const mxArray_base_full& val) - : mxArray_matlab (val), m_complex (val.m_complex), - m_pr (mxArray::malloc (get_number_of_elements () * get_element_size ())), - m_pi (m_interleaved - ? nullptr - : (val.m_pi - ? mxArray::malloc (get_number_of_elements () * get_element_size ()) - : nullptr)) - { - std::size_t nbytes = get_number_of_elements () * get_element_size (); - + : mxArray_matlab (val), + m_pr (mxArray::malloc (get_number_of_elements () * get_element_size ())) + { if (m_pr) - memcpy (m_pr, val.m_pr, nbytes); - - if (m_pi) - memcpy (m_pi, val.m_pi, nbytes); + memcpy (m_pr, val.m_pr, get_number_of_elements () * get_element_size ()); + } + + template + octave_value + fp_to_ov (const dim_vector& dv) const + { + if (is_complex ()) + { + std::complex *ppr = static_cast *> (m_pr); + + Array> val (dv); + + std::complex *ptr = val.fortran_vec (); + + mwSize nel = get_number_of_elements (); + + for (mwIndex i = 0; i < nel; i++) + ptr[i] = ppr[i]; + + return octave_value (val); + } + else + { + ELT_T *ppr = static_cast (m_pr); + + Array val (dv); + + ELT_T *ptr = val.fortran_vec (); + + mwSize nel = get_number_of_elements (); + + for (mwIndex i = 0; i < nel; i++) + ptr[i] = ppr[i]; + + return octave_value (val); + } } template @@ -2227,34 +2090,26 @@ if (is_complex ()) error ("complex integer types are not supported"); - mwSize nel = get_number_of_elements (); - ELT_T *ppr = static_cast (m_pr); ARRAY_T val (dv); ARRAY_ELT_T *ptr = val.fortran_vec (); + mwSize nel = get_number_of_elements (); + for (mwIndex i = 0; i < nel; i++) ptr[i] = ppr[i]; return octave_value (val); } -private: - - // Flag to identify complex object if using interleaved data and PI is - // always nullptr. - bool m_complex; +protected: // If using interleaved complex storage, this is the pointer to data // (real, complex, or logical). Otherwise, it is the pointer to the // real part of the data. void *m_pr; - - // If using non-interleaved complex storage, this is the pointer to - // the imaginary part of the data. Othrwise is is always nullptr. - void *m_pi; }; class mxArray_interleaved_full : public mxArray_base_full @@ -2263,34 +2118,37 @@ mxArray_interleaved_full (mxClassID id, mwSize ndims, const mwSize *dims, mxComplexity flag = mxREAL, bool init = true) - : mxArray_base_full (true, id, ndims, dims, flag, init) + : mxArray_base_full (true, id, ndims, dims, init), + m_complex (flag == mxCOMPLEX) { } mxArray_interleaved_full (mxClassID id, const dim_vector& dv, mxComplexity flag = mxREAL) - : mxArray_base_full (true, id, dv, flag) + : mxArray_base_full (true, id, dv), + m_complex (flag == mxCOMPLEX) { } mxArray_interleaved_full (mxClassID id, mwSize m, mwSize n, mxComplexity flag = mxREAL, bool init = true) - : mxArray_base_full (true, id, m, n, flag, init) + : mxArray_base_full (true, id, m, n, init), + m_complex (flag == mxCOMPLEX) { } mxArray_interleaved_full (mxClassID id, double val) - : mxArray_base_full (true, id, val) + : mxArray_base_full (true, id, val), m_complex (false) { } mxArray_interleaved_full (mxClassID id, mxLogical val) - : mxArray_base_full (true, id, val) + : mxArray_base_full (true, id, val), m_complex (false) { } mxArray_interleaved_full (const char *str) - : mxArray_base_full (true, str) + : mxArray_base_full (true, str), m_complex (false) { } // FIXME: ??? mxArray_interleaved_full (mwSize m, const char **str) - : mxArray_base_full (true, m, str) + : mxArray_base_full (true, m, str), m_complex (false) { } // No assignment! FIXME: should this be implemented? Note that we @@ -2305,11 +2163,20 @@ ~mxArray_interleaved_full (void) = default; + int is_complex (void) const { return m_complex; } + + void * get_imag_data (void) const { panic_impossible (); } + + void set_imag_data (void */*pi*/) { panic_impossible (); } + protected: mxArray_interleaved_full (const mxArray_interleaved_full& val) - : mxArray_base_full (val) + : mxArray_base_full (val), m_complex (val.m_complex) { } + + // Flag to identify complex object. + bool m_complex; }; class mxArray_separate_full : public mxArray_base_full @@ -2318,34 +2185,43 @@ mxArray_separate_full (mxClassID id, mwSize ndims, const mwSize *dims, mxComplexity flag = mxREAL, bool init = true) - : mxArray_base_full (false, id, ndims, dims, flag, init) + : mxArray_base_full (false, id, ndims, dims, init), + m_pi (flag == mxCOMPLEX + ? mxArray::alloc (init, get_number_of_elements (), get_element_size ()) + : nullptr) { } mxArray_separate_full (mxClassID id, const dim_vector& dv, mxComplexity flag = mxREAL) - : mxArray_base_full (false, id, dv, flag) + : mxArray_base_full (false, id, dv), + m_pi (flag == mxCOMPLEX + ? mxArray::calloc (get_number_of_elements (), get_element_size ()) + : nullptr) { } mxArray_separate_full (mxClassID id, mwSize m, mwSize n, mxComplexity flag = mxREAL, bool init = true) - : mxArray_base_full (false, id, m, n, flag, init) + : mxArray_base_full (false, id, m, n, init), + m_pi (flag == mxCOMPLEX + ? (mxArray::alloc (init, get_number_of_elements (), get_element_size ())) + : nullptr) { } mxArray_separate_full (mxClassID id, double val) - : mxArray_base_full (false, id, val) + : mxArray_base_full (false, id, val), m_pi (nullptr) { } mxArray_separate_full (mxClassID id, mxLogical val) - : mxArray_base_full (false, id, val) + : mxArray_base_full (false, id, val), m_pi (nullptr) { } mxArray_separate_full (const char *str) - : mxArray_base_full (false, str) + : mxArray_base_full (false, str), m_pi (nullptr) { } // FIXME: ??? mxArray_separate_full (mwSize m, const char **str) - : mxArray_base_full (false, m, str) + : mxArray_base_full (false, m, str), m_pi (nullptr) { } // No assignment! FIXME: should this be implemented? Note that we @@ -2358,7 +2234,16 @@ return new mxArray_separate_full (*this); } - ~mxArray_separate_full (void) = default; + ~mxArray_separate_full (void) + { + mxFree (m_pi); + } + + int is_complex (void) const { return m_pi != nullptr; } + + void * get_imag_data (void) const { return m_pi; } + + void set_imag_data (void *pi) { m_pi = pi; } mxDouble * get_doubles (void) const { panic_impossible (); } mxSingle * get_singles (void) const { panic_impossible (); } @@ -2410,11 +2295,89 @@ int set_complex_uint32s (mxComplexUint32 *) { panic_impossible (); } int set_complex_uint64s (mxComplexUint64 *) { panic_impossible (); } + octave_value as_octave_value (void) const + { + if (! is_complex ()) + return mxArray_base_full::as_octave_value (); + + octave_value retval; + + dim_vector dv = dims_to_dim_vector (); + + switch (get_class_id ()) + { + case mxDOUBLE_CLASS: + { + mwSize nel = get_number_of_elements (); + + double *ppr = static_cast (m_pr); + + ComplexNDArray val (dv); + + Complex *ptr = val.fortran_vec (); + + double *ppi = static_cast (m_pi); + + for (mwIndex i = 0; i < nel; i++) + ptr[i] = Complex (ppr[i], ppi[i]); + + retval = val; + } + break; + + case mxSINGLE_CLASS: + { + mwSize nel = get_number_of_elements (); + + float *ppr = static_cast (m_pr); + + FloatComplexNDArray val (dv); + + FloatComplex *ptr = val.fortran_vec (); + + float *ppi = static_cast (m_pi); + + for (mwIndex i = 0; i < nel; i++) + ptr[i] = FloatComplex (ppr[i], ppi[i]); + + retval = val; + } + break; + + case mxLOGICAL_CLASS: + case mxINT8_CLASS: + case mxUINT8_CLASS: + case mxINT16_CLASS: + case mxUINT16_CLASS: + case mxINT32_CLASS: + case mxUINT32_CLASS: + case mxINT64_CLASS: + case mxUINT64_CLASS: + error ("complex integer types are not supported"); + + default: + panic_impossible (); + } + + return retval; + } + protected: mxArray_separate_full (const mxArray_separate_full& val) - : mxArray_base_full (val) - { } + : mxArray_base_full (val), + m_pi (val.m_pi + ? mxArray::malloc (get_number_of_elements () * get_element_size ()) + : nullptr) + { + if (m_pi) + memcpy (m_pi, val.m_pi, get_number_of_elements () * get_element_size ()); + } + +private: + + // Pointer to the imaginary part of the data. + void *m_pi; }; // Matlab-style sparse arrays. @@ -2424,46 +2387,31 @@ public: mxArray_base_sparse (bool interleaved, mxClassID id, mwSize m, mwSize n, - mwSize nzmax, mxComplexity flag = mxREAL) - : mxArray_matlab (interleaved, id, m, n), m_complex (flag == mxCOMPLEX), + mwSize nzmax) + : mxArray_matlab (interleaved, id, m, n), m_nzmax (nzmax > 0 ? nzmax : 1), - m_pr (mxArray::calloc (m_nzmax, get_element_size ())), - m_pi (m_interleaved - ? nullptr - : (m_complex - ? mxArray::calloc (m_nzmax, get_element_size ()) - : nullptr)), m_ir (static_cast (mxArray::calloc (m_nzmax, sizeof (mwIndex)))), - m_jc (static_cast (mxArray::calloc (n + 1, sizeof (mwIndex)))) + m_jc (static_cast (mxArray::calloc (n + 1, sizeof (mwIndex)))), + m_pr (mxArray::calloc (m_nzmax, get_element_size ())) { } protected: mxArray_base_sparse (const mxArray_base_sparse& val) : mxArray_matlab (val), m_nzmax (val.m_nzmax), - m_pr (mxArray::malloc (m_nzmax * get_element_size ())), - m_pi (m_interleaved - ? nullptr - : (val.m_pi - ? mxArray::malloc (m_nzmax * get_element_size ()) - : nullptr)), m_ir (static_cast (mxArray::malloc (m_nzmax * sizeof (mwIndex)))), - m_jc (static_cast (mxArray::malloc (m_nzmax * sizeof (mwIndex)))) - { - std::size_t nbytes = m_nzmax * get_element_size (); - - if (m_pr) - memcpy (m_pr, val.m_pr, nbytes); - - if (m_pi) - memcpy (m_pi, val.m_pi, nbytes); - + m_jc (static_cast (mxArray::malloc (m_nzmax * sizeof (mwIndex)))), + m_pr (mxArray::malloc (m_nzmax * get_element_size ())) + { if (m_ir) memcpy (m_ir, val.m_ir, m_nzmax * sizeof (mwIndex)); if (m_jc) memcpy (m_jc, val.m_jc, (val.get_n () + 1) * sizeof (mwIndex)); + + if (m_pr) + memcpy (m_pr, val.m_pr, m_nzmax * get_element_size ()); } public: @@ -2480,39 +2428,17 @@ ~mxArray_base_sparse (void) { - mxFree (m_pr); - mxFree (m_pi); mxFree (m_ir); mxFree (m_jc); - } - - int is_complex (void) const - { - return m_interleaved ? m_complex : (m_pi != nullptr); + mxFree (m_pr); } int is_sparse (void) const { return 1; } void * get_data (void) const { return m_pr; } - void * get_imag_data (void) const - { - if (m_interleaved) - panic_impossible (); - - return m_pi; - } - void set_data (void *pr) { m_pr = pr; } - void set_imag_data (void *pi) - { - if (m_interleaved) - panic_impossible (); - - m_pi = pi; - } - mxDouble * get_doubles (void) const { return static_cast (m_pr); @@ -2529,7 +2455,7 @@ return 0; } - int set_complex_doubles (mxComplexDouble * d) + int set_complex_doubles (mxComplexDouble *d) { m_pr = d; return 0; @@ -2555,83 +2481,179 @@ { octave_value retval; - dim_vector dv = dims_to_dim_vector (); + switch (get_class_id ()) + { + case mxDOUBLE_CLASS: + return is_complex () ? to_ov (): to_ov (); + + case mxSINGLE_CLASS: + error ("single precision sparse data type not supported"); + + case mxLOGICAL_CLASS: + return to_ov (); + + default: + panic_impossible (); + } + + return retval; + } + +protected: + + template + octave_value + to_ov (void) const + { + ELT_T *ppr = static_cast (m_pr); + + Sparse val (get_m (), get_n (), + static_cast (m_nzmax)); + + for (mwIndex i = 0; i < m_nzmax; i++) + { + val.xdata (i) = ppr[i]; + val.xridx (i) = m_ir[i]; + } + + for (mwIndex i = 0; i < get_n () + 1; i++) + val.xcidx (i) = m_jc[i]; + + return octave_value (val); + } + + // Maximun number of nonzero elements. + mwSize m_nzmax; + + // Sparse storage indexing arrays. + mwIndex *m_ir; + mwIndex *m_jc; + + // If using interleaved complex storage, this is the pointer to data + // (real, complex, or logical). Otherwise, it is the pointer to the + // real part of the data. + void *m_pr; +}; + +class mxArray_interleaved_sparse : public mxArray_base_sparse +{ +public: + + mxArray_interleaved_sparse (mxClassID id, mwSize m, mwSize n, mwSize nzmax, + mxComplexity flag = mxREAL) + : mxArray_base_sparse (true, id, m, n, nzmax), + m_complex (flag == mxCOMPLEX) + { } + +private: + + mxArray_interleaved_sparse (const mxArray_interleaved_sparse& val) + : mxArray_base_sparse (val), m_complex (val.m_complex) + { } + +public: + + // No assignment! FIXME: should this be implemented? Note that we + // do have a copy constructor. + + mxArray_interleaved_sparse& operator = (const mxArray_interleaved_sparse&); + + mxArray_base * dup (void) const + { + return new mxArray_interleaved_sparse (*this); + } + + ~mxArray_interleaved_sparse (void) = default; + + int is_complex (void) const { return m_complex; } + + void * get_imag_data (void) const { panic_impossible (); } + + void set_imag_data (void */*pi*/) { panic_impossible (); } + +private: + + // Flag to identify complex object if using interleaved data and PI is + // always nullptr. + bool m_complex; +}; + +class mxArray_separate_sparse : public mxArray_base_sparse +{ +public: + + mxArray_separate_sparse (mxClassID id, mwSize m, mwSize n, mwSize nzmax, + mxComplexity flag = mxREAL) + : mxArray_base_sparse (false, id, m, n, nzmax), + m_pi (flag == mxCOMPLEX + ? mxArray::calloc (m_nzmax, get_element_size ()) + : nullptr) + { } + +private: + + mxArray_separate_sparse (const mxArray_separate_sparse& val) + : mxArray_base_sparse (val), + m_pi (val.m_pi + ? mxArray::malloc (m_nzmax * get_element_size ()) + : nullptr) + { + if (m_pi) + memcpy (m_pi, val.m_pi, m_nzmax * get_element_size ()); + } + +public: + + // No assignment! FIXME: should this be implemented? Note that we + // do have a copy constructor. + + mxArray_separate_sparse& operator = (const mxArray_separate_sparse&); + + mxArray_base * dup (void) const + { + return new mxArray_separate_sparse (*this); + } + + ~mxArray_separate_sparse (void) + { + mxFree (m_pi); + } + + int is_complex (void) const + { + return m_pi != nullptr; + } + + void * get_imag_data (void) const { return m_pi; } + + void set_imag_data (void *pi) { m_pi = pi; } + + mxDouble * get_doubles (void) const { panic_impossible (); } + mxComplexDouble * get_complex_doubles (void) const { panic_impossible (); } + + int set_doubles (mxDouble *) { panic_impossible (); } + int set_complex_doubles (mxComplexDouble *) { panic_impossible (); } + + octave_value as_octave_value (void) const + { + if (! is_complex ()) + return mxArray_base_sparse::as_octave_value (); + + octave_value retval; switch (get_class_id ()) { case mxDOUBLE_CLASS: { - if (is_complex ()) - { - if (m_interleaved) - { - Complex *ppr = static_cast (m_pr); - - SparseComplexMatrix val (get_m (), get_n (), - static_cast (m_nzmax)); - - for (mwIndex i = 0; i < m_nzmax; i++) - { - val.xdata (i) = ppr[i]; - val.xridx (i) = m_ir[i]; - } - - for (mwIndex i = 0; i < get_n () + 1; i++) - val.xcidx (i) = m_jc[i]; - - retval = val; - } - else - { - double *ppr = static_cast (m_pr); - double *ppi = static_cast (m_pi); - - SparseComplexMatrix val (get_m (), get_n (), - static_cast (m_nzmax)); - - for (mwIndex i = 0; i < m_nzmax; i++) - { - val.xdata (i) = Complex (ppr[i], ppi[i]); - val.xridx (i) = m_ir[i]; - } - - for (mwIndex i = 0; i < get_n () + 1; i++) - val.xcidx (i) = m_jc[i]; - - retval = val; - } - } - else - { - double *ppr = static_cast (m_pr); - - SparseMatrix val (get_m (), get_n (), - static_cast (m_nzmax)); - - for (mwIndex i = 0; i < m_nzmax; i++) - { - val.xdata (i) = ppr[i]; - val.xridx (i) = m_ir[i]; - } - - for (mwIndex i = 0; i < get_n () + 1; i++) - val.xcidx (i) = m_jc[i]; - - retval = val; - } - } - break; - - case mxLOGICAL_CLASS: - { - bool *ppr = static_cast (m_pr); - - SparseBoolMatrix val (get_m (), get_n (), - static_cast (m_nzmax)); + double *ppr = static_cast (m_pr); + double *ppi = static_cast (m_pi); + + SparseComplexMatrix val (get_m (), get_n (), + static_cast (m_nzmax)); for (mwIndex i = 0; i < m_nzmax; i++) { - val.xdata (i) = ppr[i]; + val.xdata (i) = Complex (ppr[i], ppi[i]); val.xridx (i) = m_ir[i]; } @@ -2654,91 +2676,8 @@ private: - // Flag to identify complex object if using interleaved data and PI is - // always nullptr. - bool m_complex; - - // Maximun number of nonzero elements. - mwSize m_nzmax; - - // If using interleaved complex storage, this is the pointer to data - // (real, complex, or logical). Otherwise, it is the pointer to the - // real part of the data. - void *m_pr; - - // If using non-interleaved complex storage, this is the pointer to - // the imaginary part of the data. Othrwise is is always nullptr. + // Pointer to the imaginary part of the data. void *m_pi; - - // Sparse storage indexing arrays. - mwIndex *m_ir; - mwIndex *m_jc; -}; - -class mxArray_interleaved_sparse : public mxArray_base_sparse -{ -public: - - mxArray_interleaved_sparse (mxClassID id, mwSize m, mwSize n, mwSize nzmax, - mxComplexity flag = mxREAL) - : mxArray_base_sparse (true, id, m, n, nzmax, flag) - { } - -private: - - mxArray_interleaved_sparse (const mxArray_interleaved_sparse& val) - : mxArray_base_sparse (val) - { } - -public: - - // No assignment! FIXME: should this be implemented? Note that we - // do have a copy constructor. - - mxArray_interleaved_sparse& operator = (const mxArray_interleaved_sparse&); - - mxArray_base * dup (void) const - { - return new mxArray_interleaved_sparse (*this); - } - - ~mxArray_interleaved_sparse (void) = default; -}; - -class mxArray_separate_sparse : public mxArray_base_sparse -{ -public: - - mxArray_separate_sparse (mxClassID id, mwSize m, mwSize n, mwSize nzmax, - mxComplexity flag = mxREAL) - : mxArray_base_sparse (false, id, m, n, nzmax, flag) - { } - -private: - - mxArray_separate_sparse (const mxArray_separate_sparse& val) - : mxArray_base_sparse (val) - { } - -public: - - // No assignment! FIXME: should this be implemented? Note that we - // do have a copy constructor. - - mxArray_separate_sparse& operator = (const mxArray_separate_sparse&); - - mxArray_base * dup (void) const - { - return new mxArray_separate_sparse (*this); - } - - ~mxArray_separate_sparse (void) = default; - - mxDouble * get_doubles (void) const { panic_impossible (); } - mxComplexDouble * get_complex_doubles (void) const { panic_impossible (); } - - int set_doubles (mxDouble *d) { panic_impossible (); } - int set_complex_doubles (mxComplexDouble * d) { panic_impossible (); } }; // Matlab-style struct arrays. @@ -3585,8 +3524,6 @@ // 1 if error should be returned to MEX file, 0 if abort. int trap_feval_error = 0; -private: - // Mark a pointer as one we allocated. void global_mark (void *ptr) { @@ -3611,7 +3548,7 @@ #endif } - //-------- +private: // Pointer to the mex function that corresponds to this mex context. octave_mex_function& m_curr_mex_fcn;