Calculating Inverse_chi_squared_distribution using boost - c++

I'm trying to implement a function to calculate inverse_chi_squared_distribution, boost has a container named inverse_chi_squared_distribution, however, when I try to create an instance of the class I get this error too few template arguments for class template 'inverse_chi_squared_distribution'.
I'm on wsl:ubuntu-18.04 and other boost functions/containers work fine.
Here's the code generating the error:
boost::math::inverse_chi_squared_distribution<double> invChi(degValue);
Not exactly sure how to calculate it even if this instance is created (was gonna just hit and miss till I get it) so help using this to calculate the function would be much appreciated, thanks.

OK, do you want the inverse of a chi-squared distribution (ie its quantile) or do you want the "inverse chi squared distribution" which is a distribution in it's own right, also with an inverse/quantile!
If the former, then assuming v degrees of freedom, and probability p then this would do it:
#include <boost/math/distributions/chi_squared.hpp>
double chi_squared_quantile(double v, double p)
{
return quantile(boost::math::chi_squared(v), p);
}
If the latter, then example usages might be:
#include <boost/math/distributions/inverse_chi_squared.hpp>
double inverse_chi_squared_quantile(double v, double p)
{
return quantile(boost::math::inverse_chi_squared(v), p);
}
double inverse_chi_squared_pdf(double v, double x)
{
return pdf(boost::math::inverse_chi_squared(v), x);
}
double inverse_chi_squared_cdf(double v, double x)
{
return cdf(boost::math::inverse_chi_squared(v), x);
}
There are other options - you can calculate with types other than double then you would use boost::math::inverse_chi_squared_distribution<MyType> in place of the convenience typedef inverse_chi_squared.

Related

Using Boost bisection when the function relies on a class attribute and has additional arguments

I am trying to use the Boost bisection method described here.
I have seen a couple of examples of how to get this to work, e.g. How to use boost bisection?, but I don't understand how to apply these to my particular set-up.
Here is a sketch of some code that illustrates what I am trying to do.
class Model {
double b;
double root;
public:
double func(double x, double c);
void solve(void);
};
double Model::func(double x, double c) {
return (x*x*x + (b*x) + c);
}
void Model::solve(void) {
double c;
b = 2.;
c = 1.;
// root = bisect(func(), from, to, ...);
// where the first argument to func() is what we want to find the root over
// and the second argument to func() is c
}
int main(void) {
Model model;
model.solve();
}
The member function solve() needs to find the root of the member function func(). func() has two important features:
It relies on the class attribute b
It has a second argument c that is determined in solve(). I want to hold this second argument fixed when finding the root
How would I implement the Boost bisection method in this context? This answer seems to suggest that boost::bind might solve part of the problem but I don't understand enough of it to know how to apply it to my problem.

Pass a function of n arguments as function of n-x arguments

