Error when calling C++ function from R and integrate it - c++

I want to numerically integrate a 1-dimensional function (that was written in C++) with the R function integrate. As a short example, I coded the function myfunc in C++.
#include <cmath>
#include <Rcpp.h>
using namespace std;
// [[Rcpp::export]]
double myfunc (double x){
double result;
result = exp( -0.5*pow(x,2) + 2*x );
return result;
}
After loading myfunc in R and integrating it, I obtain the following error:
library(Rcpp)
sourceCpp("myfunc.cpp")
integrate(myfunc,lower=0,upper=10)
Error in f(x, ...) : Expecting a single value: [extent=21].
Can anyone explain what this error means and how I can solve this problem?

From help("integrate"):
f must accept a vector of inputs and produce a vector of function evaluations at those points. The Vectorize function may be helpful to convert f to this form.
You have created your function to accept a single value, a double, so when integrate() tries to pass it a vector, it rightfully complains. So, try
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::NumericVector myfunc(Rcpp::NumericVector x){
return exp(-0.5 * pow(x, 2) + 2 * x);
}
/*** R
integrate(myfunc, lower = 0, upper = 10)
*/
Resulting in
integrate(myfunc, lower = 0, upper = 10)
# 18.10025 with absolute error < 5.1e-08
Or, using myfunc() compiled from your C++ code from above,
f <- Vectorize(myfunc)
integrate(f, lower = 0, upper = 10)
# 18.10025 with absolute error < 5.1e-08

Related

How do I input a quadratic equation in C++?

We were given an assignment to program the following, which I have been trying to figure out how to solve for the last 2 hours but to no avail.
How do you actually solve a complex formula having different operations in one mathematical expression?
For you to properly understand which of the operations are to be solved in order, try recreating the quadratic equation, ax^2 + bx + c, in C++ on your own!
Instructions:
The value of a, b, c, and x are already provided for you in the code editor. Remake the formula using C++'s math functions and operators and store it into one variable.
Print the value of the variable that stores the formula. To understand which to actually solve first in the equation, try tracing it out by yourself and manually solve it and see if your answer match that of the sample output.
Sample output: 16
TL;DR I am told to recreate the quadratic equation on my own using the given variables with their values.
Here is my current output which failed:
#include<iostream>
#include <cmath>
int main(void) {
int a = 2;
int b = 2;
int c = 4;
int x = 2;
// TODO:
// 1. Compute for the result of the quadratic equation
// using the variables provided above and the math library
double result;
result = (a * x + b * x) pow(2, 2) + c;
// 2. Print the output required by the output sample
std::cout << result;
return 0;
}
It prints out 4 when it should be 16.
You use this code:
result = a * pow(x, 2) + b * x + c;

Eigen LLT Module Giving incorrect result?

