#include <sicstus/sicstus.h> //#include "sicstus.h" /* ex_glue.h is generated by splfr from the foreign/[2,3] facts. Always include the glue header in your foreign resource code. */ #include "lars_glue.h" #include <mlpack/methods/lars/lars.hpp> #include <mlpack/core.hpp> // including helper functions for converting between arma structures and arrays #include "../../helper_files/helper.hpp" using namespace arma; using namespace mlpack; using namespace std; using namespace mlpack::regression; // Global Variable of the Lars regressor object so it can be accessed from all functions LARS regressor; bool isModelTrained = false; // input: const bool useCholesky, // const double lambda1, // const double lambda2, // const double tolerance // output: void initModelNoDataNoGram(SP_integer useCholesky, double lambda1, double lambda2, double tol) { regressor = new LARS((useCholesky == 1), lambda1, lambda2, tol); isModelTrained = false; } // input: const bool useCholesky, // const arma::mat & gramMatrix, // const double lambda1, // const double lambda2, // const double tolerance // output: void initModelNoDataWithGram(SP_integer useCholesky, float *gramArr, SP_integer gramSize, SP_integer gramRowNum, double lambda1, double lambda2, double tol) { mat gramMatrix = convertArrayToMat(gramArr, gramSize, gramRowNum); regressor = new LARS((useCholesky == 1), gramMatrix, lambda1, lambda2, tol); isModelTrained = false; } // input: const arma::mat & dataMatrix, // const arma::rowvec & responses, // const bool transposeData, // const bool useCholesky, // const double lambda1, // const double lambda2, // const double tolerance // output: void initModelWithDataNoGram(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum, float *responsesArr, SP_integer responsesArrSize, SP_integer transposeData, SP_integer useCholesky, double lambda1, double lambda2, double tol) { // convert the Prolog array to arma::mat mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); // check if labels fit the data if (data.n_cols != responsesArrSize) { raisePrologSystemExeption("The number of data points does not match the number of labels!"); return; } // convert the Prolog array to arma::rowvec rowvec responsesVector = convertArrayToRowvec(responsesArr, responsesArrSize); try { regressor = new LARS(data, responsesVector, (transposeData == 1), (useCholesky == 1), lambda1, lambda2, tol); } catch(const std::exception& e) { raisePrologSystemExeption(e.what()); return; } isModelTrained = true; } // input: const arma::mat & dataMatrix, // const arma::rowvec & responses, // const bool transposeData, // const bool useCholesky, // const arma::mat & gramMatrix, // const double lambda1, // const double lambda2, // const double tolerance // output: void initModelWithDataWithGram(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum, float *responsesArr, SP_integer responsesArrSize, SP_integer transposeData, SP_integer useCholesky, float *gramMatArr, SP_integer gramMatSize, SP_integer gramMatRowNum, double lambda1, double lambda2, double tol) { // convert the Prolog array to arma::mat mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); // check if labels fit the data if (data.n_cols != responsesArrSize) { raisePrologSystemExeption("The number of data points does not match the number of labels!"); return; } // convert the Prolog array to arma::rowvec rowvec responsesVector = convertArrayToRowvec(responsesArr, responsesArrSize); // convert the Prolog array to arma::mat mat gram = convertArrayToMat(gramMatArr, gramMatSize, gramMatRowNum); try { regressor = new LARS(data, responsesVector, (transposeData == 1), (useCholesky == 1), gram, lambda1, lambda2, tol); } catch(const std::exception& e) { raisePrologSystemExeption(e.what()); return; } isModelTrained = true; } // input: // output: const std::vector<size_t>& void activeSet(float **activeSetArr, SP_integer *activeSetSize) { std::vector<size_t> activeVec = regressor.ActiveSet(); // give back the sizes and the converted results as arrays *activeSetSize = activeVec.size(); *activeSetArr = convertToArray(activeVec); } // input: // output: arma::vec& void beta(float **betaArr, SP_integer *betaArrSize) { if (!isModelTrained) { raisePrologSystemExeption("The Model is not trained!"); return; } // create the ReturnVector vec betaReturnVector = regressor.Beta(); // return the Vector returnVectorInformation(betaReturnVector, betaArr, betaArrSize); } // input: // output: std::vector<arma::vec>& void betaPath(float **betaPathArr, SP_integer *betaPathColNum, SP_integer *betaPathRowNum) { if (!isModelTrained) { raisePrologSystemExeption("The Model is not trained!"); return; } // get the betaPath matrix vector<vec> matrix = regressor.BetaPath(); // return the matrix dimensions *betaPathColNum = matrix[0].size(); *betaPathRowNum = matrix.size(); // return the matrix as array *betaPathArr = convertToArray(matrix); } // input: const arma::mat &data, // const arma::rowvec &responses, // const bool rowMajor // // output: double minimum cost error double computeError(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum, float *responsesArr, SP_integer responsesArrSize, SP_integer rowMajor) { if (!isModelTrained) { raisePrologSystemExeption("The Model is not trained!"); return 0.0; } if(dataMatSize / dataMatRowNum != responsesArrSize) { cout << "Target dim doesnt fit to the Data dim" << endl; return 0.0; } // convert the Prolog array to arma::mat mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); // convert the Prolog array to arma::rowvec rowvec responsesVector = convertArrayToRowvec(responsesArr, responsesArrSize); // run the model function double result; try { result = regressor.ComputeError(data, responsesVector, (rowMajor == 1)); } catch(const std::exception& e) { raisePrologSystemExeption(e.what()); return 0.0; } return result; } // input: // output: std::vector<double>& void lambdaPath(float **lambdaPathArr, SP_integer *lambdaPathSize) { if (!isModelTrained) { raisePrologSystemExeption("The Model is not trained!"); return; } std::vector<double> lambdaPathVec = regressor.LambdaPath(); // give back the sizes and the converted results as arrays *lambdaPathSize = lambdaPathVec.size(); *lambdaPathArr = convertToArray(lambdaPathVec); } // input: // output: arma::mat& upper triangular cholesky factor void matUtriCholFactor(float **factorMatArr, SP_integer *factorMatColNum, SP_integer *factorMatRowNum) { if (!isModelTrained) { raisePrologSystemExeption("The Model is not trained!"); return; } // create the ReturnMat mat factorReturnMat = regressor.MatUtriCholFactor(); // return the Matrix returnMatrixInformation(factorReturnMat, factorMatArr, factorMatColNum, factorMatRowNum); } // input: const arma::mat &points, // arma::rowvec &predictions <-, // const bool rowMajor // output: void predict(float *pointsMatArr, SP_integer pointsMatSize, SP_integer pointsMatRowNum, float **predicArr, SP_integer *predicArrSize, SP_integer rowMajor) { if (!isModelTrained) { raisePrologSystemExeption("The Model is not trained!"); return; } // convert the Prolog array to arma::mat mat points = convertArrayToMat(pointsMatArr, pointsMatSize, pointsMatRowNum); // create the ReturnVector rowvec predicReturnVector; try { regressor.Predict(points, predicReturnVector, (rowMajor == 1)); } catch(const std::exception& e) { raisePrologSystemExeption(e.what()); return; } // return the Vector returnVectorInformation(predicReturnVector, predicArr, predicArrSize); } // input: const arma::mat &data, // const arma::rowvec &responses, // arma::vec& beta, // const bool transposeData // // output: double minimum cost error double train(float *dataMatArr, SP_integer dataMatSize, SP_integer dataMatRowNum, float *responsesArr, SP_integer responsesArrSize, float **betaArr, SP_integer *betaArrSize, SP_integer transposeData) { if(dataMatSize / dataMatRowNum != responsesArrSize) { cout << "Target dim doesnt fit to the Data dim" << endl; return 0.0; } // convert the Prolog array to arma::mat mat data = convertArrayToMat(dataMatArr, dataMatSize, dataMatRowNum); // convert the Prolog array to arma::rowvec rowvec responsesVector = convertArrayToRowvec(responsesArr, responsesArrSize); // create the ReturnVector vec betaReturnVector; // run the model function double error; try { error = regressor.Train(data, responsesVector, betaReturnVector, (transposeData == 1)); } catch(const std::exception& e) { raisePrologSystemExeption(e.what()); return 0.0; } // return the Vector returnVectorInformation(betaReturnVector, betaArr, betaArrSize); isModelTrained = true; return error; }