C++ Objective AlgLib - c++

I have an c++ code. that i have to use in objective c.
double[,] x = new double[,]{{-1},{-0.8},{-0.6},{-0.4},{-0.2},{0},{0.2},{0.4},{0.6},{0.8},{1.0}};
double[] y = new double[]{0.223130,0.382893,0.582748,0.786628,0.941765,1.000000,0.941765,0.786628,0.582748,0.382893,0.223130};
double[] c = new double[]{0.3};
double epsf = 0;
double epsx = 0.000001;
int maxits = 0;
int info;
alglib::lsfitstate state;
alglib::lsfitreport rep;
double diffstep = 0.0001;
//
// Fitting with weights
// (you can change weights and see how it changes result)
//
double[] w = new double[]{1,1,1,1,1,1,1,1,1,1,1};
alglib::lsfitcreatewf(x, y, w, c, diffstep, out state);
alglib::lsfitsetcond(state, epsf, epsx, maxits);
alglib::lsfitfit(state, function_cx_1_func, null, null);
alglib::lsfitresults(state, out info, out c, out rep);
i already called my objective file at the end with .mm
But i get difference Errors. (first lines - expected expression when i init my vars).
I can't c++. But i only need this one function.
I hope that this is a solution for this question.
https://gis.stackexchange.com/questions/74567/math-algorithm-for-n-amount-points-in-objective-c

That is mostly Java code at the beginning for the array declarations, not C, C++ or ObjC.
This would be C/C++ code:
double x[][1] = {{-1},{-0.8},{-0.6},{-0.4},{-0.2},{0},{0.2},{0.4},{0.6},{0.8},{1.0}};
double y[] = {0.223130,0.382893,0.582748,0.786628,0.941765,1.000000,0.941765,0.786628,0.582748,0.382893,0.223130};
double c[] = {0.3};
However, according to the lsfitcreatewf function reference here, you need it to be of the type alglib::real_2d_array. There are some examples here how to generate such data.
Here and following are some general examples about how to use the lsfit subpackage.

Related

Return Double Complex Array in MEX file (Matlab)

