Skip to content

Integration Test

Description

Performs integration test on a pointset. The choice of integrand is crucial, and should be carefully choosen. UTK provides some basic test but one may design its own test.

Examples may be found in : - include/utk/metrics/Integrands/Heaviside.hpp, src/metrics/BuildHeavisideDatabase.cpp, src/metrics/HeavisideIntegrationTest.hpp - include/utk/metrics/Integrands/Gaussians.hpp, src/metrics/BuildGaussiansDatabase.cpp, src/metrics/GaussiansIntegrationTest.hpp - include/utk/metrics/Integrands/ClippedGaussianMixture.hpp, src/metrics/BuildClippedGaussianMixtureDatabase.cpp, src/metrics/ClippedGaussianMixtureIntegrationTest.hpp

Performing Integration Test

IntegrationTests have two main steps : creating a database and performing the test. First, a database of integrant is built. This is a caching mecanism allowing for reusing same integrands with their integral already computated (this can be heavy if there is no close form and it should be approximated using MC methods with high sample count). Second, the database is read and the test is performed as usual.

For each pointset tested against, an ‘ErrorReport’ is returned containing the following information :

  • min : minimum error among all integrands in database
  • max : maximum error among all integrands in database
  • mean : average error among all integrands in database
  • var : variance of error among all integrands in database

Creating Integrands

Integrands must derive from utk::Integrand and must implements the folowing methods :

  • Constructor: Takes as parameter the dimension.
  • GenerateRandom: The method takes a map of string to int, double or string and a seed. First argument is here to guide generation (for exemple “scaling” of a function). The second is for reproducibility.
  • ReadFromStream: Reads parameters defining a function.
  • WriteToStream: Writes parameters defining a function.
  • Eval: Evaluate the function at a given point.

Additionnal method may also be derived controlling the computation of ground truth:

  • hasCloseForm: Defaults return false.
  • getIntegral: Will only be used if hasCloseForm() == true.

When hasCloseForm() == false, the ground truth will be computed using QMC samples (likely from Sobol’ + Owen).

UTK’s integrand

  • Heaviside : The unit cube is clipped by an hyperplane
  • Gaussian: Gaussian density on the unit cube. The position is random in the hypercube, and the orientation is sampled uniformly in the space of rotations.
  • BlinnPhong: Rendering-based test. The scene is a simple rectangle that reflects light with the BlinnPhong model. The light source is randomly sampled while the rectangle isn’t.
  • ClippedGaussianMixture : Multiple boxes are sampled in the unit square. A gaussian density is put inside each of the boxes. The integrand is 0 outside the boxes. If a point belong to multiple boxes, the sum of each corresponding gaussian is performed.

Files

include/utk/metrics/IntegrationTest.hpp

include/utk/metrics/Integrands/Heaviside.hpp
src/metrics/BuildHeavisideDatabase.cpp
src/metrics/HeavisideIntegrationTest.hpp 

include/utk/metrics/Integrands/Gaussians.hpp
src/metrics/BuildGaussiansDatabase.cpp
src/metrics/GaussiansIntegrationTest.hpp

include/utk/metrics/Integrands/BlinnPhong.hpp
src/metrics/BuildBlinnPhongDatabase.cpp
src/metrics/BlinnPhongIntegrationTest.hpp


include/utk/metrics/Integrands/ClippedGaussianMixture.hpp
src/metrics/BuildClippedGaussianMixtureDatabase.cpp
src/metrics/ClippedGaussianMixtureIntegrationTest.hpp

Usage (For gaussians)


Integrand database builder
Usage: ./Integration/BuildGaussianIntegrandDatabase [OPTIONS]

Options:
  -h,--help                   Print this help message and exit
  -o,--output TEXT REQUIRED   Output file
  -d,--dimension UINT REQUIRED
                              Dimension
  -n,--npts UINT REQUIRED     Number of points for integral computation.
  -m UINT REQUIRED            Number of integrands to compute
  -s UINT [0]                 Seed (0 means random)
  --sigmamin FLOAT [0.01]     Min value for variance
  --sigmamax FLOAT [1]        Max value for variance
  --silent                    Silence UTK logs

Gaussian Integration calculator
Usage: ./Integration/GaussianIntegrationTest [OPTIONS]

Options:
  -h,--help                   Print this help message and exit
  -i,--input TEXT:FILE ... REQUIRED
                              Input file(s)
  -o,--output TEXT            Output file (empty is stdout)
  -f,--file,--integrands TEXT REQUIRED
                              Integrand File
  --silent                    Silence UTK logs
#include <utk/utils/PointsetIO.hpp>
#include <utk/utils/Pointset.hpp>
#include <utk/samplers/SamplerWhitenoise.hpp>
#include <utk/samplers/SamplerSobol.hpp>

#include <utk/metrics/IntegrationTest.hpp>
#include <utk/metrics/Integrands/GaussianIntegrands.hpp>


int main()
{
    utk::Pointset<double> ptsGT;
    utk::Pointset<double> ptsWN;

    utk::SamplerSobol sobol(2);
    sobol.generateSamples(ptsGT, 16384); // For integration 

    utk::SamplerWhitenoise wn(2);
    wn.generateSamples(ptsWN, 1024);

    utk::IntegrationTest test;

    // Build database
    test.BuildDatabase<utk::GaussianIntegrand>(
      "gaussians.db", // Output file
      2,              // Dimension 
      128,            // Number of integrands  
      0,              // seed   
      {{"smin", 0.01}, {"smax", 1.0}}, // Parameters (variance min and max)
      ptsGT           // Points to compute ground truth
    );

    // (Note: if build is first called, read is not necessary, but it may require heavy computation)
    // Perform test
    // Reads the Database
    test.ReadDatabase<utk::GaussianIntegrand>(
      "gaussians.db", // File to read
      2               // Dimension
    );

    // Compute the statistics
    auto report = test.compute(ptsWN);
    ostream << report.min << " " << report.mean << " " << report.var << " " << report.max << '\n';
}
import pyutk 
import numpy as np

ptsGT = pyutk.Sobol(d=2, depth=32).sample(16384)

test = pyutk.IntegrationTest()

test.BuildGaussianDatabase(
  "gaussians.db",              # Output file
  2,                           # Dimension
  128,                         # Number of Integrands
  0,                           # Seed
  {"smin": 0.01, "smax": 1.0}, # Parameters (variance min and max)
  ptsGT                        # POints to compute ground truth
)

# Perform test :
test.ReadGaussianDatabse(
  "gaussians.db", # File to read
  2               # Dimension
)

report = test.compute(np.random.uniform(0, 1, (1024, 2)))
print(f"{report.min}, {report.mean}, {report.var}, {report.max}")

License

BSD