casadi_from_mex.hpp
1 //
2 // MIT No Attribution
3 //
4 // Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl, KU Leuven.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
7 // software and associated documentation files (the "Software"), to deal in the Software
8 // without restriction, including without limitation the rights to use, copy, modify,
9 // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13 // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
16 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
17 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 //
19 
20 // SYMBOL "from_mex"
21 template<typename T1>
22 T1* casadi_from_mex(const mxArray* p, T1* y, const casadi_int* sp, T1* w) {
23  casadi_int nrow, ncol, is_sparse, c, k, p_nrow, p_ncol;
24  const casadi_int *colind, *row;
25  mwIndex *Jc, *Ir;
26  const double* p_data;
27  if (!mxIsDouble(p) || mxGetNumberOfDimensions(p)!=2)
28  mexErrMsgIdAndTxt("Casadi:RuntimeError",
29  "\"from_mex\" failed: Not a two-dimensional matrix of double precision.");
30  nrow = *sp++;
31  ncol = *sp++;
32  colind = sp;
33  row = sp+ncol+1;
34  p_nrow = mxGetM(p);
35  p_ncol = mxGetN(p);
36  is_sparse = mxIsSparse(p);
37  Jc = 0;
38  Ir = 0;
39  if (is_sparse) {
40  Jc = mxGetJc(p);
41  Ir = mxGetIr(p);
42  }
43  p_data = (const double*)mxGetData(p);
44  if (p_nrow==1 && p_ncol==1) {
45  casadi_int nnz;
46  double v = is_sparse && Jc[1]==0 ? 0 : *p_data;
47  nnz = sp[ncol];
48  casadi_fill(y, nnz, v);
49  } else {
50  casadi_int tr = 0;
51  if (nrow!=p_nrow || ncol!=p_ncol) {
52  tr = nrow==p_ncol && ncol==p_nrow && (nrow==1 || ncol==1);
53  if (!tr) mexErrMsgIdAndTxt("Casadi:RuntimeError",
54  "\"from_mex\" failed: Dimension mismatch. "
55  "Expected %d-by-%d, got %d-by-%d instead.",
56  nrow, ncol, p_nrow, p_ncol);
57  }
58  if (is_sparse) {
59  if (tr) {
60  for (c=0; c<ncol; ++c)
61  for (k=colind[c]; k<colind[c+1]; ++k) w[row[k]+c*nrow]=0;
62  for (c=0; c<p_ncol; ++c)
63  for (k=Jc[c]; k<(casadi_int) Jc[c+1]; ++k) w[c+Ir[k]*p_ncol] = p_data[k];
64  for (c=0; c<ncol; ++c)
65  for (k=colind[c]; k<colind[c+1]; ++k) y[k] = w[row[k]+c*nrow];
66  } else {
67  for (c=0; c<ncol; ++c) {
68  for (k=colind[c]; k<colind[c+1]; ++k) w[row[k]]=0;
69  for (k=Jc[c]; k<(casadi_int) Jc[c+1]; ++k) w[Ir[k]]=p_data[k];
70  for (k=colind[c]; k<colind[c+1]; ++k) y[k]=w[row[k]];
71  }
72  }
73  } else {
74  for (c=0; c<ncol; ++c) {
75  for (k=colind[c]; k<colind[c+1]; ++k) {
76  y[k] = p_data[row[k]+c*nrow];
77  }
78  }
79  }
80  }
81  return y;
82 }