viltrum

VILTRUM: Varied Integration Layouts for arbiTRary integrals in a Unified Manner - A C++17 header-only library that provides a set of numerical integration routines

https://github.com/adolfomunoz/viltrum

Science Score: 57.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
    Found 3 DOI reference(s) in README
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (16.3%) to scientific vocabulary

Keywords

adaptive-quadrature control-variates numerical-integration piecewise-polynomial rendering
Last synced: 6 months ago · JSON representation ·

Repository

VILTRUM: Varied Integration Layouts for arbiTRary integrals in a Unified Manner - A C++17 header-only library that provides a set of numerical integration routines

Basic Info
Statistics
  • Stars: 16
  • Watchers: 1
  • Forks: 4
  • Open Issues: 0
  • Releases: 0
Topics
adaptive-quadrature control-variates numerical-integration piecewise-polynomial rendering
Created almost 5 years ago · Last pushed about 1 year ago
Metadata Files
Readme License Citation

README.md

viltrum

VILTRUM: Varied Integration Layouts for arbiTRary integrals in a Unified Manner - A C++17 header-only library that provides a set of numerical integration routines. This library was generated during research for our paper:

Primary-Space Adaptive Control Variates using Piecewise-Polynomial Approximations

Logo

ACM Transactions on Graphics - 2021
Miguel Crespo · Adrian Jarabo · Adolfo Muñoz

Paper PDF Project Page

Installation

viltrum is a header-only library and has no external dependencies, so installation is rather simple (it does not require any compilation process). You just need to download the library in a specific folder:

folder> git clone https://github.com/adolfomunoz/viltrum.git

Then make sure folder is within the included directories (-Ifolder parameter in g++, include_directories("folder") in CMake) and include it from C++.

```cpp

include

```

That would be enough to use all the features of the library. There are other alternatives that might be more comfortable for you, see them here. There is a CMake-based building system for several example and test executable files that automatically downloads external dependencies and compiles all executables but it is not needed for the libray's usage.

Usage

Integrating a function in a specific n-dimensional range is rather simple. You need the following information: - An integrator, a numerical integration method, for which there are several to choose from. - An integrand, a function to be integrated. It's only parameter has to be a std::array<F,N>, where F is a floating point number and N is the number of dimensions. There are several ways in which such integrand can be defined. The integrand can return any numeric value, or, in general, any data type that supports addition and multiplication by a scalar (tested with Eigen arrays ). - A range, the integration domain, that is composed on two std::array<F,N> marking the limits of the potentially multidimensional integration domain, which can be defined in different ways.

Example:

cpp float sphere(const std::array<float,3>& x) { return (x[0]*x[0]+x[1]*x[1]+x[2]*x[2])<=1.0f?1.0f:0.0f; } int main() { unsigned long samples = 1024; auto method = viltrum::integrator_monte_carlo_uniform(samples); auto range = viltrum::range(std::array<float,3>{-1.0f,-1.0f,-1.0f},std::array<float,3>{1.0f,1.0f,1.0f}); std::cout<<"Sphere volume = "<<method.integrate(sphere,range)<<"\n"; }

The return type of the integrate method will be the same return type of the integrand (float in the example above).

Integrating into bins

It is also possible to obtain not only a single integral value, but to obtain integrals in a regular n-dimensional grid of cells or bins. For this purpose, this library provides bin integrators, that is, integrators that are capable of integrating into bins. For using them, in addition to the integrand and range you need: - A bin accesor, that is, a function that given an n-dimensional array (where n is the dimensionality of the bin regular structure) of positions (of type std::size_t) gives read and write access to the binning structure in that specific position. - A resolution, a n-dimensional array of std::size_t that gives the resolution of the bin structure for each dimension n.

Given these common structure:Bin integrators can be used as follows:

```cpp float slope(const std::array& x) { return (x[1]<x[0])?1.0f:0.0f; }

int main(int argc, char **argv) { auto integratorbins = viltrum::integratorbinsmontecarlouniform(1024); auto range = viltrum::range(std::array{0,0},std::array{1,1}); float outputarray[16]; //... } ```

bin integrators can be used as follows (1D example):

cpp auto output_array_access = [&output_array] (const std::array<std::size_t,1>& i) -> float& { return output_array[i[0]]; }; integrator_bins.integrate(output_array_access,std::array<std::size_t,1>{16},slope,range); for (float f : output_array) std::cout<<f<<" "; std::cout<<std::endl;