I have a problem with MEX files in C/C++ coding.
I need to return a double complex array to Matlab but I am not able to do that and I don't find information about it. I show my code with some tries:
double complex output[nSymb];
nlhs = 1;
plhs[0] = mxCreateDoubleMatrix(nSymb,(mwSize)nlhs,mxCOMPLEX);
// 1º option
plhs[0] = output;
// 2º option
memcpy(plhs, output, nSymb * sizeof(double complex));
// 3º option
plhs = output;
Thanks you in advance.
You mentioned C++, so I've shown an example copying a std::vector<double> into an MxArray object, same can be applied to C-style arrays:
mxArray* CreateDoubleArray(const std::vector<double>& d)
{
mxArray* m = mxCreateDoubleMatrix(d.size(), 1, mxComplexity::mxReal); // mxComplexity::mxCOMPLEX
double* pm = mxGetDoubles (m); // mxGetComplexDoubles
for (size_t i=0; i<d.size(); i++)
{
pm[i] = d[i];
}
return m;
}
// ...
// Return value for the Mex:
plhs[0] = CreateDoubleArray(stdVecObj);
You can change the value_type of the vector to std::complex, and apply the changes suggested in the comments to handle complex type instead of double. mxGetComplexDoubles returns a MxDOUBLE_CLASS* documented here (it's just a struct with a real and imaginary component of type mxDouble).

Matrix multiplication issues using C++ Eigen, and matlab mexFunction

// computing the matrix operation here
// resultEigen = Input matrix
// result1Eigen = hidden bias
// result2Eigen = visible bias
// result3Eigen = weight matrix
MatrixXd H;
MatrixXd V;
double well[36];
Map<MatrixXd>( well, H.rows(), H.cols() ) = H;
H = resultEigen * result3Eigen + result1Eigen;
mexPrintf("H is here\n");
for (int i=0; i<36; i++)
{
mexPrintf("%d\n",H);
}
mexPrintf("\n");
I need to build a reconstructing function for my RBM and since direct matrix multiplication could get me a better result, I have been referring to eigen library to solve my issues but I am facing some difficulties.
when running the above code I end up getting a single value for the H matrix and I wonder why!
Moreover the parameters used in for the computation of H have been initiated as follows:
double *data1 = hbias;
Map<VectorXd>hidden_bias(data1,6,1);
VectorXd result1Eigen;
double result1[6];
result1Eigen = hidden_bias.transpose();
Map<VectorXd>(result1, result1Eigen.cols()) = result1Eigen;
// next param
double *data2 = vbias;
Map<VectorXd>visible_bias(data2,6,1);
VectorXd result2Eigen;
double result2[6];
result2Eigen = visible_bias.transpose();
Map<VectorXd>(result2, result2Eigen.cols()) = result2Eigen;
// next param
double *data3 = w;
Map<MatrixXd>weight_matrix(data3,n_visible,n_hidden);
MatrixXd result3Eigen;
// double result3[36];
mxArray * result3Matrix = mxCreateDoubleMatrix(n_visible, n_hidden, mxREAL );
double *result3=(double*)mxGetData(result3Matrix);
result3Eigen = weight_matrix.transpose();
Map<MatrixXd>(result3, result3Eigen.rows(), result3Eigen.cols()) = result3Eigen
At last I also face issues printing out data using std::cout from inside the mexFunction.
Thanks for any hints.
The problem is in the printing code which should be:
mexPrintf("%d\n",H(i));
Then, there is no need to duplicate vectors and matrices. For instance, result1 is useless, as you can get a raw pointer to the data stored in result1Eigen using result1Eigen.data(). Likewise, you can directly assign weight_matrix.transpose() to Map<MatrixXd>(result3,...), and I don't see the purpose of well.
Finally, if sizes are really known at compile-time, then better using Matrix<double,6,1> instead of a VectorXd and Matrix<double,6,6> instead of a MatrixXd. Yo ucan expect significant speedup.

Any example of `cholmod_updown_solve()` (Updating in CHOLMOD)?

I'm working on a project using CHOLMOD in C++ to do Cholesky factorization updating. The only reference I can find is the User Guide. And cholmod_updown_solve() seems to be the right function for me. But there is no example on this function and I can't get a correct result.
Below is the essential part of my code. According to the user guide, the only thing to notice seems to be sorting the update matrix C in advance. But that doesn't work. Could anyone tell me if there's any important step I missed?
Also, I'm confused because the user guide says that the solution phi will be given "in the permuted ordering, not your original ordering". How could I restore the order without knowing the permutation matrix? (L->Perm doesn't work.)
// The original system is At*A*phi = At*b
// Updates: C*Ct is added to At*A (Here C is a sparse column vector)
size_t n = m_pMesh->numVertices();
double w = 1e3;
cholmod_sparse *C;
cholmod_triplet *C_coefficients;
cholmod_dense *Delta_Atb;
cholmod_common common;
cholmod_common *cm = &common;
cholmod_start(cm);
C_coefficients = cholmod_allocate_triplet(n, 1, 2, 0, CHOLMOD_REAL, cm);
Delta_Atb = cholmod_zeros(n, 1, CHOLMOD_REAL, cm);
// updates: two more constraints
CViewerVertex *pNew = stroke_ends.start;
CViewerVertex *qNew = stroke_ends.end;
cholmodEntry(C_coefficients, pNew->sid(), pNew->sid(), w, cm);
cholmodEntry(C_coefficients, qNew->sid(), qNew->sid(), w, cm);
// change to At*b is Delta_Atb
((double*)Delta_Atb->x)[pNew->sid()] = w * w;
C = cholmod_triplet_to_sparse(C_coefficients, C_coefficients->nnz, cm);
cholmod_sort(C, cm);
// phi is the given solution to the original system At*A*phi = At*b
// L is the Cholesky factor to modify
// Both phi and L should be overwritten here
cholmod_updown_solve(1, C, L, phi, Delta_Atb, cm);
cholmod_free_sparse(&C, cm);
cholmod_free_triplet(&C_coefficients, cm);
cholmod_free_dense(&Delta_Atb, cm);
cholmod_finish(cm);

What is wrong in my mex file? input/output definition?

