inline
HandleMap<Matrix, MutableArrayHandle<double> >&
HandleMap<Matrix, MutableArrayHandle<double> >::rebind(
    const MutableArrayHandle<double>& inHandle) {

    return rebind(inHandle, inHandle.sizeOfDim(1), inHandle.sizeOfDim(0));
}
AnyType matrix_mem_trans::run(AnyType & args)
{
    ArrayHandle<double> m = args[0].getAs<ArrayHandle<double> >();

    if (m.dims() != 2){
        throw std::invalid_argument(
            "invalid argument - 2-d array expected");
    }

    int row_m = static_cast<int>(m.sizeOfDim(0));
    int col_m = static_cast<int>(m.sizeOfDim(1));

    int dims[2] = {col_m, row_m};
    int lbs[2] = {1, 1};
    MutableArrayHandle<double> r = madlib_construct_md_array(
            NULL, NULL, 2, dims, lbs, FLOAT8TI.oid,
            FLOAT8TI.len, FLOAT8TI.byval, FLOAT8TI.align);

    for (int i = 0; i < row_m; i++){
        for(int j = 0; j < col_m; j++){
                *(r.ptr() + j * row_m + i) = *(m.ptr() + i * col_m + j);
        }
    }
    return r;
}
ArrayType*
VectorToNativeArray(const Eigen::MatrixBase<Derived>& inVector) {
    typedef typename Derived::Scalar T;
    typedef typename Derived::Index Index;

    MutableArrayHandle<T> arrayHandle
        = defaultAllocator().allocateArray<T>(inVector.size());

    T* ptr = arrayHandle.ptr();
    for (Index el = 0; el < inVector.size(); ++el)
        *(ptr++) = inVector(el);

    return arrayHandle.array();
}
AnyType rand_vector::run(AnyType & args)
{
    int dim = args[0].getAs<int>();
    if (dim < 1) {
        throw std::invalid_argument("invalid argument - dim should be positive");
    }
    MutableArrayHandle<int> r =  madlib_construct_array(
            NULL, dim, INT4TI.oid, INT4TI.len, INT4TI.byval, INT4TI.align);

    for (int i = 0; i < dim; i++){
        *(r.ptr() + i) = (int)(drand48() * 1000);
    }
    return r;
}
inline
HandleMap<ColumnVector, MutableArrayHandle<double> >&
HandleMap<ColumnVector, MutableArrayHandle<double> >::rebind(
    const MutableArrayHandle<double>& inHandle) {

    return rebind(inHandle, inHandle.sizeOfDim(0));
}
ArrayType*
MatrixToNativeArray(const Eigen::MatrixBase<Derived>& inMatrix) {
    typedef typename Derived::Scalar T;
    typedef typename Derived::Index Index;

    MutableArrayHandle<T> arrayHandle
        = defaultAllocator().allocateArray<T>(
            inMatrix.cols(), inMatrix.rows());

    T* ptr = arrayHandle.ptr();
    for (Index row = 0; row < inMatrix.rows(); ++row)
        for (Index col = 0; col < inMatrix.cols(); ++col)
            *(ptr++) = inMatrix(row, col);

    return arrayHandle.array();
}
AnyType l1_norm_with_smoothing::run(AnyType & args){
    MutableArrayHandle<double> arr = args[0].getAs<MutableArrayHandle<double> >();
    double smooth = args[1].getAs<double>();
    smooth = fabs(smooth);

    double sum = 0.0;
    for(size_t i = 0; i < arr.size(); i++)
        sum += fabs(arr[i]);
    sum += smooth * static_cast<double>(arr.size());

    double inverse_sum = 0.0;
    if (sum != 0.0)
        inverse_sum = 1.0 / sum;
    for(size_t i = 0; i < arr.size(); i++)
        arr[i] = (arr[i] + smooth) * inverse_sum;
    return arr;
}
inline
HandleMap<Matrix, MutableArrayHandle<double> >::HandleMap(
    const MutableArrayHandle<double>& inHandle)
  : Base(const_cast<double*>(inHandle.ptr()), inHandle.sizeOfDim(1),
        inHandle.sizeOfDim(0)),
    mMemoryHandle(inHandle) { }