NiHu  2.0
mex_matrix_interleaved.hpp
Go to the documentation of this file.
1 // This file is a part of NiHu, a C++ BEM template library.
2 //
3 // Copyright (C) 2012-2014 Peter Fiala <fiala@hit.bme.hu>
4 // Copyright (C) 2012-2014 Peter Rucz <rucz@hit.bme.hu>
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
30 #ifndef MEX_MATRIX_INTERLEAVED_HPP_INCLUDED
31 #define MEX_MATRIX_INTERLEAVED_HPP_INCLUDED
32 
33 #include "eigen_utils.hpp"
34 #include "../core/result_matrix.hpp"
35 
36 #include <complex>
37 #include <cstddef>
38 #include <mex.h>
39 #include <matrix.h>
40 #include <type_traits>
41 
42 namespace NiHu
43 {
44 
50 namespace mex {
51 
53 template <class Scalar>
54 struct classID;
55 
56 template <class RealScalar>
57 struct classID<std::complex<RealScalar> >
58  : public classID<RealScalar>
59 {
60 };
61 
62 template <>
63 struct classID<int>
64 {
65  static mxClassID const value = mxINT32_CLASS;
66 };
67 
68 template <>
69 struct classID<unsigned>
70 {
71  static mxClassID const value = mxUINT32_CLASS;
72 };
73 
74 template <>
75 struct classID<double>
76 {
77  static mxClassID const value = mxDOUBLE_CLASS;
78 };
79 
80 template <>
81 struct classID<float>
82 {
83  static mxClassID const value = mxSINGLE_CLASS;
84 };
85 
86 
87 
89 template <class Scalar>
90 struct complexity
91 {
92  static mxComplexity const value = mxREAL;
93 };
94 
95 template <class RealScalar>
96 struct complexity<std::complex<RealScalar> >
97 {
98  static mxComplexity const value = mxCOMPLEX;
99 };
100 
101 template <class Scalar>
102 void *get_data_ptr(mxArray const *pa);
103 
104 template <class Scalar>
105 Scalar *get_data_pointer(mxArray const *pa)
106 {
107  if (mxIsComplex(pa) != (complexity<Scalar>::value == mxCOMPLEX))
108  mexErrMsgIdAndTxt("mex_matrix_interleaved::get_data_pointer",
109  "Mex tries to access complex array as real or vica versa");
110  return static_cast<Scalar *>(get_data_ptr<Scalar>(pa));
111 }
112 
113 template <>
114 void *get_data_ptr<double>(mxArray const *pa)
115 {
116  return mxGetDoubles(pa);
117 }
118 
119 template <>
120 void *get_data_ptr<float>(mxArray const *pa)
121 {
122  return mxGetSingles(pa);
123 }
124 
125 template <>
126 void *get_data_ptr<int>(mxArray const *pa)
127 {
128  return mxGetInt32s(pa);
129 }
130 
131 template <>
132 void *get_data_ptr<unsigned>(mxArray const *pa)
133 {
134  return mxGetUint32s(pa);
135 }
136 
137 template <>
138 void *get_data_ptr<std::complex<double> >(mxArray const *pa)
139 {
140  return mxGetComplexDoubles(pa);
141 }
142 
143 template <>
144 void *get_data_ptr<std::complex<float> >(mxArray const *pa)
145 {
146  return mxGetComplexSingles(pa);
147 }
148 
150 template <class Scalar>
151 class matrix
152  : public Eigen::Map<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> >
153 {
154 public:
155  typedef Scalar scalar_t;
156  typedef Eigen::Map<Eigen::Matrix<scalar_t, Eigen::Dynamic, Eigen::Dynamic> > base_t;
157 
164  matrix(size_t rows, size_t cols, mxArray*& output)
165  : base_t(
166  static_cast<scalar_t*>(
167  get_data_pointer<scalar_t>(
168  output = mxCreateNumericMatrix(
169  rows, cols,
170  classID<scalar_t>::value,
171  complexity<scalar_t>::value
172  )
173  )
174  ),
175  rows, cols)
176  {
177  }
178 
183  matrix(mxArray const* input)
184  : base_t(
185  static_cast<scalar_t*>(get_data_pointer<scalar_t>(input)),
186  mxGetM(input),
187  mxGetN(input))
188  {
189  }
190 };
191 
192 template <class RealScalar>
193 using real_matrix = matrix<RealScalar>;
194 
195 template <class RealScalar>
196 using complex_matrix = matrix<std::complex<RealScalar> >;
197 
198 template <class Scalar>
199 Scalar const &get_scalar(mxArray const *pa)
200 {
201  return *static_cast<Scalar const *>(get_data_ptr<Scalar>(pa));
202 }
203 
204 } // end of namespace mex
205 
206 
207 template <class Scalar>
208 struct is_result_matrix_impl<mex::matrix<Scalar> > : std::true_type {};
209 
210 } // end of namespace NiHu
211 
212 #endif /* MEX_MATRIX_INTERLEAVED_HPP_INCLUDED */
213 
NiHu::mex::classID
metafunction assigning a Matlab class ID to a C type
Definition: mex_matrix_interleaved.hpp:54
NiHu::is_result_matrix_impl
Definition: result_matrix.hpp:35
eigen_utils.hpp
Implementation of Eigen related utility classes.
NiHu::mex::matrix
Matlab mex matrix.
Definition: mex_matrix_interleaved.hpp:151
NiHu::mex::matrix::matrix
matrix(mxArray const *input)
input matrix constructor
Definition: mex_matrix_interleaved.hpp:183
NiHu::mex::complexity
metafunction assigning a Matlab complexity to a C type
Definition: mex_matrix_interleaved.hpp:90
NiHu::mex::matrix::matrix
matrix(size_t rows, size_t cols, mxArray *&output)
output matrix constructor
Definition: mex_matrix_interleaved.hpp:164