Skip to content

Instantly share code, notes, and snippets.

@fenrir-naru
Last active September 17, 2020 00:00
Show Gist options
  • Save fenrir-naru/db8867fa7211e0e3e2f53398d1d71dea to your computer and use it in GitHub Desktop.
Save fenrir-naru/db8867fa7211e0e3e2f53398d1d71dea to your computer and use it in GitHub Desktop.
SWIG for boost::math::distributions
/**
* @file SWIG interface file for boost::math::distributions
*
*/
%module BoostDistributions
%include exception.i
%exception {
try {
$action
} catch (const std::exception& e) {
SWIG_exception(SWIG_RuntimeError, e.what());
}
}
%include std_pair.i
%{
#include <boost/math/distributions.hpp>
using namespace boost::math;
%}
%define ADD_BASIC_METHODS(dist_name)
%extend boost::math::dist_name {
RealType pdf(const RealType &x) const {
return pdf(*$self, x);
}
RealType cdf(const RealType &x, const bool &is_complement = false) const {
return is_complement ? cdf(complement(*$self, x)) : cdf(*$self, x);
}
RealType quantile(const RealType &p, const bool &is_complement = false) const {
return is_complement ? quantile(complement(*$self, p)) : quantile(*$self, p);
}
RealType mean() const {return mean(*$self);}
RealType median() const {return median(*$self);}
RealType mode() const {return mode(*$self);}
RealType standard_deviation() const {return standard_deviation(*$self);}
RealType variance() const {return variance(*$self);}
RealType skewness() const {return skewness(*$self);}
RealType kurtosis() const {return kurtosis(*$self);}
RealType kurtosis_excess() const {return kurtosis_excess(*$self);}
#if defined(SWIGRUBY)
%typemap(out) std::pair<RealType, RealType> {
VALUE arr(rb_ary_new2(2));
rb_ary_push(arr, DBL2NUM($1.first));
rb_ary_push(arr, DBL2NUM($1.second));
$result = arr;
}
#endif
std::pair<RealType, RealType> range() const {return range(*$self);}
std::pair<RealType, RealType> support() const {return support(*$self);}
};
%enddef
%define INSTANTIATE(dist_name, type, class_name)
%include /usr/include/boost/math/distributions/ ## dist_name ## .hpp
ADD_BASIC_METHODS(dist_name ## _distribution);
%template(class_name) boost::math:: ## dist_name ## _distribution<type, policies::policy<> >;
%enddef
%extend boost::math::cauchy_distribution {
%ignore mean;
%ignore standard_deviation;
%ignore variance;
%ignore skewness;
%ignore kurtosis;
%ignore kurtosis_excess;
};
%extend boost::math::non_central_beta_distribution {
%ignore skewness;
%ignore kurtosis;
%ignore kurtosis_excess;
};
// workaround for hyperexponential haaving RealT template parameter instead of RealType
%extend boost::math::hyperexponential_distribution {
%ignore hyperexponential_distribution(std::initializer_list<RealT>, std::initializer_list<RealT>);
%ignore hyperexponential_distribution(std::initializer_list<RealT>);
RealT pdf(const RealT &x) const {
return pdf(*$self, x);
}
RealT cdf(const RealT &x, const bool &is_complement = false) const {
return is_complement ? cdf(complement(*$self, x)) : cdf(*$self, x);
}
RealT quantile(const RealT &p, const bool &is_complement = false) const {
return is_complement ? quantile(complement(*$self, p)) : quantile(*$self, p);
}
RealT mean() const {return mean(*$self);}
RealT median() const {return median(*$self);}
RealT mode() const {return mode(*$self);}
RealT standard_deviation() const {return standard_deviation(*$self);}
RealT variance() const {return variance(*$self);}
RealT skewness() const {return skewness(*$self);}
RealT kurtosis() const {return kurtosis(*$self);}
RealT kurtosis_excess() const {return kurtosis_excess(*$self);}
#if defined(SWIGRUBY)
%typemap(out) std::pair<RealT, RealT> {
VALUE arr(rb_ary_new2(2));
rb_ary_push(arr, DBL2NUM($1.first));
rb_ary_push(arr, DBL2NUM($1.second));
$result = arr;
}
#endif
std::pair<RealT, RealT> range() const {return range(*$self);}
std::pair<RealT, RealT> support() const {return support(*$self);}
};
%include /usr/include/boost/math/distributions/hyperexponential.hpp
%template(Hyperexponential) boost::math::hyperexponential_distribution<double, policies::policy<> >;
INSTANTIATE(arcsine, double, Arcsine);
INSTANTIATE(bernoulli, double, Bernoulli);
INSTANTIATE(beta, double, Beta);
INSTANTIATE(binomial, double, Binomial);
INSTANTIATE(cauchy, double, Cauchy);
INSTANTIATE(chi_squared, double, ChiSquared);
INSTANTIATE(exponential, double, Exponential);
INSTANTIATE(extreme_value, double, ExtremeValue);
INSTANTIATE(fisher_f, double, FisherF);
INSTANTIATE(gamma, double, Gamma);
INSTANTIATE(geometric, double, Geometric);
//INSTANTIATE(hyperexponential, double, Hyperexponential); // TODO due to initializer list
INSTANTIATE(hypergeometric, double, Hypergeometric);
INSTANTIATE(inverse_chi_squared, double, InverseChiSquared);
INSTANTIATE(inverse_gamma, double, InverseGamma);
INSTANTIATE(inverse_gaussian, double, InverseGaussian);
INSTANTIATE(laplace, double, Laplace);
INSTANTIATE(logistic, double, Logistic);
INSTANTIATE(lognormal, double, Lognormal);
INSTANTIATE(negative_binomial, double, NegativeBinomial);
INSTANTIATE(non_central_beta, double, NonCentralBeta);
INSTANTIATE(non_central_chi_squared, double, NonCentralChiSquared);
INSTANTIATE(non_central_f, double, NonCentralF);
INSTANTIATE(non_central_t, double, NonCentralT);
INSTANTIATE(normal, double, Normal);
INSTANTIATE(pareto, double, Pareto);
INSTANTIATE(poisson, double, Poisson);
INSTANTIATE(rayleigh, double, Rayleigh);
INSTANTIATE(skew_normal, double, SkewNormal);
INSTANTIATE(students_t, double, StudentsT);
INSTANTIATE(triangular, double, Triangular);
INSTANTIATE(uniform, double, Uniform);
INSTANTIATE(weibull, double, Weibull);
require "mkmf"
cflags = " -Wall -I../../.."
$CFLAGS += cflags
$CPPFLAGS += cflags if RUBY_VERSION >= "2.0.0"
$LOCAL_LIBS += " -lstdc++ "
SWIG = swig
SWIGFLAGS = -c++ -ruby
INCLUDES =
BUILD_DIR = build_SWIG
RUBY = ruby
RUBY_CONF = extconf.rb
SRCS = $(shell ls *.i)
PACKAGES = $(SRCS:.i=.so)
all : $(BUILD_DIR) depend $(PACKAGES)
depend: $(SRCS)
if [ -f $(BUILD_DIR)/depend.inc ]; then rm -f $(BUILD_DIR)/depend.inc; fi
for i in $^; do\
$(SWIG) $(SWIGFLAGS) $(INCLUDES) -MM -MP $$i | sed -e 's/[^\.]*\.cxx/$$\(BUILD_DIR\)\/&/g' >> $(BUILD_DIR)/depend.inc;\
done
-include $(BUILD_DIR)/depend.inc
$(PACKAGES) : $(patsubst %,$(BUILD_DIR)/%,$(PACKAGES))
$(BUILD_DIR)/%_wrap.cxx : %.i
$(SWIG) $(SWIGFLAGS) $(INCLUDES) -o $@ $<
$(BUILD_DIR)/%.so : PACKAGE = $(shell echo $@ | sed -e 's/^$(BUILD_DIR)\/\([^\.]*\)\.so/\1/g')
$(BUILD_DIR)/%.so : $(BUILD_DIR)/%_wrap.cxx $(RUBY_CONF)
echo "building $(PACKAGE) ..."
if ! [ -d $(BUILD_DIR)/$(PACKAGE) ]; then mkdir $(BUILD_DIR)/$(PACKAGE); fi
cp $(RUBY_CONF) $(BUILD_DIR)/$(PACKAGE)/
cp $(BUILD_DIR)/$(PACKAGE)_wrap.cxx $(BUILD_DIR)/$(PACKAGE)/
cd $(BUILD_DIR)/$(PACKAGE); \
echo 'create_makefile("$(PACKAGE)")' >> $(RUBY_CONF); \
$(RUBY) $(RUBY_CONF); \
make; \
cp *.so ../
$(BUILD_DIR) :
mkdir $@
clean :
rm -rf $(BUILD_DIR)/*
run : all
.PHONY : clean all depend
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment