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.