This is a very basic question and I'm sure this was answered before, but I don't know what to search for.
Stated I have a function that integrates a mathematical function:
double integrator(double (*func_to_integrate)(double,double));
But my function to integrate is of a type that allows me to manipulate more than two parameters, for example:
double func_to_integrate(double mu, double w0, double x, double y);
So that I can loop over different values of mu and w0 and compare the results of integration.
How can I pass a function like func_to_integrate to integrator?
Greetings
Edit: As alain pointed out in the comments this is partly a duplicate of: How can currying be done in C++?
Is there an elegant solution doing a currying operation on a function pointer?
Given you are able to change the signature of the integrator function, there are several solutions. The basic two directions are
use a general template parameter instead of the function pointer (--where the caller has to be aware of the correct signature to pass), or
use std::function<double(double, double)> as the function argument.
Both alternatives allow you to pass general function objects (functors, lambdas, a std::bind-object, etc.). I'd go with alternative 1. as it usually gives a better performance.
Then you can easily set up a lambda:
double mu = 1.0;
double w0 = 1.0;
auto f = [mu, w0] (double x, double y) { return func_to_integrate(mu, w0, x, y); };
and pass f to your (adusted) integrator routine.
Here is further an alternative if you cannot change the function signature -- as it is often the case for third-party libraries.
I first thought there is no solution in this case, as you can't bind a general functor to a function pointer. But then I encountered the nice idea in this answer (which I slightly adjusted): encode everything in terms of a static std::function variable, then use a static function to call this std::function object. As the static function is just syntactic sugar for a global function, it is possible to set up a function pointer to it:
template <typename Res, typename... Args>
struct function_ptr_helper
{
public:
template<typename function_type>
static auto bind(function_type&& f) { func = std::forward<function_type>(f); }
static auto invoke(Args... args) { return func(args...); }
static auto* ptr() { return &invoke; }
private:
static std::function<Res(Args ...)> func;
};
template <typename Res, typename... Args>
std::function<Res(Args ...)> function_ptr_helper<Res, Args...>::func;
template <typename Res, typename ... Args>
auto* get_function_ptr(std::function<Res(Args...)> f)
{
using type = function_ptr_helper<Res, Args...>;
type::bind(std::move(f));
return type::ptr();
}
DEMO
You can use it as
double mu = 1.0;
double w0 = 1.0;
std::function<double(double, double)> f
= [mu, w0] (double x, double y) { return func_to_integrate(mu, w0, x, y); };
integrator(get_function_ptr(f));
Be aware, however, that you are dealing with global variables here. This often works, but sometimes might lead to subtle errors (for example when you call get_function_ptr more than once in a single expression).
How can I pass a function like func_to_integrate to integrator?
Seems very easy to fix. Just add two more arguments to your pointer function signature.
double integrator(double (*func_to_integrate)(double,double,double,double));
As previous comments point out the most elegant solution would be using bind and or lambda. A nice solution would be an adapter design pattern class wrapper, where mu and w0 become class members.
class IntegratorAdaptor {
private:
double _mu, double _w0;
public:
IntegratorAdapter(double arg_mu, double arg_w0)
: _mu(arg_mu), _w0(arg_w0) { }
double twoArgIntegrator( double x, double y )
{ return func_to_intergrate( _mu, _w0, x, y ); }
};
Construction of this class is very low overhead, so I made the members immutable. I didn't come up with very good names for the class and functions, you should put more thought into those names than I did.
Most answers I've seen for this kind of question rely on std::function and/or C++ templates. I wanted to share an alternate solution which may be less general, but to me is simpler. It doesn't use std::function or templates---in fact, it doesn't use any libraries at all.
The idea is that instead of passing around a function pointer, you pass around an object that implements a particular 'interface'. In this example,
double integrator(double (*func_to_integrate)(double,double))
becomes
double integrator(Integratable func_to_integrate)
where Integratable is an 'interface' (abstract base class) defined as
class Integratable {
public:
virtual double compute(double x, double y) = 0; // pure virtual function
}
We can then make func_to_integrate into an instance of this class, with extra members for the additional parameters:
class SomeClassName : public Integratable {
public:
double compute(double x, double y);
double mu;
double w0;
}
SomeClassName func_to_integrate;
To test several values of mu and w0 in a loop:
for(double mu : mus) {
for(double w0 : w0s) {
func_to_integrate.mu = mu;
func_to_integrate.w0 = w0;
integrator(func_to_integrate);
}
}
Of course, we have to modify integrator so that instead of calling a function pointer, it calls the compute() method on the object passed to it, but this is trivial (assuming you can change the signature of integrator, which is probably required for any possible solution to this problem).
I like this solution because it avoids some of C++'s more heavyweight features and libraries. However, it certainly is less general than many of the other solutions that are often suggested for partial application in C++. For OP I believe this solution is an elegant fit for the given use case.

How to use boost::geometry::distance with opencv cv::Point?

typedef boost::geometry::model::d2::point_xy<double> boostPoint;
How to use boost::geometry::distance with opencv cv::Point without convertion to boostPoint?
double EuclideanDistance(const cv::Point2d &pt1, const cv::Point2d &pt2)
{
boostPoint boostPt1(pt1.x, pt1.y);
boostPoint boostPt2(pt2.x, pt2.y);
double distance= boost::geometry::distance(boostPt1, boostPt2);
return distance;
}
Update:
I tried this code, but it complaines to x error: ‘x’ has not been declared
BOOST_GEOMETRY_REGISTER_POINT_2D(cv::Point2d, double, boost::geometry::cs::cartesian, x, y)
Make sure you include the necessary header as indicated by the doc:
#include <boost/geometry/geometries/register/point.hpp>
If you want to make the code more elegant, just use the proper way. Boost is not a advantage if you added to your code. Since your points are OpenCV points, compute the distance using OpenCV like this:
double EuclideanDistance(const cv::Point2d &pt1, const cv::Point2d &pt2)
{
return cv::norm(pt1-pt2,cv::NORM_L2);
}
EDIT:
Since the OP need to do it in this way, I may suggest this solution: Create your own Point Class let us call it MyPoint. In MyPoint define copy constructors and conversation from and to cv::Point, boostPoint. In your code just use YourPoint everywhere. If you need help in implementing this just comment.

Functions with many parameters - making them as structs

I'm writing an API for internal needs and so ease of use is one of the top priorities. I wonder if I'm pushing it too far as in the following example.
The function to solve the inverse geodetic problem takes in geocoordinates of two points and calculates distance between them and asimuths (angles) from each of the points to the other.
Ease-of-use-optimised conventional solution might look something like (please don't mind the length of the names, I know there's room for improvement):
class Angle;
class GeoCoordinate;
...
struct InverseGeodeticOut
{
Angle forwardAzimuth;
Angle backAzimuth;
double distance;
};
InverseGeodeticOut inverseGeodetic(const GeoCoordinate &firstPoint,
const GeoCoordinate &secondPoint);
// or
void inverseGeodetic(const GeoCoordinate &firstPoint,
const GeoCoordinate &secondPoint,
InverseGeodeticOut *result);
My question is how reasonable would it be to take it one step further to save user some typing:
class Angle;
class GeoCoordinate;
...
struct InverseGeodetic
{
InverseGeodetic();
InverseGeodetic(const GeoCoordinate &firstPoint,
const GeoCoordinate &secondPoint);
Angle forwardAzimuth;
Angle backAzimuth;
double distance;
};
// so the usages would be
InverseGeodeticOut inverse = inverseGeodetic(firstPoint, secondPoint);
InverseGeodeticOut inverse;
inverseGeodetic(firstPoint, secondPoint, &inverse);
InverseGeodetic inverse(firstPoint, secondPoint);
Perhaps in this particular example the difference is too small to be worth talking about but I wonder if such constructs are okay in general.
I like your 2nd code example, though I find the public constructor a bit confusing. Especially if there are other ways to construct an InverseGeodetic. I'd rather use a static factory method to construct it. That way you can give a more meaningful name to the method:
struct InverseGeodetic
{
Angle forwardAzimuth;
Angle backAzimuth;
double distance;
static InverseGeodetic FromTwoPoints(const GeoCoordinate &, const GeoCoordinate &);
};
// usage
auto inverse = InverseGeodetic::FromTwoPoints(a, b);
But then that might be my C# background bleeding through.

Error while creating object from templated class