First off, I assume the problem is with me and not with Eigen's LLT module. That said, here is the code (I will explain the problem briefly) but sourcing the code in Rstudio should recreate the bug.
#include <RcppEigen.h>
using namespace Rcpp;
using Eigen::MatrixXd;
using Eigen::VectorXd;
// [[Rcpp::depends(RcppEigen)]]
template <typename T>
void fillUnitNormal(Eigen::PlainObjectBase<T>& Z){
int m = Z.rows();
int n = Z.cols();
Rcpp::NumericVector r(m*n);
r = Rcpp::rnorm(m*n, 0, 1); // using vectorization from Rcpp sugar
std::copy(std::begin(r), std::end(r), Z.data());
}
template <typename T1, typename T2, typename T3>
// #param z is object derived from class MatrixBase to overwrite with sample
// #param m MAP estimate
// #param S the hessian of the NEGATIVE log-likelihood evaluated at m
// #param pars structure of type pars
// #return int 0 success, 1 failure
int cholesky_lap(Eigen::MatrixBase<T1>& z, Eigen::MatrixBase<T2>& m,
Eigen::MatrixBase<T3>& S){
int nc=z.cols();
int nr=z.rows();
Eigen::LLT<MatrixXd> hesssqrt;
hesssqrt.compute(-S);
if (hesssqrt.info() == Eigen::NumericalIssue){
Rcpp::warning("Cholesky of Hessian failed with status status Eigen::NumericalIssue");
return 1;
}
typename T1::PlainObject samp(nr, nc);
fillUnitNormal(samp);
z = hesssqrt.matrixL().solve(samp);
z.template colwise() += m;
return 0;
}
// #param z an object derived from class MatrixBase to overwrite with samples
// #param m MAP estimate (as a vector)
// #param S the hessian of the NEGATIVE log-likelihood evaluated at m
// block forms should be given as blocks row bound together, blocks
// must be square and of the same size!
// [[Rcpp::export]]
Eigen::MatrixXd LaplaceApproximation(int n_samples, Eigen::VectorXd m,
Eigen::MatrixXd S){
int p=m.rows();
MatrixXd z = MatrixXd::Zero(p, n_samples);
int status = cholesky_lap(z, m, S);
if (status==1) Rcpp::stop("decomposition failed");
return z;
}
/*** R
library(testthat)
n_samples <- 1000000
m <- 1:3
S <- diag(1:3)
S[1,2] <- S[2,1] <- -1
S <- -S # Pretending this is the negative precision matrix
# e.g., hessian of negative log likelihood
z <- LaplaceApproximation(n_samples, m, S)
expect_equal(var(t(z)), solve(-S), tolerance=0.005)
expect_equal(rowMeans(z), m, tolerance=.01)
*/
Here is the (key) output:
> expect_equal(var(t(z)), solve(-S), tolerance=0.005)
Error: var(t(z)) not equal to solve(-S).
2/9 mismatches (average diff: 1)
[1] 0.998 - 2 == -1
[5] 2.003 - 1 == 1
In Words:
I am trying to write a function to perform a Laplace approximation. This means essentially sampling from a multivariate normal with mean m and covariance inverse(-S) where S is the Hessian of the negative log-liklihood.
My code works perfectly for an eigen decomposition I coded but for some reason, it is failing with the Cholesky. (I have tried to just give a minimal reproducible example and for space am not showing the eigen decomposition).
The best thought I have now is that some aliasing issue is happening but I can't figure out where that would be...
Thank you in advance!
It turned out to be a simple math error. Not a code error. Issue was that cholesky of matrix inverse has a transpose compared to just the inverse of the cholesky of the original matrix. Changing
z = hesssqrt.matrixL().solve(samp);
to
z = hesssqrt.matrixU().solve(samp);
Solved the problem.

What is the best way to apply a function to a subset of a vector?

Say I have a vector<int> positions that represents positions that I would like to subset from, and two Rcpp::NumericVector vectors A and B that I want to subset (both can be treated also as vector<double>).
What would be the best way to calculate what in R I would write as
sum(A[positions]) (a double), or A[positions] / B[positions] (a vector[double])?
Basically, I would like to access the elements of the vectors at certain positions without making copies (or a for loop) if I do not have to.
Example in R:
positions = c(2,4,5) # just a vector with positions
A = rnorm(100) # a vector with 100 random numbers
B = rnorm(100)
mysum <- sum(A[positions])
mysmallvector <- A[positions] / B[positions] # or (A/B)[positions]
Right now I just loop through all the values of positions and and subset the vectors by position one by one, but I can't help thinking there is a more elegant solution.
So, replicating R's functionality in Rcpp is not necessarily ideal. For one, you should definitely check out the caveats to subsetting in Rcpp using Rcpp sugar expressions. Secondly, you are using a for loop even within R due to the vectorization structure R has.
You may wish to consider using RcppArmadillo instead of Rcpp data types. The downside to this is you will incur a copy hit when the data is ported into C++ and then back to R. With Rcpp data types, you will avoid that but you will have to define your own operations (see divide_subset() below).
With this being said, we can replicate the functionality requested via Rcpp:
#include <Rcpp.h>
using namespace Rcpp;
// Uses sugar index subsets
// [[Rcpp::export]]
NumericVector subset(NumericVector x, IntegerVector idx) {
return x[idx];
}
// Uses sugar summation function (e.g. a nice for loop)
// [[Rcpp::export]]
double sum_subset(NumericVector x, IntegerVector idx) {
return sum(subset(x,idx));
}
// No sugar for element-wise division
// [[Rcpp::export]]
NumericVector divide_subset(NumericVector x, NumericVector y, IntegerVector idx) {
unsigned int n = idx.size();
NumericVector a(n);
for(unsigned int i = 0; i < idx.size(); i++){
a[i] = x[idx[i]]/y[idx[i]];
}
return a;
}
/*** R
set.seed(1334)
positions = c(2,4,5)
# Subtract one from indexes for C++
pos_cpp = positions - 1
A = rnorm(100) # a vector with 100 random numbers
B = rnorm(100)
mysum = sum(A[positions])
cppsum = sum_subset(A, pos_cpp)
all.equal(cppsum, mysum)
mysmallvector = A[positions] / B[positions] # or (A/B)[positions]
cppdivide = divide_subset(A,B, pos_cpp)
all.equal(cppdivide, mysmallvector)
*/

Concatenate and Lists in Rcpp

I am just getting starting with Rcpp so this might be a very stupid question. Here is the specific question (context is provided below)
What is the Rcpp equivalent of
odes <- c(A = 1.0, B = 2.0, C = 3.0, D = 4.0, E = 5.0, F = 6.0, G = 7.0)
list(odes)
Context - I am trying to solve a system of Ordinary Differential Equation (ODEs) using the deSolve package's vode solver, but using Rcpp package to write the right hand side of ODEs in a compiled code. The solver expects the function which forms the RHS of ODEs to return a list, specifically in this case the RHS from a .R function (which the solver was able to intergrate successfully) was of the form
> X
[[1]]
9000000.00 -9000000.00 0.00 19993.04 -19993.04 -19993.04 -9000000.00
and I want my .cpp file to spit out odes as a list of similar form.
Any help here would be much appreciated!!
As suggested below, I am pasting the code to show exactly what I am doing
#include <Rcpp.h>
using namespace Rcpp;
// This is a simple example of exporting a C++ function to R. You can
// source this function into an R session using the Rcpp::sourceCpp
// function (or via the Source button on the editor toolbar). Learn
// more about Rcpp at:
//
// http://www.rcpp.org/
// http://adv-r.had.co.nz/Rcpp.html
// http://gallery.rcpp.org/
//
// [[Rcpp::export]]
List odes_gprotein(double t, NumericVector A, NumericVector p) {
NumericVector odes_vec(A.length());
List odes(1);
double Flux1 = p[1] * A[4] * A[5] - p[0] * A[3];
double Flux2 = p[2] * A[5] - p[3];
double Flux3 = p[4] * A[3];
double Flux4 = p[5] * A[1] * A[6];
double Flux5 = p[6] * A[0] * A[3];
double Flux6 = p[7] * A[2];
odes_vec[0] = (Flux4 - Flux5);
odes_vec[1] = (-Flux4 + Flux6);
odes_vec[2] = (Flux5 - Flux6);
odes_vec[3] = (Flux1 - Flux3);
odes_vec[4] = (-Flux1);
odes_vec[5] = (-Flux1 - Flux2);
odes_vec[6] = (-Flux4 + Flux5);
odes = List(odes_vec);
return odes;
}
This function returns (when I supply some value of t, p and A) the following,
> Rcpp::sourceCpp('odes_gprotein.cpp')
> X <- odes_gprotein(0,IC,p)
> str(X)
List of 7
$ : num 9e+06
$ : num -9e+06
$ : num 0
$ : num 19993
$ : num -19993
$ : num -19993
$ : num -9e+06
Whereas, what I need is the X as mentioned above
> X
[[1]]
9000000.00 -9000000.00 0.00 19993.04 -19993.04 -19993.04 -9000000.00
where
str(X)
List of 1
$ : num [1:7] 9e+06 -9e+06 0e+00 2e+04 -2e+04 ...
Thank you for your suggestions!
We still do not really know what you want or tried, but here is a minimal existence proof for you:
R> cppFunction('List mylist(IntegerVector x) { return List(x); }')
R> mylist(c(2:4))
[[1]]
[1] 2
[[2]]
[1] 3
[[3]]
[1] 4
R>
In goes a vector, out comes a list. Have a look at the Rcpp examples and eg the Rcpp Gallery site.
Turns out I was creating the List in a wrong way, I had to remove the following
List odes(1); and List(odes_vec); and return (odes); and had to add the following statement at the end
return Rcpp::List::create(odes_vec);
A better explanation can be found here

How to implement a left matrix division on C++ using gsl

I am trying to port a MATLAB program to C++.
And I want to implement a left matrix division between a matrix A and a column vector B.
A is an m-by-n matrix with m is not equal to n and B is a column vector with m components.
And I want the result X = A\B is the solution in the least squares sense to the under- or overdetermined system of equations AX = B. In other words, X minimizes norm(A*X - B), the length of the vector AX - B.
That means I want it has the same result as the A\B in MATLAB.
I want to implement this feature in GSL-GNU (GNU Science Library) and I don't know too much about math, least square fitting or matrix operation, can somebody told me how to do this in GSL? Or if implement them in GSL is too complicate, can someone suggest me a good open source C/C++ library that provides the above matrix operation?
Okay, I finally figure out by my self after spend another 5 hours on it.. But still thanks for the suggestions to my question.
Assuming we have a 5 * 2 matrix
A = [1 0
1 0
0 1
1 1
1 1]
and a vector b = [1.8388,2.5595,0.0462,2.1410,0.6750]
The solution to the A \ b would be
#include <stdio.h>
#include <gsl/gsl_linalg.h>
int
main (void)
{
double a_data[] = {1.0, 0.0,1.0, 0.0, 0.0,1.0,1.0,1.0,1.0,1.0};
double b_data[] = {1.8388,2.5595,0.0462,2.1410,0.6750};
gsl_matrix_view m
= gsl_matrix_view_array (a_data, 5, 2);
gsl_vector_view b
= gsl_vector_view_array (b_data, 5);
gsl_vector *x = gsl_vector_alloc (2); // size equal to n
gsl_vector *residual = gsl_vector_alloc (5); // size equal to m
gsl_vector *tau = gsl_vector_alloc (2); //size equal to min(m,n)
gsl_linalg_QR_decomp (&m.matrix, tau); //
gsl_linalg_QR_lssolve(&m.matrix, tau, &b.vector, x, residual);
printf ("x = \n");
gsl_vector_fprintf (stdout, x, "%g");
gsl_vector_free (x);
gsl_vector_free (tau);
gsl_vector_free (residual);
return 0;
}
In addition to the one you gave, a quick search revealed other GSL examples, one using QR decomposition, the other LU decomposition.
There exist other numeric libraries capable of solving linear systems (a basic functionality in every linear algebra library). For one, Armadillo offers a nice and readable interface:
#include <iostream>
#include <armadillo>
using namespace std;
using namespace arma;
int main()
{
mat A = randu<mat>(5,2);
vec b = randu<vec>(5);
vec x = solve(A, b);
cout << x << endl;
return 0;
}
Another good one is the Eigen library:
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main()
{
Matrix3f A;
Vector3f b;
A << 1,2,3, 4,5,6, 7,8,10;
b << 3, 3, 4;
Vector3f x = A.colPivHouseholderQr().solve(b);
cout << "The solution is:\n" << x << endl;
return 0;
}
Now, one thing to remember is that MLDIVIDE is a super-charged function and has multiple execution paths. If the coefficient matrix A has some special structure, then it is exploited to obtain faster or more accurate result (can choose from substitution algorithm, LU and QR factorization, ..)
MATLAB also has PINV which returns the minimal norm least-squares solution, in addition to a number of other iterative methods for solving systems of linear equations.
I'm not sure I understand your question, but if you've already found your solution using MATLAB, you may want to consider using MATLAB Coder, which automatically translates your MATLAB code into C++.