Mercurial > octave
comparison libinterp/corefcn/mex.cc @ 30226:f3ffb4596bd8
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.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 29 Sep 2021 16:43:08 -0400 |
parents | 3a988323d5d7 |
children | b00ff462e0f2 |
comparison
equal
deleted
inserted
replaced
30225:3a988323d5d7 | 30226:f3ffb4596bd8 |
---|---|
1545 class mxArray_base_full : public mxArray_matlab | 1545 class mxArray_base_full : public mxArray_matlab |
1546 { | 1546 { |
1547 public: | 1547 public: |
1548 | 1548 |
1549 mxArray_base_full (bool interleaved, mxClassID id, mwSize ndims, | 1549 mxArray_base_full (bool interleaved, mxClassID id, mwSize ndims, |
1550 const mwSize *dims, mxComplexity flag = mxREAL, | 1550 const mwSize *dims, bool init = true) |
1551 : mxArray_matlab (interleaved, id, ndims, dims), | |
1552 m_pr (mxArray::alloc (init, get_number_of_elements (), get_element_size ())) | |
1553 { } | |
1554 | |
1555 mxArray_base_full (bool interleaved, mxClassID id, const dim_vector& dv) | |
1556 : mxArray_matlab (interleaved, id, dv), | |
1557 m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())) | |
1558 { } | |
1559 | |
1560 mxArray_base_full (bool interleaved, mxClassID id, mwSize m, mwSize n, | |
1551 bool init = true) | 1561 bool init = true) |
1552 : mxArray_matlab (interleaved, id, ndims, dims), | 1562 : mxArray_matlab (interleaved, id, m, n), |
1553 m_complex (flag == mxCOMPLEX), | 1563 m_pr (mxArray::alloc (init, get_number_of_elements (), get_element_size ())) |
1554 m_pr (mxArray::alloc (init, get_number_of_elements (), get_element_size ())), | |
1555 m_pi (m_interleaved | |
1556 ? nullptr | |
1557 : (m_complex | |
1558 ? mxArray::alloc (init, get_number_of_elements (), get_element_size ()) | |
1559 : nullptr)) | |
1560 { } | 1564 { } |
1561 | 1565 |
1562 mxArray_base_full (bool interleaved, mxClassID id, const dim_vector& dv, | |
1563 mxComplexity flag = mxREAL) | |
1564 : mxArray_matlab (interleaved, id, dv), m_complex (flag == mxCOMPLEX), | |
1565 m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), | |
1566 m_pi (m_interleaved | |
1567 ? nullptr | |
1568 : (m_complex | |
1569 ? mxArray::calloc (get_number_of_elements (), get_element_size ()) | |
1570 : nullptr)) | |
1571 { } | |
1572 | |
1573 mxArray_base_full (bool interleaved, mxClassID id, mwSize m, mwSize n, | |
1574 mxComplexity flag = mxREAL, bool init = true) | |
1575 : mxArray_matlab (interleaved, id, m, n), m_complex (flag == mxCOMPLEX), | |
1576 m_pr (mxArray::alloc (init, get_number_of_elements (), get_element_size ())), | |
1577 m_pi (m_interleaved | |
1578 ? nullptr | |
1579 : (m_complex | |
1580 ? (mxArray::alloc (init, get_number_of_elements (), get_element_size ())) | |
1581 : nullptr)) | |
1582 { } | |
1583 | |
1584 mxArray_base_full (bool interleaved, mxClassID id, double val) | 1566 mxArray_base_full (bool interleaved, mxClassID id, double val) |
1585 : mxArray_matlab (interleaved, id, 1, 1), m_complex (false), | 1567 : mxArray_matlab (interleaved, id, 1, 1), |
1586 m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), | 1568 m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())) |
1587 m_pi (nullptr) | |
1588 { | 1569 { |
1589 double *dpr = static_cast<double *> (m_pr); | 1570 double *dpr = static_cast<double *> (m_pr); |
1590 dpr[0] = val; | 1571 dpr[0] = val; |
1591 } | 1572 } |
1592 | 1573 |
1593 mxArray_base_full (bool interleaved, mxClassID id, mxLogical val) | 1574 mxArray_base_full (bool interleaved, mxClassID id, mxLogical val) |
1594 : mxArray_matlab (interleaved, id, 1, 1), m_complex (false), | 1575 : mxArray_matlab (interleaved, id, 1, 1), |
1595 m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), | 1576 m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())) |
1596 m_pi (nullptr) | |
1597 { | 1577 { |
1598 mxLogical *lpr = static_cast<mxLogical *> (m_pr); | 1578 mxLogical *lpr = static_cast<mxLogical *> (m_pr); |
1599 lpr[0] = val; | 1579 lpr[0] = val; |
1600 } | 1580 } |
1601 | 1581 |
1602 mxArray_base_full (bool interleaved, const char *str) | 1582 mxArray_base_full (bool interleaved, const char *str) |
1603 : mxArray_matlab (interleaved, mxCHAR_CLASS, | 1583 : mxArray_matlab (interleaved, mxCHAR_CLASS, |
1604 str ? (strlen (str) ? 1 : 0) : 0, | 1584 str ? (strlen (str) ? 1 : 0) : 0, |
1605 str ? strlen (str) : 0), | 1585 str ? strlen (str) : 0), |
1606 m_complex (false), | 1586 m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())) |
1607 m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), | |
1608 m_pi (nullptr) | |
1609 { | 1587 { |
1610 mxChar *cpr = static_cast<mxChar *> (m_pr); | 1588 mxChar *cpr = static_cast<mxChar *> (m_pr); |
1611 mwSize nel = get_number_of_elements (); | 1589 mwSize nel = get_number_of_elements (); |
1612 for (mwIndex i = 0; i < nel; i++) | 1590 for (mwIndex i = 0; i < nel; i++) |
1613 cpr[i] = str[i]; | 1591 cpr[i] = str[i]; |
1614 } | 1592 } |
1615 | 1593 |
1616 // FIXME: ??? | 1594 // FIXME: ??? |
1617 mxArray_base_full (bool interleaved, mwSize m, const char **str) | 1595 mxArray_base_full (bool interleaved, mwSize m, const char **str) |
1618 : mxArray_matlab (interleaved, mxCHAR_CLASS, m, max_str_len (m, str)), | 1596 : mxArray_matlab (interleaved, mxCHAR_CLASS, m, max_str_len (m, str)), |
1619 m_complex (false), | 1597 m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())) |
1620 m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), | |
1621 m_pi (nullptr) | |
1622 { | 1598 { |
1623 mxChar *cpr = static_cast<mxChar *> (m_pr); | 1599 mxChar *cpr = static_cast<mxChar *> (m_pr); |
1624 | 1600 |
1625 mwSize *dv = get_dimensions (); | 1601 mwSize *dv = get_dimensions (); |
1626 | 1602 |
1651 } | 1627 } |
1652 | 1628 |
1653 ~mxArray_base_full (void) | 1629 ~mxArray_base_full (void) |
1654 { | 1630 { |
1655 mxFree (m_pr); | 1631 mxFree (m_pr); |
1656 mxFree (m_pi); | |
1657 } | |
1658 | |
1659 int is_complex (void) const | |
1660 { | |
1661 return m_interleaved ? m_complex : (m_pi != nullptr); | |
1662 } | 1632 } |
1663 | 1633 |
1664 double get_scalar (void) const | 1634 double get_scalar (void) const |
1665 { | 1635 { |
1666 // FIXME: how does this work for interleaved complex arrays? | 1636 // FIXME: how does this work for interleaved complex arrays? |
1724 return retval; | 1694 return retval; |
1725 } | 1695 } |
1726 | 1696 |
1727 void * get_data (void) const { return m_pr; } | 1697 void * get_data (void) const { return m_pr; } |
1728 | 1698 |
1729 void * get_imag_data (void) const | |
1730 { | |
1731 if (m_interleaved) | |
1732 panic_impossible (); | |
1733 | |
1734 return m_pi; | |
1735 } | |
1736 | |
1737 void set_data (void *pr) { m_pr = pr; } | 1699 void set_data (void *pr) { m_pr = pr; } |
1738 | |
1739 void set_imag_data (void *pi) | |
1740 { | |
1741 if (m_interleaved) | |
1742 panic_impossible (); | |
1743 | |
1744 m_pi = pi; | |
1745 } | |
1746 | 1700 |
1747 // The typed get and set functions only work for interleaved data but | 1701 // The typed get and set functions only work for interleaved data but |
1748 // they are defined here because this class owns PR. There are | 1702 // they are defined here because this class owns PR. There are |
1749 // definitions in the mxArray_separate_full class that override these | 1703 // definitions in the mxArray_separate_full class that override these |
1750 // functions. | 1704 // functions. |
2039 dim_vector dv = dims_to_dim_vector (); | 1993 dim_vector dv = dims_to_dim_vector (); |
2040 | 1994 |
2041 switch (get_class_id ()) | 1995 switch (get_class_id ()) |
2042 { | 1996 { |
2043 case mxDOUBLE_CLASS: | 1997 case mxDOUBLE_CLASS: |
2044 { | 1998 return fp_to_ov<double> (dv); |
2045 mwSize nel = get_number_of_elements (); | |
2046 | |
2047 if (is_complex ()) | |
2048 { | |
2049 if (m_interleaved) | |
2050 { | |
2051 Complex *ppr = static_cast<Complex *> (m_pr); | |
2052 | |
2053 ComplexNDArray val (dv); | |
2054 Complex *ptr = val.fortran_vec (); | |
2055 | |
2056 for (mwIndex i = 0; i < nel; i++) | |
2057 ptr[i] = ppr[i]; | |
2058 | |
2059 retval = val; | |
2060 } | |
2061 else | |
2062 { | |
2063 double *ppr = static_cast<double *> (m_pr); | |
2064 | |
2065 ComplexNDArray val (dv); | |
2066 | |
2067 Complex *ptr = val.fortran_vec (); | |
2068 | |
2069 double *ppi = static_cast<double *> (m_pi); | |
2070 | |
2071 for (mwIndex i = 0; i < nel; i++) | |
2072 ptr[i] = Complex (ppr[i], ppi[i]); | |
2073 | |
2074 retval = val; | |
2075 } | |
2076 } | |
2077 else | |
2078 { | |
2079 double *ppr = static_cast<double *> (m_pr); | |
2080 | |
2081 NDArray val (dv); | |
2082 | |
2083 double *ptr = val.fortran_vec (); | |
2084 | |
2085 for (mwIndex i = 0; i < nel; i++) | |
2086 ptr[i] = ppr[i]; | |
2087 | |
2088 retval = val; | |
2089 } | |
2090 } | |
2091 break; | |
2092 | 1999 |
2093 case mxSINGLE_CLASS: | 2000 case mxSINGLE_CLASS: |
2094 { | 2001 return fp_to_ov<float> (dv); |
2095 mwSize nel = get_number_of_elements (); | |
2096 | |
2097 if (is_complex ()) | |
2098 { | |
2099 if (m_interleaved) | |
2100 { | |
2101 FloatComplex *ppr = static_cast<FloatComplex *> (m_pr); | |
2102 | |
2103 FloatComplexNDArray val (dv); | |
2104 FloatComplex *ptr = val.fortran_vec (); | |
2105 | |
2106 for (mwIndex i = 0; i < nel; i++) | |
2107 ptr[i] = ppr[i]; | |
2108 | |
2109 retval = val; | |
2110 } | |
2111 else | |
2112 { | |
2113 float *ppr = static_cast<float *> (m_pr); | |
2114 | |
2115 FloatComplexNDArray val (dv); | |
2116 | |
2117 FloatComplex *ptr = val.fortran_vec (); | |
2118 | |
2119 float *ppi = static_cast<float *> (m_pi); | |
2120 | |
2121 for (mwIndex i = 0; i < nel; i++) | |
2122 ptr[i] = FloatComplex (ppr[i], ppi[i]); | |
2123 | |
2124 retval = val; | |
2125 } | |
2126 } | |
2127 else | |
2128 { | |
2129 float *ppr = static_cast<float *> (m_pr); | |
2130 | |
2131 FloatNDArray val (dv); | |
2132 | |
2133 float *ptr = val.fortran_vec (); | |
2134 | |
2135 for (mwIndex i = 0; i < nel; i++) | |
2136 ptr[i] = ppr[i]; | |
2137 | |
2138 retval = val; | |
2139 } | |
2140 } | |
2141 break; | |
2142 | 2002 |
2143 case mxCHAR_CLASS: | 2003 case mxCHAR_CLASS: |
2144 { | 2004 return int_to_ov<mxChar, charNDArray, char> (dv); |
2145 mwSize nel = get_number_of_elements (); | |
2146 | |
2147 mxChar *ppr = static_cast<mxChar *> (m_pr); | |
2148 | |
2149 charNDArray val (dv); | |
2150 | |
2151 char *ptr = val.fortran_vec (); | |
2152 | |
2153 for (mwIndex i = 0; i < nel; i++) | |
2154 ptr[i] = static_cast<char> (ppr[i]); | |
2155 | |
2156 retval = val; | |
2157 } | |
2158 break; | |
2159 | 2005 |
2160 case mxLOGICAL_CLASS: | 2006 case mxLOGICAL_CLASS: |
2161 retval = int_to_ov<mxLogical, boolNDArray, bool> (dv); | 2007 return int_to_ov<mxLogical, boolNDArray, bool> (dv); |
2162 break; | |
2163 | 2008 |
2164 case mxINT8_CLASS: | 2009 case mxINT8_CLASS: |
2165 retval = int_to_ov<int8_t, int8NDArray, octave_int8> (dv); | 2010 return int_to_ov<int8_t, int8NDArray, octave_int8> (dv); |
2166 break; | |
2167 | 2011 |
2168 case mxUINT8_CLASS: | 2012 case mxUINT8_CLASS: |
2169 retval = int_to_ov<uint8_t, uint8NDArray, octave_uint8> (dv); | 2013 return int_to_ov<uint8_t, uint8NDArray, octave_uint8> (dv); |
2170 break; | |
2171 | 2014 |
2172 case mxINT16_CLASS: | 2015 case mxINT16_CLASS: |
2173 retval = int_to_ov<int16_t, int16NDArray, octave_int16> (dv); | 2016 return int_to_ov<int16_t, int16NDArray, octave_int16> (dv); |
2174 break; | |
2175 | 2017 |
2176 case mxUINT16_CLASS: | 2018 case mxUINT16_CLASS: |
2177 retval = int_to_ov<uint16_t, uint16NDArray, octave_uint16> (dv); | 2019 return int_to_ov<uint16_t, uint16NDArray, octave_uint16> (dv); |
2178 break; | |
2179 | 2020 |
2180 case mxINT32_CLASS: | 2021 case mxINT32_CLASS: |
2181 retval = int_to_ov<int32_t, int32NDArray, octave_int32> (dv); | 2022 return int_to_ov<int32_t, int32NDArray, octave_int32> (dv); |
2182 break; | |
2183 | 2023 |
2184 case mxUINT32_CLASS: | 2024 case mxUINT32_CLASS: |
2185 retval = int_to_ov<uint32_t, uint32NDArray, octave_uint32> (dv); | 2025 return int_to_ov<uint32_t, uint32NDArray, octave_uint32> (dv); |
2186 break; | |
2187 | 2026 |
2188 case mxINT64_CLASS: | 2027 case mxINT64_CLASS: |
2189 retval = int_to_ov<int64_t, int64NDArray, octave_int64> (dv); | 2028 return int_to_ov<int64_t, int64NDArray, octave_int64> (dv); |
2190 break; | |
2191 | 2029 |
2192 case mxUINT64_CLASS: | 2030 case mxUINT64_CLASS: |
2193 retval = int_to_ov<uint64_t, uint64NDArray, octave_uint64> (dv); | 2031 return int_to_ov<uint64_t, uint64NDArray, octave_uint64> (dv); |
2194 break; | |
2195 | 2032 |
2196 default: | 2033 default: |
2197 panic_impossible (); | 2034 panic_impossible (); |
2198 } | 2035 } |
2199 | 2036 |
2201 } | 2038 } |
2202 | 2039 |
2203 protected: | 2040 protected: |
2204 | 2041 |
2205 mxArray_base_full (const mxArray_base_full& val) | 2042 mxArray_base_full (const mxArray_base_full& val) |
2206 : mxArray_matlab (val), m_complex (val.m_complex), | 2043 : mxArray_matlab (val), |
2207 m_pr (mxArray::malloc (get_number_of_elements () * get_element_size ())), | 2044 m_pr (mxArray::malloc (get_number_of_elements () * get_element_size ())) |
2208 m_pi (m_interleaved | 2045 { |
2209 ? nullptr | |
2210 : (val.m_pi | |
2211 ? mxArray::malloc (get_number_of_elements () * get_element_size ()) | |
2212 : nullptr)) | |
2213 { | |
2214 std::size_t nbytes = get_number_of_elements () * get_element_size (); | |
2215 | |
2216 if (m_pr) | 2046 if (m_pr) |
2217 memcpy (m_pr, val.m_pr, nbytes); | 2047 memcpy (m_pr, val.m_pr, get_number_of_elements () * get_element_size ()); |
2218 | 2048 } |
2219 if (m_pi) | 2049 |
2220 memcpy (m_pi, val.m_pi, nbytes); | 2050 template <typename ELT_T> |
2051 octave_value | |
2052 fp_to_ov (const dim_vector& dv) const | |
2053 { | |
2054 if (is_complex ()) | |
2055 { | |
2056 std::complex<ELT_T> *ppr = static_cast<std::complex<ELT_T> *> (m_pr); | |
2057 | |
2058 Array<std::complex<ELT_T>> val (dv); | |
2059 | |
2060 std::complex<ELT_T> *ptr = val.fortran_vec (); | |
2061 | |
2062 mwSize nel = get_number_of_elements (); | |
2063 | |
2064 for (mwIndex i = 0; i < nel; i++) | |
2065 ptr[i] = ppr[i]; | |
2066 | |
2067 return octave_value (val); | |
2068 } | |
2069 else | |
2070 { | |
2071 ELT_T *ppr = static_cast<ELT_T *> (m_pr); | |
2072 | |
2073 Array<ELT_T> val (dv); | |
2074 | |
2075 ELT_T *ptr = val.fortran_vec (); | |
2076 | |
2077 mwSize nel = get_number_of_elements (); | |
2078 | |
2079 for (mwIndex i = 0; i < nel; i++) | |
2080 ptr[i] = ppr[i]; | |
2081 | |
2082 return octave_value (val); | |
2083 } | |
2221 } | 2084 } |
2222 | 2085 |
2223 template <typename ELT_T, typename ARRAY_T, typename ARRAY_ELT_T> | 2086 template <typename ELT_T, typename ARRAY_T, typename ARRAY_ELT_T> |
2224 octave_value | 2087 octave_value |
2225 int_to_ov (const dim_vector& dv) const | 2088 int_to_ov (const dim_vector& dv) const |
2226 { | 2089 { |
2227 if (is_complex ()) | 2090 if (is_complex ()) |
2228 error ("complex integer types are not supported"); | 2091 error ("complex integer types are not supported"); |
2229 | 2092 |
2093 ELT_T *ppr = static_cast<ELT_T *> (m_pr); | |
2094 | |
2095 ARRAY_T val (dv); | |
2096 | |
2097 ARRAY_ELT_T *ptr = val.fortran_vec (); | |
2098 | |
2230 mwSize nel = get_number_of_elements (); | 2099 mwSize nel = get_number_of_elements (); |
2231 | |
2232 ELT_T *ppr = static_cast<ELT_T *> (m_pr); | |
2233 | |
2234 ARRAY_T val (dv); | |
2235 | |
2236 ARRAY_ELT_T *ptr = val.fortran_vec (); | |
2237 | 2100 |
2238 for (mwIndex i = 0; i < nel; i++) | 2101 for (mwIndex i = 0; i < nel; i++) |
2239 ptr[i] = ppr[i]; | 2102 ptr[i] = ppr[i]; |
2240 | 2103 |
2241 return octave_value (val); | 2104 return octave_value (val); |
2242 } | 2105 } |
2243 | 2106 |
2244 private: | 2107 protected: |
2245 | |
2246 // Flag to identify complex object if using interleaved data and PI is | |
2247 // always nullptr. | |
2248 bool m_complex; | |
2249 | 2108 |
2250 // If using interleaved complex storage, this is the pointer to data | 2109 // If using interleaved complex storage, this is the pointer to data |
2251 // (real, complex, or logical). Otherwise, it is the pointer to the | 2110 // (real, complex, or logical). Otherwise, it is the pointer to the |
2252 // real part of the data. | 2111 // real part of the data. |
2253 void *m_pr; | 2112 void *m_pr; |
2254 | |
2255 // If using non-interleaved complex storage, this is the pointer to | |
2256 // the imaginary part of the data. Othrwise is is always nullptr. | |
2257 void *m_pi; | |
2258 }; | 2113 }; |
2259 | 2114 |
2260 class mxArray_interleaved_full : public mxArray_base_full | 2115 class mxArray_interleaved_full : public mxArray_base_full |
2261 { | 2116 { |
2262 public: | 2117 public: |
2263 | 2118 |
2264 mxArray_interleaved_full (mxClassID id, mwSize ndims, const mwSize *dims, | 2119 mxArray_interleaved_full (mxClassID id, mwSize ndims, const mwSize *dims, |
2265 mxComplexity flag = mxREAL, bool init = true) | 2120 mxComplexity flag = mxREAL, bool init = true) |
2266 : mxArray_base_full (true, id, ndims, dims, flag, init) | 2121 : mxArray_base_full (true, id, ndims, dims, init), |
2122 m_complex (flag == mxCOMPLEX) | |
2267 { } | 2123 { } |
2268 | 2124 |
2269 mxArray_interleaved_full (mxClassID id, const dim_vector& dv, | 2125 mxArray_interleaved_full (mxClassID id, const dim_vector& dv, |
2270 mxComplexity flag = mxREAL) | 2126 mxComplexity flag = mxREAL) |
2271 : mxArray_base_full (true, id, dv, flag) | 2127 : mxArray_base_full (true, id, dv), |
2128 m_complex (flag == mxCOMPLEX) | |
2272 { } | 2129 { } |
2273 | 2130 |
2274 mxArray_interleaved_full (mxClassID id, mwSize m, mwSize n, | 2131 mxArray_interleaved_full (mxClassID id, mwSize m, mwSize n, |
2275 mxComplexity flag = mxREAL, bool init = true) | 2132 mxComplexity flag = mxREAL, bool init = true) |
2276 : mxArray_base_full (true, id, m, n, flag, init) | 2133 : mxArray_base_full (true, id, m, n, init), |
2134 m_complex (flag == mxCOMPLEX) | |
2277 { } | 2135 { } |
2278 | 2136 |
2279 mxArray_interleaved_full (mxClassID id, double val) | 2137 mxArray_interleaved_full (mxClassID id, double val) |
2280 : mxArray_base_full (true, id, val) | 2138 : mxArray_base_full (true, id, val), m_complex (false) |
2281 { } | 2139 { } |
2282 | 2140 |
2283 mxArray_interleaved_full (mxClassID id, mxLogical val) | 2141 mxArray_interleaved_full (mxClassID id, mxLogical val) |
2284 : mxArray_base_full (true, id, val) | 2142 : mxArray_base_full (true, id, val), m_complex (false) |
2285 { } | 2143 { } |
2286 | 2144 |
2287 mxArray_interleaved_full (const char *str) | 2145 mxArray_interleaved_full (const char *str) |
2288 : mxArray_base_full (true, str) | 2146 : mxArray_base_full (true, str), m_complex (false) |
2289 { } | 2147 { } |
2290 | 2148 |
2291 // FIXME: ??? | 2149 // FIXME: ??? |
2292 mxArray_interleaved_full (mwSize m, const char **str) | 2150 mxArray_interleaved_full (mwSize m, const char **str) |
2293 : mxArray_base_full (true, m, str) | 2151 : mxArray_base_full (true, m, str), m_complex (false) |
2294 { } | 2152 { } |
2295 | 2153 |
2296 // No assignment! FIXME: should this be implemented? Note that we | 2154 // No assignment! FIXME: should this be implemented? Note that we |
2297 // do have a copy constructor. | 2155 // do have a copy constructor. |
2298 | 2156 |
2303 return new mxArray_interleaved_full (*this); | 2161 return new mxArray_interleaved_full (*this); |
2304 } | 2162 } |
2305 | 2163 |
2306 ~mxArray_interleaved_full (void) = default; | 2164 ~mxArray_interleaved_full (void) = default; |
2307 | 2165 |
2166 int is_complex (void) const { return m_complex; } | |
2167 | |
2168 void * get_imag_data (void) const { panic_impossible (); } | |
2169 | |
2170 void set_imag_data (void */*pi*/) { panic_impossible (); } | |
2171 | |
2308 protected: | 2172 protected: |
2309 | 2173 |
2310 mxArray_interleaved_full (const mxArray_interleaved_full& val) | 2174 mxArray_interleaved_full (const mxArray_interleaved_full& val) |
2311 : mxArray_base_full (val) | 2175 : mxArray_base_full (val), m_complex (val.m_complex) |
2312 { } | 2176 { } |
2177 | |
2178 // Flag to identify complex object. | |
2179 bool m_complex; | |
2313 }; | 2180 }; |
2314 | 2181 |
2315 class mxArray_separate_full : public mxArray_base_full | 2182 class mxArray_separate_full : public mxArray_base_full |
2316 { | 2183 { |
2317 public: | 2184 public: |
2318 | 2185 |
2319 mxArray_separate_full (mxClassID id, mwSize ndims, const mwSize *dims, | 2186 mxArray_separate_full (mxClassID id, mwSize ndims, const mwSize *dims, |
2320 mxComplexity flag = mxREAL, bool init = true) | 2187 mxComplexity flag = mxREAL, bool init = true) |
2321 : mxArray_base_full (false, id, ndims, dims, flag, init) | 2188 : mxArray_base_full (false, id, ndims, dims, init), |
2189 m_pi (flag == mxCOMPLEX | |
2190 ? mxArray::alloc (init, get_number_of_elements (), get_element_size ()) | |
2191 : nullptr) | |
2322 { } | 2192 { } |
2323 | 2193 |
2324 mxArray_separate_full (mxClassID id, const dim_vector& dv, | 2194 mxArray_separate_full (mxClassID id, const dim_vector& dv, |
2325 mxComplexity flag = mxREAL) | 2195 mxComplexity flag = mxREAL) |
2326 : mxArray_base_full (false, id, dv, flag) | 2196 : mxArray_base_full (false, id, dv), |
2197 m_pi (flag == mxCOMPLEX | |
2198 ? mxArray::calloc (get_number_of_elements (), get_element_size ()) | |
2199 : nullptr) | |
2327 { } | 2200 { } |
2328 | 2201 |
2329 mxArray_separate_full (mxClassID id, mwSize m, mwSize n, | 2202 mxArray_separate_full (mxClassID id, mwSize m, mwSize n, |
2330 mxComplexity flag = mxREAL, bool init = true) | 2203 mxComplexity flag = mxREAL, bool init = true) |
2331 : mxArray_base_full (false, id, m, n, flag, init) | 2204 : mxArray_base_full (false, id, m, n, init), |
2205 m_pi (flag == mxCOMPLEX | |
2206 ? (mxArray::alloc (init, get_number_of_elements (), get_element_size ())) | |
2207 : nullptr) | |
2332 { } | 2208 { } |
2333 | 2209 |
2334 mxArray_separate_full (mxClassID id, double val) | 2210 mxArray_separate_full (mxClassID id, double val) |
2335 : mxArray_base_full (false, id, val) | 2211 : mxArray_base_full (false, id, val), m_pi (nullptr) |
2336 { } | 2212 { } |
2337 | 2213 |
2338 mxArray_separate_full (mxClassID id, mxLogical val) | 2214 mxArray_separate_full (mxClassID id, mxLogical val) |
2339 : mxArray_base_full (false, id, val) | 2215 : mxArray_base_full (false, id, val), m_pi (nullptr) |
2340 { } | 2216 { } |
2341 | 2217 |
2342 mxArray_separate_full (const char *str) | 2218 mxArray_separate_full (const char *str) |
2343 : mxArray_base_full (false, str) | 2219 : mxArray_base_full (false, str), m_pi (nullptr) |
2344 { } | 2220 { } |
2345 | 2221 |
2346 // FIXME: ??? | 2222 // FIXME: ??? |
2347 mxArray_separate_full (mwSize m, const char **str) | 2223 mxArray_separate_full (mwSize m, const char **str) |
2348 : mxArray_base_full (false, m, str) | 2224 : mxArray_base_full (false, m, str), m_pi (nullptr) |
2349 { } | 2225 { } |
2350 | 2226 |
2351 // No assignment! FIXME: should this be implemented? Note that we | 2227 // No assignment! FIXME: should this be implemented? Note that we |
2352 // do have a copy constructor. | 2228 // do have a copy constructor. |
2353 | 2229 |
2356 mxArray_base * dup (void) const | 2232 mxArray_base * dup (void) const |
2357 { | 2233 { |
2358 return new mxArray_separate_full (*this); | 2234 return new mxArray_separate_full (*this); |
2359 } | 2235 } |
2360 | 2236 |
2361 ~mxArray_separate_full (void) = default; | 2237 ~mxArray_separate_full (void) |
2238 { | |
2239 mxFree (m_pi); | |
2240 } | |
2241 | |
2242 int is_complex (void) const { return m_pi != nullptr; } | |
2243 | |
2244 void * get_imag_data (void) const { return m_pi; } | |
2245 | |
2246 void set_imag_data (void *pi) { m_pi = pi; } | |
2362 | 2247 |
2363 mxDouble * get_doubles (void) const { panic_impossible (); } | 2248 mxDouble * get_doubles (void) const { panic_impossible (); } |
2364 mxSingle * get_singles (void) const { panic_impossible (); } | 2249 mxSingle * get_singles (void) const { panic_impossible (); } |
2365 mxInt8 * get_int8s (void) const { panic_impossible (); } | 2250 mxInt8 * get_int8s (void) const { panic_impossible (); } |
2366 mxInt16 * get_int16s (void) const { panic_impossible (); } | 2251 mxInt16 * get_int16s (void) const { panic_impossible (); } |
2408 int set_complex_uint8s (mxComplexUint8 *) { panic_impossible (); } | 2293 int set_complex_uint8s (mxComplexUint8 *) { panic_impossible (); } |
2409 int set_complex_uint16s (mxComplexUint16 *) { panic_impossible (); } | 2294 int set_complex_uint16s (mxComplexUint16 *) { panic_impossible (); } |
2410 int set_complex_uint32s (mxComplexUint32 *) { panic_impossible (); } | 2295 int set_complex_uint32s (mxComplexUint32 *) { panic_impossible (); } |
2411 int set_complex_uint64s (mxComplexUint64 *) { panic_impossible (); } | 2296 int set_complex_uint64s (mxComplexUint64 *) { panic_impossible (); } |
2412 | 2297 |
2413 protected: | |
2414 | |
2415 mxArray_separate_full (const mxArray_separate_full& val) | |
2416 : mxArray_base_full (val) | |
2417 { } | |
2418 }; | |
2419 | |
2420 // Matlab-style sparse arrays. | |
2421 | |
2422 class mxArray_base_sparse : public mxArray_matlab | |
2423 { | |
2424 public: | |
2425 | |
2426 mxArray_base_sparse (bool interleaved, mxClassID id, mwSize m, mwSize n, | |
2427 mwSize nzmax, mxComplexity flag = mxREAL) | |
2428 : mxArray_matlab (interleaved, id, m, n), m_complex (flag == mxCOMPLEX), | |
2429 | |
2430 m_nzmax (nzmax > 0 ? nzmax : 1), | |
2431 m_pr (mxArray::calloc (m_nzmax, get_element_size ())), | |
2432 m_pi (m_interleaved | |
2433 ? nullptr | |
2434 : (m_complex | |
2435 ? mxArray::calloc (m_nzmax, get_element_size ()) | |
2436 : nullptr)), | |
2437 m_ir (static_cast<mwIndex *> (mxArray::calloc (m_nzmax, sizeof (mwIndex)))), | |
2438 m_jc (static_cast<mwIndex *> (mxArray::calloc (n + 1, sizeof (mwIndex)))) | |
2439 { } | |
2440 | |
2441 protected: | |
2442 | |
2443 mxArray_base_sparse (const mxArray_base_sparse& val) | |
2444 : mxArray_matlab (val), m_nzmax (val.m_nzmax), | |
2445 m_pr (mxArray::malloc (m_nzmax * get_element_size ())), | |
2446 m_pi (m_interleaved | |
2447 ? nullptr | |
2448 : (val.m_pi | |
2449 ? mxArray::malloc (m_nzmax * get_element_size ()) | |
2450 : nullptr)), | |
2451 m_ir (static_cast<mwIndex *> (mxArray::malloc (m_nzmax * sizeof (mwIndex)))), | |
2452 m_jc (static_cast<mwIndex *> (mxArray::malloc (m_nzmax * sizeof (mwIndex)))) | |
2453 { | |
2454 std::size_t nbytes = m_nzmax * get_element_size (); | |
2455 | |
2456 if (m_pr) | |
2457 memcpy (m_pr, val.m_pr, nbytes); | |
2458 | |
2459 if (m_pi) | |
2460 memcpy (m_pi, val.m_pi, nbytes); | |
2461 | |
2462 if (m_ir) | |
2463 memcpy (m_ir, val.m_ir, m_nzmax * sizeof (mwIndex)); | |
2464 | |
2465 if (m_jc) | |
2466 memcpy (m_jc, val.m_jc, (val.get_n () + 1) * sizeof (mwIndex)); | |
2467 } | |
2468 | |
2469 public: | |
2470 | |
2471 // No assignment! FIXME: should this be implemented? Note that we | |
2472 // do have a copy constructor. | |
2473 | |
2474 mxArray_base_sparse& operator = (const mxArray_base_sparse&); | |
2475 | |
2476 mxArray_base * dup (void) const | |
2477 { | |
2478 return new mxArray_base_sparse (*this); | |
2479 } | |
2480 | |
2481 ~mxArray_base_sparse (void) | |
2482 { | |
2483 mxFree (m_pr); | |
2484 mxFree (m_pi); | |
2485 mxFree (m_ir); | |
2486 mxFree (m_jc); | |
2487 } | |
2488 | |
2489 int is_complex (void) const | |
2490 { | |
2491 return m_interleaved ? m_complex : (m_pi != nullptr); | |
2492 } | |
2493 | |
2494 int is_sparse (void) const { return 1; } | |
2495 | |
2496 void * get_data (void) const { return m_pr; } | |
2497 | |
2498 void * get_imag_data (void) const | |
2499 { | |
2500 if (m_interleaved) | |
2501 panic_impossible (); | |
2502 | |
2503 return m_pi; | |
2504 } | |
2505 | |
2506 void set_data (void *pr) { m_pr = pr; } | |
2507 | |
2508 void set_imag_data (void *pi) | |
2509 { | |
2510 if (m_interleaved) | |
2511 panic_impossible (); | |
2512 | |
2513 m_pi = pi; | |
2514 } | |
2515 | |
2516 mxDouble * get_doubles (void) const | |
2517 { | |
2518 return static_cast<mxDouble *> (m_pr); | |
2519 } | |
2520 | |
2521 mxComplexDouble * get_complex_doubles (void) const | |
2522 { | |
2523 return static_cast<mxComplexDouble *> (m_pr); | |
2524 } | |
2525 | |
2526 int set_doubles (mxDouble *d) | |
2527 { | |
2528 m_pr = d; | |
2529 return 0; | |
2530 } | |
2531 | |
2532 int set_complex_doubles (mxComplexDouble * d) | |
2533 { | |
2534 m_pr = d; | |
2535 return 0; | |
2536 } | |
2537 | |
2538 mwIndex * get_ir (void) const { return m_ir; } | |
2539 | |
2540 mwIndex * get_jc (void) const { return m_jc; } | |
2541 | |
2542 mwSize get_nzmax (void) const { return m_nzmax; } | |
2543 | |
2544 void set_ir (mwIndex *ir) { m_ir = ir; } | |
2545 | |
2546 void set_jc (mwIndex *jc) { m_jc = jc; } | |
2547 | |
2548 void set_nzmax (mwSize nzmax) | |
2549 { | |
2550 /* Require storage for at least 1 element */ | |
2551 m_nzmax = (nzmax > 0 ? nzmax : 1); | |
2552 } | |
2553 | |
2554 octave_value as_octave_value (void) const | 2298 octave_value as_octave_value (void) const |
2555 { | 2299 { |
2300 if (! is_complex ()) | |
2301 return mxArray_base_full::as_octave_value (); | |
2302 | |
2556 octave_value retval; | 2303 octave_value retval; |
2557 | 2304 |
2558 dim_vector dv = dims_to_dim_vector (); | 2305 dim_vector dv = dims_to_dim_vector (); |
2559 | 2306 |
2560 switch (get_class_id ()) | 2307 switch (get_class_id ()) |
2561 { | 2308 { |
2562 case mxDOUBLE_CLASS: | 2309 case mxDOUBLE_CLASS: |
2563 { | 2310 { |
2564 if (is_complex ()) | 2311 mwSize nel = get_number_of_elements (); |
2565 { | 2312 |
2566 if (m_interleaved) | 2313 double *ppr = static_cast<double *> (m_pr); |
2567 { | 2314 |
2568 Complex *ppr = static_cast<Complex *> (m_pr); | 2315 ComplexNDArray val (dv); |
2569 | 2316 |
2570 SparseComplexMatrix val (get_m (), get_n (), | 2317 Complex *ptr = val.fortran_vec (); |
2571 static_cast<octave_idx_type> (m_nzmax)); | 2318 |
2572 | 2319 double *ppi = static_cast<double *> (m_pi); |
2573 for (mwIndex i = 0; i < m_nzmax; i++) | 2320 |
2574 { | 2321 for (mwIndex i = 0; i < nel; i++) |
2575 val.xdata (i) = ppr[i]; | 2322 ptr[i] = Complex (ppr[i], ppi[i]); |
2576 val.xridx (i) = m_ir[i]; | |
2577 } | |
2578 | |
2579 for (mwIndex i = 0; i < get_n () + 1; i++) | |
2580 val.xcidx (i) = m_jc[i]; | |
2581 | |
2582 retval = val; | |
2583 } | |
2584 else | |
2585 { | |
2586 double *ppr = static_cast<double *> (m_pr); | |
2587 double *ppi = static_cast<double *> (m_pi); | |
2588 | |
2589 SparseComplexMatrix val (get_m (), get_n (), | |
2590 static_cast<octave_idx_type> (m_nzmax)); | |
2591 | |
2592 for (mwIndex i = 0; i < m_nzmax; i++) | |
2593 { | |
2594 val.xdata (i) = Complex (ppr[i], ppi[i]); | |
2595 val.xridx (i) = m_ir[i]; | |
2596 } | |
2597 | |
2598 for (mwIndex i = 0; i < get_n () + 1; i++) | |
2599 val.xcidx (i) = m_jc[i]; | |
2600 | |
2601 retval = val; | |
2602 } | |
2603 } | |
2604 else | |
2605 { | |
2606 double *ppr = static_cast<double *> (m_pr); | |
2607 | |
2608 SparseMatrix val (get_m (), get_n (), | |
2609 static_cast<octave_idx_type> (m_nzmax)); | |
2610 | |
2611 for (mwIndex i = 0; i < m_nzmax; i++) | |
2612 { | |
2613 val.xdata (i) = ppr[i]; | |
2614 val.xridx (i) = m_ir[i]; | |
2615 } | |
2616 | |
2617 for (mwIndex i = 0; i < get_n () + 1; i++) | |
2618 val.xcidx (i) = m_jc[i]; | |
2619 | |
2620 retval = val; | |
2621 } | |
2622 } | |
2623 break; | |
2624 | |
2625 case mxLOGICAL_CLASS: | |
2626 { | |
2627 bool *ppr = static_cast<bool *> (m_pr); | |
2628 | |
2629 SparseBoolMatrix val (get_m (), get_n (), | |
2630 static_cast<octave_idx_type> (m_nzmax)); | |
2631 | |
2632 for (mwIndex i = 0; i < m_nzmax; i++) | |
2633 { | |
2634 val.xdata (i) = ppr[i]; | |
2635 val.xridx (i) = m_ir[i]; | |
2636 } | |
2637 | |
2638 for (mwIndex i = 0; i < get_n () + 1; i++) | |
2639 val.xcidx (i) = m_jc[i]; | |
2640 | 2323 |
2641 retval = val; | 2324 retval = val; |
2642 } | 2325 } |
2643 break; | 2326 break; |
2644 | 2327 |
2645 case mxSINGLE_CLASS: | 2328 case mxSINGLE_CLASS: |
2646 error ("single precision sparse data type not supported"); | 2329 { |
2330 mwSize nel = get_number_of_elements (); | |
2331 | |
2332 float *ppr = static_cast<float *> (m_pr); | |
2333 | |
2334 FloatComplexNDArray val (dv); | |
2335 | |
2336 FloatComplex *ptr = val.fortran_vec (); | |
2337 | |
2338 float *ppi = static_cast<float *> (m_pi); | |
2339 | |
2340 for (mwIndex i = 0; i < nel; i++) | |
2341 ptr[i] = FloatComplex (ppr[i], ppi[i]); | |
2342 | |
2343 retval = val; | |
2344 } | |
2345 break; | |
2346 | |
2347 case mxLOGICAL_CLASS: | |
2348 case mxINT8_CLASS: | |
2349 case mxUINT8_CLASS: | |
2350 case mxINT16_CLASS: | |
2351 case mxUINT16_CLASS: | |
2352 case mxINT32_CLASS: | |
2353 case mxUINT32_CLASS: | |
2354 case mxINT64_CLASS: | |
2355 case mxUINT64_CLASS: | |
2356 error ("complex integer types are not supported"); | |
2647 | 2357 |
2648 default: | 2358 default: |
2649 panic_impossible (); | 2359 panic_impossible (); |
2650 } | 2360 } |
2651 | 2361 |
2652 return retval; | 2362 return retval; |
2653 } | 2363 } |
2654 | 2364 |
2365 protected: | |
2366 | |
2367 mxArray_separate_full (const mxArray_separate_full& val) | |
2368 : mxArray_base_full (val), | |
2369 m_pi (val.m_pi | |
2370 ? mxArray::malloc (get_number_of_elements () * get_element_size ()) | |
2371 : nullptr) | |
2372 { | |
2373 if (m_pi) | |
2374 memcpy (m_pi, val.m_pi, get_number_of_elements () * get_element_size ()); | |
2375 } | |
2376 | |
2655 private: | 2377 private: |
2656 | 2378 |
2657 // Flag to identify complex object if using interleaved data and PI is | 2379 // Pointer to the imaginary part of the data. |
2658 // always nullptr. | 2380 void *m_pi; |
2659 bool m_complex; | 2381 }; |
2382 | |
2383 // Matlab-style sparse arrays. | |
2384 | |
2385 class mxArray_base_sparse : public mxArray_matlab | |
2386 { | |
2387 public: | |
2388 | |
2389 mxArray_base_sparse (bool interleaved, mxClassID id, mwSize m, mwSize n, | |
2390 mwSize nzmax) | |
2391 : mxArray_matlab (interleaved, id, m, n), | |
2392 | |
2393 m_nzmax (nzmax > 0 ? nzmax : 1), | |
2394 m_ir (static_cast<mwIndex *> (mxArray::calloc (m_nzmax, sizeof (mwIndex)))), | |
2395 m_jc (static_cast<mwIndex *> (mxArray::calloc (n + 1, sizeof (mwIndex)))), | |
2396 m_pr (mxArray::calloc (m_nzmax, get_element_size ())) | |
2397 { } | |
2398 | |
2399 protected: | |
2400 | |
2401 mxArray_base_sparse (const mxArray_base_sparse& val) | |
2402 : mxArray_matlab (val), m_nzmax (val.m_nzmax), | |
2403 m_ir (static_cast<mwIndex *> (mxArray::malloc (m_nzmax * sizeof (mwIndex)))), | |
2404 m_jc (static_cast<mwIndex *> (mxArray::malloc (m_nzmax * sizeof (mwIndex)))), | |
2405 m_pr (mxArray::malloc (m_nzmax * get_element_size ())) | |
2406 { | |
2407 if (m_ir) | |
2408 memcpy (m_ir, val.m_ir, m_nzmax * sizeof (mwIndex)); | |
2409 | |
2410 if (m_jc) | |
2411 memcpy (m_jc, val.m_jc, (val.get_n () + 1) * sizeof (mwIndex)); | |
2412 | |
2413 if (m_pr) | |
2414 memcpy (m_pr, val.m_pr, m_nzmax * get_element_size ()); | |
2415 } | |
2416 | |
2417 public: | |
2418 | |
2419 // No assignment! FIXME: should this be implemented? Note that we | |
2420 // do have a copy constructor. | |
2421 | |
2422 mxArray_base_sparse& operator = (const mxArray_base_sparse&); | |
2423 | |
2424 mxArray_base * dup (void) const | |
2425 { | |
2426 return new mxArray_base_sparse (*this); | |
2427 } | |
2428 | |
2429 ~mxArray_base_sparse (void) | |
2430 { | |
2431 mxFree (m_ir); | |
2432 mxFree (m_jc); | |
2433 mxFree (m_pr); | |
2434 } | |
2435 | |
2436 int is_sparse (void) const { return 1; } | |
2437 | |
2438 void * get_data (void) const { return m_pr; } | |
2439 | |
2440 void set_data (void *pr) { m_pr = pr; } | |
2441 | |
2442 mxDouble * get_doubles (void) const | |
2443 { | |
2444 return static_cast<mxDouble *> (m_pr); | |
2445 } | |
2446 | |
2447 mxComplexDouble * get_complex_doubles (void) const | |
2448 { | |
2449 return static_cast<mxComplexDouble *> (m_pr); | |
2450 } | |
2451 | |
2452 int set_doubles (mxDouble *d) | |
2453 { | |
2454 m_pr = d; | |
2455 return 0; | |
2456 } | |
2457 | |
2458 int set_complex_doubles (mxComplexDouble *d) | |
2459 { | |
2460 m_pr = d; | |
2461 return 0; | |
2462 } | |
2463 | |
2464 mwIndex * get_ir (void) const { return m_ir; } | |
2465 | |
2466 mwIndex * get_jc (void) const { return m_jc; } | |
2467 | |
2468 mwSize get_nzmax (void) const { return m_nzmax; } | |
2469 | |
2470 void set_ir (mwIndex *ir) { m_ir = ir; } | |
2471 | |
2472 void set_jc (mwIndex *jc) { m_jc = jc; } | |
2473 | |
2474 void set_nzmax (mwSize nzmax) | |
2475 { | |
2476 /* Require storage for at least 1 element */ | |
2477 m_nzmax = (nzmax > 0 ? nzmax : 1); | |
2478 } | |
2479 | |
2480 octave_value as_octave_value (void) const | |
2481 { | |
2482 octave_value retval; | |
2483 | |
2484 switch (get_class_id ()) | |
2485 { | |
2486 case mxDOUBLE_CLASS: | |
2487 return is_complex () ? to_ov<Complex> (): to_ov<double> (); | |
2488 | |
2489 case mxSINGLE_CLASS: | |
2490 error ("single precision sparse data type not supported"); | |
2491 | |
2492 case mxLOGICAL_CLASS: | |
2493 return to_ov<bool> (); | |
2494 | |
2495 default: | |
2496 panic_impossible (); | |
2497 } | |
2498 | |
2499 return retval; | |
2500 } | |
2501 | |
2502 protected: | |
2503 | |
2504 template <typename ELT_T> | |
2505 octave_value | |
2506 to_ov (void) const | |
2507 { | |
2508 ELT_T *ppr = static_cast<ELT_T *> (m_pr); | |
2509 | |
2510 Sparse<ELT_T> val (get_m (), get_n (), | |
2511 static_cast<octave_idx_type> (m_nzmax)); | |
2512 | |
2513 for (mwIndex i = 0; i < m_nzmax; i++) | |
2514 { | |
2515 val.xdata (i) = ppr[i]; | |
2516 val.xridx (i) = m_ir[i]; | |
2517 } | |
2518 | |
2519 for (mwIndex i = 0; i < get_n () + 1; i++) | |
2520 val.xcidx (i) = m_jc[i]; | |
2521 | |
2522 return octave_value (val); | |
2523 } | |
2660 | 2524 |
2661 // Maximun number of nonzero elements. | 2525 // Maximun number of nonzero elements. |
2662 mwSize m_nzmax; | 2526 mwSize m_nzmax; |
2527 | |
2528 // Sparse storage indexing arrays. | |
2529 mwIndex *m_ir; | |
2530 mwIndex *m_jc; | |
2663 | 2531 |
2664 // If using interleaved complex storage, this is the pointer to data | 2532 // If using interleaved complex storage, this is the pointer to data |
2665 // (real, complex, or logical). Otherwise, it is the pointer to the | 2533 // (real, complex, or logical). Otherwise, it is the pointer to the |
2666 // real part of the data. | 2534 // real part of the data. |
2667 void *m_pr; | 2535 void *m_pr; |
2668 | |
2669 // If using non-interleaved complex storage, this is the pointer to | |
2670 // the imaginary part of the data. Othrwise is is always nullptr. | |
2671 void *m_pi; | |
2672 | |
2673 // Sparse storage indexing arrays. | |
2674 mwIndex *m_ir; | |
2675 mwIndex *m_jc; | |
2676 }; | 2536 }; |
2677 | 2537 |
2678 class mxArray_interleaved_sparse : public mxArray_base_sparse | 2538 class mxArray_interleaved_sparse : public mxArray_base_sparse |
2679 { | 2539 { |
2680 public: | 2540 public: |
2681 | 2541 |
2682 mxArray_interleaved_sparse (mxClassID id, mwSize m, mwSize n, mwSize nzmax, | 2542 mxArray_interleaved_sparse (mxClassID id, mwSize m, mwSize n, mwSize nzmax, |
2683 mxComplexity flag = mxREAL) | 2543 mxComplexity flag = mxREAL) |
2684 : mxArray_base_sparse (true, id, m, n, nzmax, flag) | 2544 : mxArray_base_sparse (true, id, m, n, nzmax), |
2545 m_complex (flag == mxCOMPLEX) | |
2685 { } | 2546 { } |
2686 | 2547 |
2687 private: | 2548 private: |
2688 | 2549 |
2689 mxArray_interleaved_sparse (const mxArray_interleaved_sparse& val) | 2550 mxArray_interleaved_sparse (const mxArray_interleaved_sparse& val) |
2690 : mxArray_base_sparse (val) | 2551 : mxArray_base_sparse (val), m_complex (val.m_complex) |
2691 { } | 2552 { } |
2692 | 2553 |
2693 public: | 2554 public: |
2694 | 2555 |
2695 // No assignment! FIXME: should this be implemented? Note that we | 2556 // No assignment! FIXME: should this be implemented? Note that we |
2701 { | 2562 { |
2702 return new mxArray_interleaved_sparse (*this); | 2563 return new mxArray_interleaved_sparse (*this); |
2703 } | 2564 } |
2704 | 2565 |
2705 ~mxArray_interleaved_sparse (void) = default; | 2566 ~mxArray_interleaved_sparse (void) = default; |
2567 | |
2568 int is_complex (void) const { return m_complex; } | |
2569 | |
2570 void * get_imag_data (void) const { panic_impossible (); } | |
2571 | |
2572 void set_imag_data (void */*pi*/) { panic_impossible (); } | |
2573 | |
2574 private: | |
2575 | |
2576 // Flag to identify complex object if using interleaved data and PI is | |
2577 // always nullptr. | |
2578 bool m_complex; | |
2706 }; | 2579 }; |
2707 | 2580 |
2708 class mxArray_separate_sparse : public mxArray_base_sparse | 2581 class mxArray_separate_sparse : public mxArray_base_sparse |
2709 { | 2582 { |
2710 public: | 2583 public: |
2711 | 2584 |
2712 mxArray_separate_sparse (mxClassID id, mwSize m, mwSize n, mwSize nzmax, | 2585 mxArray_separate_sparse (mxClassID id, mwSize m, mwSize n, mwSize nzmax, |
2713 mxComplexity flag = mxREAL) | 2586 mxComplexity flag = mxREAL) |
2714 : mxArray_base_sparse (false, id, m, n, nzmax, flag) | 2587 : mxArray_base_sparse (false, id, m, n, nzmax), |
2588 m_pi (flag == mxCOMPLEX | |
2589 ? mxArray::calloc (m_nzmax, get_element_size ()) | |
2590 : nullptr) | |
2715 { } | 2591 { } |
2716 | 2592 |
2717 private: | 2593 private: |
2718 | 2594 |
2719 mxArray_separate_sparse (const mxArray_separate_sparse& val) | 2595 mxArray_separate_sparse (const mxArray_separate_sparse& val) |
2720 : mxArray_base_sparse (val) | 2596 : mxArray_base_sparse (val), |
2721 { } | 2597 m_pi (val.m_pi |
2598 ? mxArray::malloc (m_nzmax * get_element_size ()) | |
2599 : nullptr) | |
2600 { | |
2601 if (m_pi) | |
2602 memcpy (m_pi, val.m_pi, m_nzmax * get_element_size ()); | |
2603 } | |
2722 | 2604 |
2723 public: | 2605 public: |
2724 | 2606 |
2725 // No assignment! FIXME: should this be implemented? Note that we | 2607 // No assignment! FIXME: should this be implemented? Note that we |
2726 // do have a copy constructor. | 2608 // do have a copy constructor. |
2730 mxArray_base * dup (void) const | 2612 mxArray_base * dup (void) const |
2731 { | 2613 { |
2732 return new mxArray_separate_sparse (*this); | 2614 return new mxArray_separate_sparse (*this); |
2733 } | 2615 } |
2734 | 2616 |
2735 ~mxArray_separate_sparse (void) = default; | 2617 ~mxArray_separate_sparse (void) |
2618 { | |
2619 mxFree (m_pi); | |
2620 } | |
2621 | |
2622 int is_complex (void) const | |
2623 { | |
2624 return m_pi != nullptr; | |
2625 } | |
2626 | |
2627 void * get_imag_data (void) const { return m_pi; } | |
2628 | |
2629 void set_imag_data (void *pi) { m_pi = pi; } | |
2736 | 2630 |
2737 mxDouble * get_doubles (void) const { panic_impossible (); } | 2631 mxDouble * get_doubles (void) const { panic_impossible (); } |
2738 mxComplexDouble * get_complex_doubles (void) const { panic_impossible (); } | 2632 mxComplexDouble * get_complex_doubles (void) const { panic_impossible (); } |
2739 | 2633 |
2740 int set_doubles (mxDouble *d) { panic_impossible (); } | 2634 int set_doubles (mxDouble *) { panic_impossible (); } |
2741 int set_complex_doubles (mxComplexDouble * d) { panic_impossible (); } | 2635 int set_complex_doubles (mxComplexDouble *) { panic_impossible (); } |
2636 | |
2637 octave_value as_octave_value (void) const | |
2638 { | |
2639 if (! is_complex ()) | |
2640 return mxArray_base_sparse::as_octave_value (); | |
2641 | |
2642 octave_value retval; | |
2643 | |
2644 switch (get_class_id ()) | |
2645 { | |
2646 case mxDOUBLE_CLASS: | |
2647 { | |
2648 double *ppr = static_cast<double *> (m_pr); | |
2649 double *ppi = static_cast<double *> (m_pi); | |
2650 | |
2651 SparseComplexMatrix val (get_m (), get_n (), | |
2652 static_cast<octave_idx_type> (m_nzmax)); | |
2653 | |
2654 for (mwIndex i = 0; i < m_nzmax; i++) | |
2655 { | |
2656 val.xdata (i) = Complex (ppr[i], ppi[i]); | |
2657 val.xridx (i) = m_ir[i]; | |
2658 } | |
2659 | |
2660 for (mwIndex i = 0; i < get_n () + 1; i++) | |
2661 val.xcidx (i) = m_jc[i]; | |
2662 | |
2663 retval = val; | |
2664 } | |
2665 break; | |
2666 | |
2667 case mxSINGLE_CLASS: | |
2668 error ("single precision sparse data type not supported"); | |
2669 | |
2670 default: | |
2671 panic_impossible (); | |
2672 } | |
2673 | |
2674 return retval; | |
2675 } | |
2676 | |
2677 private: | |
2678 | |
2679 // Pointer to the imaginary part of the data. | |
2680 void *m_pi; | |
2742 }; | 2681 }; |
2743 | 2682 |
2744 // Matlab-style struct arrays. | 2683 // Matlab-style struct arrays. |
2745 | 2684 |
2746 class mxArray_struct : public mxArray_matlab | 2685 class mxArray_struct : public mxArray_matlab |
3583 } | 3522 } |
3584 | 3523 |
3585 // 1 if error should be returned to MEX file, 0 if abort. | 3524 // 1 if error should be returned to MEX file, 0 if abort. |
3586 int trap_feval_error = 0; | 3525 int trap_feval_error = 0; |
3587 | 3526 |
3588 private: | |
3589 | |
3590 // Mark a pointer as one we allocated. | 3527 // Mark a pointer as one we allocated. |
3591 void global_mark (void *ptr) | 3528 void global_mark (void *ptr) |
3592 { | 3529 { |
3593 #if defined (DEBUG) | 3530 #if defined (DEBUG) |
3594 if (s_global_memlist.find (ptr) != s_global_memlist.end ()) | 3531 if (s_global_memlist.find (ptr) != s_global_memlist.end ()) |
3609 else | 3546 else |
3610 warning ("%s: value not marked", function_name ()); | 3547 warning ("%s: value not marked", function_name ()); |
3611 #endif | 3548 #endif |
3612 } | 3549 } |
3613 | 3550 |
3614 //-------- | 3551 private: |
3615 | 3552 |
3616 // Pointer to the mex function that corresponds to this mex context. | 3553 // Pointer to the mex function that corresponds to this mex context. |
3617 octave_mex_function& m_curr_mex_fcn; | 3554 octave_mex_function& m_curr_mex_fcn; |
3618 | 3555 |
3619 // List of memory resources that need to be freed upon exit. | 3556 // List of memory resources that need to be freed upon exit. |