I've been trying to find a way to sample random vectors from a multivariate normal distribution in C++, having both the mean vector and the covariance matrix, much like Matlab's mvnrnd function works. I've found relevant code for a class that implements this on this page, but I've been having some problems compiling it. I've created a header file that is being included on my main.cpp, and I'm trying to create an object of the EigenMultivariateNormal class:
MatrixXd MN(10,1);
MatrixXd CVM(10,10);
EigenMultivariateNormal <double,int> (&MN,&CVM) mvn;
The problem is I get a template-related error when compiling:
error: type/value mismatch at argument 2 in template parameter list for ‘template<class _Scalar, int _size> class EigenMultivariateNormal’
error: expected a constant of type ‘int’, got ‘int’
error: expected ‘;’ before ‘mvn’
I only have a superficial idea on how to work with templates, and I am by no means a cpp expert, so I was wondering what exactly am I doing wrong? Apparently I should have a const somewhere on my code.
That code's a bit old. Here's a newer, possibly improved version. There are probably still some bad things. For example, I think it should be changed to use the MatrixBase instead of an actual Matrix. That might let it optimize and better decide when it needs to allocate storage space or not. This also uses the namespace internal which is probably frowned on, but it seems necessary to make use of Eigen's NullaryExpr which seems like the right thing to do. There's usage of the dreaded mutable keyword. That's necessary because of what Eigen thinks should be const when used in a NullaryExpr.
It's also a little annoying to rely on boost. It seems that in C++11 the necessary functions have become standard. Below the class code, there's a short usage sample.
The class eigenmultivariatenormal.hpp
#ifndef __EIGENMULTIVARIATENORMAL_HPP
#define __EIGENMULTIVARIATENORMAL_HPP
#include <Eigen/Dense>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/normal_distribution.hpp>
/*
We need a functor that can pretend it's const,
but to be a good random number generator
it needs mutable state. The standard Eigen function
Random() just calls rand(), which changes a global
variable.
*/
namespace Eigen {
namespace internal {
template<typename Scalar>
struct scalar_normal_dist_op
{
static boost::mt19937 rng; // The uniform pseudo-random algorithm
mutable boost::normal_distribution<Scalar> norm; // The gaussian combinator
EIGEN_EMPTY_STRUCT_CTOR(scalar_normal_dist_op)
template<typename Index>
inline const Scalar operator() (Index, Index = 0) const { return norm(rng); }
};
template<typename Scalar>
boost::mt19937 scalar_normal_dist_op<Scalar>::rng;
template<typename Scalar>
struct functor_traits<scalar_normal_dist_op<Scalar> >
{ enum { Cost = 50 * NumTraits<Scalar>::MulCost, PacketAccess = false, IsRepeatable = false }; };
} // end namespace internal
/**
Find the eigen-decomposition of the covariance matrix
and then store it for sampling from a multi-variate normal
*/
template<typename Scalar, int Size>
class EigenMultivariateNormal
{
Matrix<Scalar,Size,Size> _covar;
Matrix<Scalar,Size,Size> _transform;
Matrix< Scalar, Size, 1> _mean;
internal::scalar_normal_dist_op<Scalar> randN; // Gaussian functor
public:
EigenMultivariateNormal(const Matrix<Scalar,Size,1>& mean,const Matrix<Scalar,Size,Size>& covar)
{
setMean(mean);
setCovar(covar);
}
void setMean(const Matrix<Scalar,Size,1>& mean) { _mean = mean; }
void setCovar(const Matrix<Scalar,Size,Size>& covar)
{
_covar = covar;
// Assuming that we'll be using this repeatedly,
// compute the transformation matrix that will
// be applied to unit-variance independent normals
/*
Eigen::LDLT<Eigen::Matrix<Scalar,Size,Size> > cholSolver(_covar);
// We can only use the cholesky decomposition if
// the covariance matrix is symmetric, pos-definite.
// But a covariance matrix might be pos-semi-definite.
// In that case, we'll go to an EigenSolver
if (cholSolver.info()==Eigen::Success) {
// Use cholesky solver
_transform = cholSolver.matrixL();
} else {*/
SelfAdjointEigenSolver<Matrix<Scalar,Size,Size> > eigenSolver(_covar);
_transform = eigenSolver.eigenvectors()*eigenSolver.eigenvalues().cwiseMax(0).cwiseSqrt().asDiagonal();
/*}*/
}
/// Draw nn samples from the gaussian and return them
/// as columns in a Size by nn matrix
Matrix<Scalar,Size,-1> samples(int nn)
{
return (_transform * Matrix<Scalar,Size,-1>::NullaryExpr(Size,nn,randN)).colwise() + _mean;
}
}; // end class EigenMultivariateNormal
} // end namespace Eigen
#endif
Here's a simple program that uses it:
#include <fstream>
#include "eigenmultivariatenormal.hpp"
#ifndef M_PI
#define M_PI REAL(3.1415926535897932384626433832795029)
#endif
/**
Take a pair of un-correlated variances.
Create a covariance matrix by correlating
them, sandwiching them in a rotation matrix.
*/
Eigen::Matrix2d genCovar(double v0,double v1,double theta)
{
Eigen::Matrix2d rot = Eigen::Rotation2Dd(theta).matrix();
return rot*Eigen::DiagonalMatrix<double,2,2>(v0,v1)*rot.transpose();
}
void main()
{
Eigen::Vector2d mean;
Eigen::Matrix2d covar;
mean << -1,0.5; // Set the mean
// Create a covariance matrix
// Much wider than it is tall
// and rotated clockwise by a bit
covar = genCovar(3,0.1,M_PI/5.0);
// Create a bivariate gaussian distribution of doubles.
// with our chosen mean and covariance
Eigen::EigenMultivariateNormal<double,2> normX(mean,covar);
std::ofstream file("samples.txt");
// Generate some samples and write them out to file
// for plotting
file << normX.samples(1000).transpose() << std::endl;
}
And here's a plot showing the results.
Using the SelfAdjointEigenSolver is probably a lot slower than a Cholesky decomposition, but it is stable, even if the covariance matrix is singular. If you know that your covariance matrices will always be full, then you could use that instead. However, if you create the distribution rarely and sample from it often, then that's probably not a big deal.
template<class _Scalar, int _size> class EigenMultivariateNormal is specialized template class. The first class _Scalar ask for a type but int _size ask for an int.
You should call it with a constant int instead of the type int as you did.
Secondly, your syntax to instance a new class EigenMultivariateNormal is wrong.
Try this instead:
EigenMultivariateNormal<double, 10> mvn (&MN, &CVM); // with 10 is the size