I am trying to run my mex function which I've written in c++ in VS. It compiles successfully in MATLAB but returns the wrong values. I'm pretty much sure, I'm not reading the 16-by-21 input matrix gammas. Can anybody see what is wrong here?
void fun(double gammas[], int num1, int num2, int length, double a[])
{
...
}
void mexFunction(int nlhs, mxArray *plhs, int nrhs, const mxArray *prhs)
{
double *gammas, *a;
int num1, num2, length;
size_t mrows, mcols;
mrows = 4; mcols = 21;
length = 21;
plhs[0] = mxCreateDoubleMatrix((mSize)mrows, (mwSize)ncols, mxREAL);
gammas = mxGetPr(prhs[0]);
num1 = (int)*mxGetPr(prhs[1]);
num2 = (int)*mxGetPr(prhs[2]);
a = mxGetPr(plhs[0]);
fun(gammas, num1, num2, length, a);
}
I get correct "a" when I call "fun" within a "main" instead of "mex" function in VS and manually provide the input gammas. I receive wrong "a" when I call the resulted mex file in my MATLAB code.
As suspected in comments to your question issue is due to how matlab and c/c++ order array elements for linear storage as 1D array in memory. Matlab uses column-major order while C/C++ uses row-major.
I would not advice you to do permutation prior to call mex-function but rather do the permutation inside the mex function. Either as suggested by #chappjc by call to permute with mexCallMatlab or by call to mxCalcSingleSubscript which returns matlab's linear index from coordinates (whatever the number of dimensions).
Side note: Need confirmation and find back great article I read about that, but matlab uses column-major ordering because it's more appropriate for matrix multiplication (creates less page-defaults when accessing memory cache, and is thus faster). Again need confirmation ... but at least this organisation is better suited for access by columns rather than by rows ...
Edit
Btw, some simple code (C#) to obtain coordinates from maltab's zero based linear index (reverse of mxCalcSingleSubscript):
private static int[] getCoordinatesFromMatlabLinearIndex(int index, int[] arrayDims)
{
var ret = new int[count];
var count = arrayDims.Length;
for (var k = 0; k < count; k++)
{
index = Math.DivRem(index, arrayDims[k], out ret[k]);
}
return ret;
}
As an alternative to inputting a transposed matrix to address the row/column-major discrepancy that CitizenInsane pointed out, you can have the transpose handled inside the MEX file. Use a helper C++ function. You can either write a loop to copy elements, or simply call permute via mexCallMATLAB. Something like the following:
int permute2DMATtoC(mxArray*& matPermuted, const mxArray* mat)
{
mxAssert(mxGetNumberOfDimensions(mat)<=3, "Requires 2D or 3D matrix.");
mxArray *permuteRHSArgs[2];
permuteRHSArgs[0] = const_cast<mxArray*>(mat);
permuteRHSArgs[1] = mxCreateDoubleMatrix(1,3,mxREAL);
mxGetPr(permuteRHSArgs[1])[0] = 2;
mxGetPr(permuteRHSArgs[1])[1] = 1;
mxGetPr(permuteRHSArgs[1])[2] = 3; // supports 2D and 3D
return mexCallMATLAB(1, &matPermuted, 2, permuteRHSArgs, "permute");
}
Use:
mxArray *matPermuted;
permute2DMATtoC(matPermuted, prhs[0]); // matPermuted is MATLAB-managed
double *gammas = (double*)mxGetData(matPermuted);
NOTE: Since matPermuted is manage by MATLAB, you don't need to explicitly destroy it to reclaim resources, but when you are done you can do this if you want:
mxDestroyArray(matPermuted);
For RGB, it may be necessary to convert pixel order (RGB-RGB-RGB-...) to planar order (RRRR...-GGGG...-BBBB...).

How can I tell what the default parameters are for CvSVMParams in opencv?

I'm pretty new to opencv and just getting used to C++ programming so this question might be pretty silly. What values are the the parameters in "struct CvSVMParams" initialized with if I leave them as their defaults and train a classifier without modifying them?
well, since opencv is open source you could just look at the source code
but it's often faster to just google it, like https://www.google.no/search?q=struct+CvSVMParams
then right click on third hit, end up at the opencv documentation http://docs.opencv.org/modules/ml/doc/support_vector_machines.html
then use your browser's page search functionality (typically [Ctrl F] for "find") to find the text "CvSVMParams" in that page, leading you down the page to http://docs.opencv.org/modules/ml/doc/support_vector_machines.html#cvsvmparams-cvsvmparams
at this point it's a matter of reading the documentation
it is a skill that is essential, so i'm not going to spoil it by repeating here what i found there in 0.5 seconds or so – just take a look. i also recommend trying to do the searching yourself, from scratch. because that's also a fundamental skill that you need and that must be trained up
Here is constructor:
https://github.com/Itseez/opencv/blob/ddf82d0b154873510802ef75c53e628cd7b2cb13/modules/ml/src/svm.cpp
// SVM training parameters
struct SvmParams
{
int svmType;
int kernelType;
double gamma;
double coef0;
double degree;
double C;
double nu;
double p;
Mat classWeights;
TermCriteria termCrit;
SvmParams()
{
svmType = SVM::C_SVC;
kernelType = SVM::RBF;
degree = 0;
gamma = 1;
coef0 = 0;
C = 1;
nu = 0;
p = 0;
termCrit = TermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
}
SvmParams( int _svmType, int _kernelType,
double _degree, double _gamma, double _coef0,
double _Con, double _nu, double _p,
const Mat& _classWeights, TermCriteria _termCrit )
{
svmType = _svmType;
kernelType = _kernelType;
degree = _degree;
gamma = _gamma;
coef0 = _coef0;
C = _Con;
nu = _nu;
p = _p;
classWeights = _classWeights;
termCrit = _termCrit;
}
};