and can be expanded to two dimensions as follows:

cpp auto output_array_access_2d = [&output_array] (const std::array<std::size_t,2>& i) -> float& { return output_array[4*i[0]+i[1]]; }; integrator_bins.integrate(output_array_access_2d,std::array<std::size_t,2>{4,4},slope,range);

Additionally, the viltrum library offers a functional version of the same method: cpp integrate_bins(integrator_bins,output_array_access,std::array<std::size_t,1>{16},slope,range); integrate_bins(integrator_bins,output_array_access_2d,std::array<std::size_t,2>{4,4},slope,range);

This functional version is able to deduce the bin accesor as well as the resolution for std::vector data types, in which there is only one parameter defining the binning structure: ```cpp std::vector outputvector(16); integratebins(integratorbins, outputvector, slope, range); for (float f : output_vector) std::cout<<f<<" "; std::cout<<std::endl;

std::vector<std::vector<float>> output_matrix(4,std::vector<float>(4));
integrate_bins(integrator_bins, output_matrix, slope, range);
std::cout<<std::endl;
for (const std::vector<float>& row : output_matrix) {
    for (float f : row) std::cout<<f<<" ";
    std::cout<<std::endl;
}
std::cout<<std::endl;

```

If you want to define your own automatic bin accesors you can take inspiration from our source code for the case of vectors but we do not provide documentation for that (you can always use the general version by explicitly indicating bin accesor and resolution independently as illustrated above).

Last, there are several bin integrators to choose from. However, if you want to use exactly the same integrator with the default parameters than we use in our paper define the bin integrator as follows:

cpp unsigned long spp_cv = std::max(1UL,(unsigned long)(spp*(1.0/16.0))); auto integrator = integrator_optimized_perpixel_adaptive_stratified_control_variates( viltrum::nested(viltrum::simpson,viltrum::trapezoidal), // nested rule, order 2 polynomials viltrum::error_single_dimension_size(1.e-5), // error heuristic spp_cv*bins/(2*std::pow(3, dim-1)), // number of adaptive iterations calculated from the spps std::max(1UL,spp-spp_cv) // number of spps for the residual ); where: - spp is the number of samples per pixel. - dim is the number of dimensions to be explored. - bins is the total number of bins (pixels in the case of images) in all dimensions.

License

This code is released under the GPL v3. Additionally, if you are using this code in academic research, we would be grateful if you cited our paper, for which we generated with this source code:

bibtex @article{crespo21primary, title = {Primary-Space Adaptive Control Variates using Piecewise-Polynomial Approximations.}, year = {2021}, journal = {ACM Transactions on Graphics}, author = {Crespo, Miguel and Jarabo, Adrian and Mu\~{n}oz, Adolfo}, volume = {40}, number = {3}, issn = {0730-0301}, url = {https://doi.org/10.1145/3450627}, doi = {10.1145/3450627}, issue_date = {July 2021}, month = jul, articleno = {25}, numpages = {15}, keywords = {adaptive quadrature, numerical integration, control variates, rendering, piecewise polynomial} }

Owner

  • Name: Adolfo Muñoz
  • Login: adolfomunoz
  • Kind: user

Citation (CITATION.cff)

title: Primary-space Adaptive Control Variates Using Piecewise-polynomial Approximations
abstract: This repository contains the source code of the integration library generated for the paper Primary-space Adaptive Control Variates Using Piecewise-polynomial Approximations by Miguel Crespo, Adrian Jarabo and Adolfo Muñoz, from ACM Trans. Graph.
doi: 10.1145/3450627
repository-code: https://github.com/adolfomunoz/viltrum
version: 1.0.0
date-released: 2021-07-14
message: If you use this software in your work, please cite it using the following metadata.
authors:
  - given-names: Miguel
    family-names: Crespo
    affiliation: Universidad de Zaragoza-I3A, Maria de Luna, Zaragoza (Spain)
  - given-names: Adrian
    family-names: Jarabo
    affiliation: Universidad de Zaragoza-I3A, and Centro Universitario de la Defensa Zaragoza, Maria de Luna, Zaragoza (Spain)
  - given-names: Adolfo
    family-names: Muñoz
    affiliation: Universidad de Zaragoza-I3A, Maria de Luna, Zaragoza (Spain)
cff-version: 1.2.0

GitHub Events

Total
  • Watch event: 4
  • Push event: 13
Last Year
  • Watch event: 4
  • Push event: 13