title: Dynamic parameterization of Armadillo matrix dimensions in C++
body: <p>The title summarizes the goal that is more exactly to dynamically retrieve the number of dimensions of MATLAB arrays passed to armadillo matrices.</p>
  <p>I would like to change the second and third arguments of mY() and mD() to parametric ones below.</p>
  <pre><code>// mat(ptr_aux_mem, n_rows, n_cols, copy_aux_mem = true, strict = false)
  arma::mat mY(&amp;dY[0], 2, 168, false);
  arma::mat mD(&amp;dD[0], 2, 168, false);
  </code></pre>
  <p>This must be definitely a common use case, but I still could not find a nice way of achieving it for the general case when the number of dimensions of the arrays feeding from MATLAB could be arbitrary (n &gt; 2).</p>
  <p>For the matrix (two dimensional) case, I could possibly hack my way around but I feel like that is not elegant enough (probably not efficient either).</p>
  <p>IMHO, the way to go must be:</p>
  <p><code>matlab::data::TypedArray&lt;double&gt;</code> has <code>getDimensions()</code> member function which retrieves <code>matlab::data::ArrayDimensions</code> that is fundamentally a <code>std::vector&lt;size_t&gt;</code>.</p>
  <p>Indexing the first and second element of the vector retrieved by <code>getDimensions()</code> one can retrieve the number of rows and columns, for instance like below.</p>
  <pre><code>unsigned int mYrows = matrixY.getDimensions()[0];
  unsigned int mYcols = matrixY.getDimensions()[1];
  </code></pre>
  <p>However, with my current setup, I cannot get to call <code>getDimensions()</code> through pointers/references in the <code>foo()</code> function of sub.cpp. If it is feasible, I would neither like to create additional temporary objects nor passing other arguments to <code>foo()</code>. How it possible that way?</p>
  <p>Intuition keeps telling me that there must be an elegant solution that way too. Maybe using multiple indirection?</p>
  <p>I would highly appreciate any help, hints or constructive comments from more knowledgeable SO members. Thank you in advance.</p>
  <p><strong>Setup:</strong></p>
  <p>Two C++ source files and a header file:</p>
  <p><strong>main.cpp</strong></p>
  <ul>
  <li>contains the general IO interface between MATLAB and C++</li>
  <li>feeds two double arrays and two double const doubles into C++</li>
  <li>it does some Armadillo based looping (this part is not that important therefore omitted) by calling <em>foo()</em></li>
  <li>returns <em>outp</em> which is a “just a plain” scalar double</li>
  <li>Nothing fancy or complicated.</li>
  </ul>
  <p><strong>sub.cpp</strong></p>
  <ul>
  <li>This is only for the <em>foo()</em> looping part.</li>
  </ul>
  <p><strong>sub.hpp</strong></p>
  <ul>
  <li>Just a simple header file.</li>
  </ul>
  <pre><code>// main.cpp
  // MATLAB API Header Files
  #include &quot;mex.hpp&quot;
  #include &quot;mexAdapter.hpp&quot;
  
  // Custom header
  #include &quot;sub.hpp&quot;
  
  // Overloading the function call operator, thus class acts as a functor
  class MexFunction : public matlab::mex::Function {
      public:
          void operator()(matlab::mex::ArgumentList outputs,
                          matlab::mex::ArgumentList inputs){
              
              matlab::data::ArrayFactory factory;
              // Validate arguments
              checkArguments(outputs, inputs);
  
              matlab::data::TypedArray&lt;double&gt; matrixY = std::move(inputs[0]);
              matlab::data::TypedArray&lt;double&gt; matrixD = std::move(inputs[1]);
              const double csT = inputs[2][0];
              const double csKy = inputs[3][0];
  
              buffer_ptr_t&lt;double&gt; mY = matrixY.release();
              buffer_ptr_t&lt;double&gt; mD = matrixD.release();
  
              double* darrY = mY.get();
              double* darrD = mD.get();
  
              // data type of outp is &quot;just&quot; a plain double, NOT a double array
              double outp = foo(darrY, darrD, csT, csKy);
  
              outputs[0] = factory.createScalar(outp);
  
              void checkArguments(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs){
              // Create pointer to MATLAB engine
              std::shared_ptr&lt;matlab::engine::MATLABEngine&gt; matlabPtr = getEngine();
              // Create array factory, allows us to create MATLAB arrays in C++
              matlab::data::ArrayFactory factory;
              // Check input size and types
              if (inputs[0].getType() != ArrayType::DOUBLE ||
                  inputs[0].getType() == ArrayType::COMPLEX_DOUBLE)
              {
                  // Throw error directly into MATLAB if type does not match
                  matlabPtr-&gt;feval(u&quot;error&quot;, 0,
                      std::vector&lt;Array&gt;({ factory.createScalar(&quot;Input must be double array.&quot;) }));
              }
              // Check output size
              if (outputs.size() &gt; 1) {
                  matlabPtr-&gt;feval(u&quot;error&quot;, 0, 
                      std::vector&lt;Array&gt;({ factory.createScalar(&quot;Only one output is returned.&quot;) }));
                  }
          }
  };
  
  // sub.cpp
  
  #include &quot;sub.hpp&quot;
  #include &quot;armadillo&quot;
  
  double foo(double* dY, double* dD, const double T, const double Ky) {
      
      double sum = 0;
  
      // Conversion of input parameters to Armadillo types
      // mat(ptr_aux_mem, n_rows, n_cols, copy_aux_mem = true, strict = false)
      arma::mat mY(&amp;dY[0], 2, 168, false);
      arma::mat mD(&amp;dD[0], 2, 168, false);
  
      // Armadillo calculations
  
      for(int t=0; t&lt;int(T); t++){
  
          // some armadillo based calculation
          // each for cycle increments sum by its return value 
      }
  
      return sum;
  }
  
  // sub.hpp
  
  #ifndef SUB_H_INCLUDED
  #define SUB_H_INCLUDED
  
  double foo(double* dY, double* dD, const double T, const double Ky);
  
  #endif // SUB_H_INCLUDED
  </code></pre>