LatNet Builder Manual  2.0.1-11
Software Package for Constructing Highly Uniform Point Sets
Net Construction Types and Definitions

In NetBuilder, digital nets are represented by the abstract class DigitalNet.

This class is basically a wrapper around a vector of pointers to generating matrices.

DigitalNet is an abstract class which is implemented by the DigitalNetConstruction class template. This derived class corresponds to the various constructions of generating matrices which are available in NetBuilder. The template parameter is a non-type template parameter whose value belongs to the NetConstruction enumeration. To each value of this enumeration corresponds a trait class containing the implementation which is used to construct and extend digital nets. These implementations can be found in the NetConstructionTraits class.

Sobol' construction

In the case of the Sobol' construction, we have the following types:

typedef typename NetConstructionTraits<NetConstruction::SOBOL>::GenValue GeneratingValue;
typedef typename NetConstructionTraits<NetConstruction::SOBOL>::SizeParameter SizeParameter;

The first typedef corresponds to the type of the generating values. A generating value is the base from which a construction method such as the Sobol' construction produces a generating matrix. In the case of the Sobol' construction, it consists in a pair made of an integer and a vector of integers. The first integer is the coordinate (starting from 0) and stands for the primitive polynomial used to compute the matrix. The vector of integers is the vector of direction numbers.

The second typedef corresponds to the type of the size parameter. For Sobol' net, matrices are always square matrices and this parameter is an integer corresponding to the size of the generating matrices.

Now we show how to construct a Sobol' net in dimension 1 with \(2^{10}\) points. For this purpose, we first construct a generating value for the first coordinate. As a special case, the direction number for the first coordinate is always equal to 0. Then we construct the net (through std::make_unique), specifying the dimension, the size parameter and the vector of generating values (of size 1 in this case).

GeneratingValue firstGenValue(0, {0});
std::vector<GeneratingValue> genVals{firstGenValue};
auto sobolNet = std::make_unique<DigitalNetConstruction<NetConstruction::SOBOL>>(1, SizeParameter(10), genVals);
std::cout << "First generating matrix:" << std::endl << sobolNet->generatingMatrix(0) << std::endl;

We can now construct a new Sobol' net from this first net by adding a new coordinate. We use the extendDimension member function which instantiates a new net and returns a unique pointer to it:

GeneratingValue secondGenValue(1, {1});
auto newSobolNet = sobolNet->extendDimension(secondGenValue);
std::cout << "Second generating matrix:" << std::endl << newSobolNet->generatingMatrix(1) << std::endl;

The number of direction numbers required for each coordinate can be found here. Note that there is an offset as the coordinates start from 0 in the software.

Note that the generating matrix for the first coordinate is shared by the two nets. This is achieved through the use of shared pointers instead of raw pointers to the generating matrices. The memory management is directly handled by the smart pointers. This can be verified by comparing the adresses of the first generating matrix of each net:

if (&(sobolNet->generatingMatrix(0)) == &(newSobolNet->generatingMatrix(0)))
std::cout << "The shared generating matrix has a unique address." << std::endl;

Polynomial construction

Now we turn to the polynomial lattice rules case.

typedef typename NetConstructionTraits<NetConstruction::POLYNOMIAL>::GenValue GeneratingValue;
typedef typename NetConstructionTraits<NetConstruction::POLYNOMIAL>::SizeParameter Modulus;

The generating values of a polynomial lattice rules are polynomials over \(\mathbb F_2\) and the size parameter is also a polynomial (which corresponds to the modulus of the lattice).

To create a polynomial lattice rule with modulus \(1 + z^3 +z^{10}\) and first generating value \(1\), we first create the modulus ( \( 1033 = 1 + 2^3 + 2^{10}\)) and the generating value. Then we use the constructor of the DigitalNetConstruction class through the std::make_unique function template.

Modulus modulus = PolynomialFromInt(1033);
std::cout << "Modulus: " << modulus << std::endl;
GeneratingValue firstGenValue = PolynomialFromInt(1);
std::cout << "First generating value: " << firstGenValue << std::endl;
std::vector<GeneratingValue> genVals{firstGenValue};
auto polynomialNet = std::make_unique<DigitalNetConstruction<NetConstruction::POLYNOMIAL>>(1, modulus, genVals);
std::cout << "First generating matrix:" << std::endl << polynomialNet->generatingMatrix(0) << std::endl;

The extension of the lattice rule is performed in a very similar way to the Sobol' case. Here we add the polynomial \(z^9\) ( \(512 = 2^9\)) as second generating value.

GeneratingValue newGenValue = PolynomialFromInt(512);
std::cout << "Second generating value: " << newGenValue << std::endl;
auto newPolynomialNet = polynomialNet->extendDimension(newGenValue);
std::cout << "Second generating matrix:" << std::endl << newPolynomialNet->generatingMatrix(1) << std::endl;

Explicit construction

Let us finish with the explicit construction. In this case, we have the following types:

typedef typename NetConstructionTraits<NetConstruction::EXPLICIT>::GenValue GeneratingValue;
typedef typename NetConstructionTraits<NetConstruction::EXPLICIT>::SizeParameter SizeParameter;

In this case, the generating values are exactly the generating matrices. The size parameter is a pair of integers which represents the size of the matrices (number of rows and number of columns).

We now directly construct a digital net with explicit generating matrices in dimension 2, with \(2^{10}\) points. A matrix is specified as a vector of integers, the binary digits of an integer representing the elements of the associated row, with the least significant bit on the left.

GeneratingValue firstGenValue(10, 10, {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024});
std::cout << "Second generating value: " << std::endl << firstGenValue << std::endl;
GeneratingValue newGenValue(10, 10, {1, 1, 0, 7, 0, 31, 0, 127, 0, 511, 0});
std::cout << "Second generating value: " << std::endl << newGenValue << std::endl;
std::vector<GeneratingValue> genVals{firstGenValue, newGenValue};
SizeParameter sizeParam(10,10);
auto explicitNet = std::make_unique<DigitalNetConstruction<NetConstruction::EXPLICIT>>(2, sizeParam, genVals);

The complete example can be found in tutorial/NetDef.cc.