packages feed

eigen-1.2.2: cbits/eigen-proxy.cpp

#include "eigen-proxy.h"
#include <Eigen/LU>
#include <Eigen/LeastSquares>
#include <stdio.h>
#include <sstream>

static bool inited = eigen_initParallel();

class eigen_assert_exception : public std::exception {
    std::string _what;
public:
    eigen_assert_exception(const std::string& what) : _what(what) {}
    ~eigen_assert_exception() throw() {}
    const char* what() const throw () { return _what.c_str(); }
};

void eigen_assert_fail(const char* condition, const char* function, const char* file, int line) {
    std::ostringstream os;
    os << "assertion failed: " << condition << " in function " << function << " at " << file << ":" << line << std::endl;
    throw eigen_assert_exception(os.str());
}

typedef Map< Matrix<double,Dynamic,Dynamic> > MapMatrix;
typedef Map< Matrix<double,1,Dynamic> > MapVector;
typedef Map< Vector3d > MapVector3d;
typedef Map< Vector4d > MapVector4d;

extern "C" {

const char* eigen_add(
    double* data, int rows, int cols,
    const double* data1, int rows1, int cols1,
    const double* data2, int rows2, int cols2)
{
    GUARD_START
    MapMatrix(data, rows, cols) = MapMatrix(data1, rows1, cols1) + MapMatrix(data2, rows2, cols2);
    GUARD_END
}

const char* eigen_sub(
    double* data, int rows, int cols,
    const double* data1, int rows1, int cols1,
    const double* data2, int rows2, int cols2)
{
    GUARD_START
    MapMatrix(data, rows, cols) = MapMatrix(data1, rows1, cols1) - MapMatrix(data2, rows2, cols2);
    GUARD_END
}

const char* eigen_mul(
    double* data, int rows, int cols,
    const double* data1, int rows1, int cols1,
    const double* data2, int rows2, int cols2)
{
    GUARD_START
    MapMatrix(data, rows, cols) = MapMatrix(data1, rows1, cols1) * MapMatrix(data2, rows2, cols2);
    GUARD_END
}

double eigen_norm(const double* data, int rows, int cols) { return MapMatrix(data, rows, cols).norm();  }
double eigen_squaredNorm(const double* data, int rows, int cols) { return MapMatrix(data, rows, cols).squaredNorm(); }
double eigen_blueNorm(const double* data, int rows, int cols) { return MapMatrix(data, rows, cols).squaredNorm(); }
double eigen_hypotNorm(const double* data, int rows, int cols) { return MapMatrix(data, rows, cols).hypotNorm(); }
double eigen_sum(const double* data, int rows, int cols) { return MapMatrix(data, rows, cols).sum(); }
double eigen_prod(const double* data, int rows, int cols) { return MapMatrix(data, rows, cols).prod(); }
double eigen_mean(const double* data, int rows, int cols) { return MapMatrix(data, rows, cols).mean(); }
double eigen_trace(const double* data, int rows, int cols) { return MapMatrix(data, rows, cols).trace(); }
double eigen_determinant(const double* data, int rows, int cols) { return MapMatrix(data, rows, cols).determinant(); }

const char* eigen_inverse(double* data, int rows, int cols, const double* data1, int rows1, int cols1)
{
    GUARD_START
    MapMatrix(data, rows, cols) = MapMatrix(data1, rows1, cols1).inverse();
    GUARD_END
}

const char* eigen_adjoint(double* data, int rows, int cols, const double* data1, int rows1, int cols1)
{
    GUARD_START
    MapMatrix(data, rows, cols) = MapMatrix(data1, rows1, cols1).adjoint();
    GUARD_END
}

const char* eigen_conjugate(double* data, int rows, int cols, const double* data1, int rows1, int cols1)
{
    GUARD_START
    MapMatrix(data, rows, cols) = MapMatrix(data1, rows1, cols1).conjugate();
    GUARD_END
}

const char* eigen_diagonal(double* data, int rows, int cols, const double* data1, int rows1, int cols1)
{
    GUARD_START
    MapMatrix(data, rows, cols) = MapMatrix(data1, rows1, cols1).diagonal();
    GUARD_END
}

const char* eigen_transpose(double* data, int rows, int cols, const double* data1, int rows1, int cols1)
{
    GUARD_START
    MapMatrix(data, rows, cols) = MapMatrix(data1, rows1, cols1).transpose();
    GUARD_END
}

const char* eigen_dot(double* retval, 
    const double* data1, int size1,
    const double* data2, int size2)
{
    GUARD_START
    *retval = MapVector(data1, size1).dot(MapVector(data2, size2));
    GUARD_END
}

const char* eigen_cross(
    double* data,
    const double* data1,
    const double* data2)
{
    GUARD_START
    MapVector3d retval(data);
    retval = MapVector3d(data1).cross(MapVector3d(data2));
    GUARD_END
}

const char* eigen_cross3(
    double* data,
    const double* data1,
    const double* data2)
{
    GUARD_START
    MapVector4d retval(data);
    retval = MapVector4d(data1).cross3(MapVector4d(data2));
    GUARD_END
}

const char* eigen_normalize(double* data, int rows, int cols)
{
    GUARD_START
    MapMatrix(data, rows, cols).normalize();
    GUARD_END
}

const char* eigen_random(double* data, int rows, int cols)
{
    GUARD_START
    MapMatrix(data, rows, cols) = MatrixXd::Random(rows, cols);
    GUARD_END
}

const char* eigen_rank(Decomposition d, int* r, const double* data, int rows, int cols) {
    GUARD_START
    MapMatrix A(data, rows, cols);
    switch (d) {
        case ::FullPivLU:
            *r = A.fullPivLu().rank();
            break;
        case ::ColPivHouseholderQR:
            *r = A.colPivHouseholderQr().rank();
            break;
        case ::FullPivHouseholderQR:
            *r = A.fullPivHouseholderQr().rank();
            break;
        case ::JacobiSVD:
            *r = A.jacobiSvd(ComputeThinU | ComputeThinV).rank();
            break;
        default:
            return strdup("Selected decomposition doesn't support rank revealing.");
    }
    GUARD_END
}

const char* eigen_kernel(Decomposition d, double** data0, int* rows0, int* cols0, const double* data1, int rows1, int cols1) {
    GUARD_START
    if (d != ::FullPivLU)
        return strdup("Selected decomposition doesn't support kernel revealing.");
    MapMatrix A(data1, rows1, cols1);
    MatrixXd B = A.fullPivLu().kernel();
    *rows0 = B.rows();
    *cols0 = B.cols();
    *data0 = (double*)malloc(*rows0 * *cols0 * sizeof(double));
    MapMatrix(*data0, *rows0, *cols0) = B;
    GUARD_END
}

const char* eigen_image(Decomposition d, double** data0, int* rows0, int* cols0, const double* data1, int rows1, int cols1) {
    GUARD_START
    if (d != ::FullPivLU)
        return strdup("Selected decomposition doesn't support image revealing.");
    MapMatrix A(data1, rows1, cols1);
    MatrixXd B = A.fullPivLu().image(A);
    *rows0 = B.rows();
    *cols0 = B.cols();
    *data0 = (double*)malloc(*rows0 * *cols0 * sizeof(double));
    MapMatrix(*data0, *rows0, *cols0) = B;
    GUARD_END
}

const char* eigen_solve(Decomposition d,
    double* px, int rx, int cx,
    const double* pa, int ra, int ca,
    const double* pb, int rb, int cb)
{
    GUARD_START
    MapMatrix x(px, rx, cx);
    MapMatrix A(pa, ra, ca);
    MapMatrix b(pb, rb, cb);
    switch (d) {
        case ::PartialPivLU:
            x = A.partialPivLu().solve(b);
            break;
        case ::FullPivLU:
            x = A.fullPivLu().solve(b);
            break;
        case ::HouseholderQR:
            x = A.householderQr().solve(b);
            break;
        case ::ColPivHouseholderQR:
            x = A.colPivHouseholderQr().solve(b);
            break;
        case ::FullPivHouseholderQR:
            x = A.fullPivHouseholderQr().solve(b);
            break;
        case ::LLT:
            x = A.llt().solve(b);
            break;
        case ::LDLT:
            x = A.ldlt().solve(b);
            break;
        case ::JacobiSVD:
            x = A.jacobiSvd(ComputeThinU | ComputeThinV).solve(b);
            break;
    }
    GUARD_END
}


const char* eigen_relativeError(double* e,
    const double* px, int rx, int cx,
    const double* pa, int ra, int ca,
    const double* pb, int rb, int cb)
{
    GUARD_START
    MapMatrix x(px, rx, cx);
    MapMatrix A(pa, ra, ca);
    MapMatrix b(pb, rb, cb);
    *e = (A*x - b).norm() / b.norm();
    GUARD_END
}


bool eigen_initParallel() {
    initParallel();
    return true;
}

void eigen_setNbThreads(int n) {
    setNbThreads(n);
}

int eigen_getNbThreads() {
    return nbThreads();
}

}