xref: /petsc/src/dm/dt/tests/ex14.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
1d6685f55SMatthew G. Knepley const char help[] = "Tests properties of probability distributions";
2d6685f55SMatthew G. Knepley 
3d6685f55SMatthew G. Knepley #include <petscdt.h>
4d6685f55SMatthew G. Knepley 
5d6685f55SMatthew G. Knepley /* Checks that
6d6685f55SMatthew G. Knepley    - the PDF integrates to 1
7d6685f55SMatthew G. Knepley    - the incomplete integral of the PDF is the CDF at many points
8d6685f55SMatthew G. Knepley */
99371c9d4SSatish Balay static PetscErrorCode VerifyDistribution(const char name[], PetscBool pos, PetscProbFunc pdf, PetscProbFunc cdf) {
10d6685f55SMatthew G. Knepley   const PetscInt digits = 14;
11d6685f55SMatthew G. Knepley   PetscReal      lower = pos ? 0. : -10., upper = 10.;
12d6685f55SMatthew G. Knepley   PetscReal      integral, integral2;
13d6685f55SMatthew G. Knepley   PetscInt       i;
14d6685f55SMatthew G. Knepley 
15d6685f55SMatthew G. Knepley   PetscFunctionBeginUser;
169566063dSJacob Faibussowitsch   PetscCall(PetscDTTanhSinhIntegrate((void (*)(const PetscReal[], void *, PetscReal *))pdf, lower, upper, digits, NULL, &integral));
1763a3b9bcSJacob Faibussowitsch   PetscCheck(PetscAbsReal(integral - 1.0) < 100 * PETSC_MACHINE_EPSILON, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "PDF %s must integrate to 1, not %g", name, (double)integral);
18d6685f55SMatthew G. Knepley   for (i = 0; i <= 10; ++i) {
19d6685f55SMatthew G. Knepley     const PetscReal x = i;
20d6685f55SMatthew G. Knepley 
219566063dSJacob Faibussowitsch     PetscCall(PetscDTTanhSinhIntegrate((void (*)(const PetscReal[], void *, PetscReal *))pdf, lower, x, digits, NULL, &integral));
229566063dSJacob Faibussowitsch     PetscCall(cdf(&x, NULL, &integral2));
2363a3b9bcSJacob Faibussowitsch     PetscCheck(PetscAbsReal(integral - integral2) < PETSC_SQRT_MACHINE_EPSILON, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Integral of PDF %s %g != %g CDF at x = %g", name, (double)integral, (double)integral2, (double)x);
24d6685f55SMatthew G. Knepley   }
25d6685f55SMatthew G. Knepley   PetscFunctionReturn(0);
26d6685f55SMatthew G. Knepley }
27d6685f55SMatthew G. Knepley 
289371c9d4SSatish Balay static PetscErrorCode TestDistributions() {
29d6685f55SMatthew G. Knepley   PetscProbFunc pdf[]  = {PetscPDFMaxwellBoltzmann1D, PetscPDFMaxwellBoltzmann2D, PetscPDFMaxwellBoltzmann3D, PetscPDFGaussian1D};
30d6685f55SMatthew G. Knepley   PetscProbFunc cdf[]  = {PetscCDFMaxwellBoltzmann1D, PetscCDFMaxwellBoltzmann2D, PetscCDFMaxwellBoltzmann3D, PetscCDFGaussian1D};
31d6685f55SMatthew G. Knepley   PetscBool     pos[]  = {PETSC_TRUE, PETSC_TRUE, PETSC_TRUE, PETSC_FALSE};
32d6685f55SMatthew G. Knepley   const char   *name[] = {"Maxwell-Boltzmann 1D", "Maxwell-Boltzmann 2D", "Maxwell-Boltzmann 3D", "Gaussian"};
33d6685f55SMatthew G. Knepley 
34d6685f55SMatthew G. Knepley   PetscFunctionBeginUser;
35*48a46eb9SPierre Jolivet   for (PetscInt i = 0; i < (PetscInt)(sizeof(pdf) / sizeof(PetscProbFunc)); ++i) PetscCall(VerifyDistribution(name[i], pos[i], pdf[i], cdf[i]));
36d6685f55SMatthew G. Knepley   PetscFunctionReturn(0);
37d6685f55SMatthew G. Knepley }
38d6685f55SMatthew G. Knepley 
399371c9d4SSatish Balay static PetscErrorCode TestSampling() {
40d6685f55SMatthew G. Knepley   PetscProbFunc cdf[2]     = {PetscCDFMaxwellBoltzmann1D, PetscCDFMaxwellBoltzmann2D};
41d6685f55SMatthew G. Knepley   PetscProbFunc sampler[2] = {PetscPDFSampleGaussian1D, PetscPDFSampleGaussian2D};
42d6685f55SMatthew G. Knepley   PetscInt      dim[2]     = {1, 2};
43d6685f55SMatthew G. Knepley   PetscRandom   rnd;
44d6685f55SMatthew G. Knepley   Vec           v;
45d6685f55SMatthew G. Knepley   PetscScalar  *a;
46d6685f55SMatthew G. Knepley   PetscReal     alpha, confidenceLevel = 0.05;
47d6685f55SMatthew G. Knepley   PetscInt      n = 1000, s, i, d;
48d6685f55SMatthew G. Knepley 
49d6685f55SMatthew G. Knepley   PetscFunctionBeginUser;
509566063dSJacob Faibussowitsch   PetscCall(PetscRandomCreate(PETSC_COMM_SELF, &rnd));
519566063dSJacob Faibussowitsch   PetscCall(PetscRandomSetInterval(rnd, 0, 1.));
529566063dSJacob Faibussowitsch   PetscCall(PetscRandomSetFromOptions(rnd));
53d6685f55SMatthew G. Knepley 
54d6685f55SMatthew G. Knepley   for (s = 0; s < 2; ++s) {
559566063dSJacob Faibussowitsch     PetscCall(VecCreateSeq(PETSC_COMM_SELF, n * dim[s], &v));
569566063dSJacob Faibussowitsch     PetscCall(VecSetBlockSize(v, dim[s]));
579566063dSJacob Faibussowitsch     PetscCall(VecGetArray(v, &a));
58d6685f55SMatthew G. Knepley     for (i = 0; i < n; ++i) {
59d6685f55SMatthew G. Knepley       PetscReal r[3], o[3];
60d6685f55SMatthew G. Knepley 
619566063dSJacob Faibussowitsch       for (d = 0; d < dim[s]; ++d) PetscCall(PetscRandomGetValueReal(rnd, &r[d]));
629566063dSJacob Faibussowitsch       PetscCall(sampler[s](r, NULL, o));
63d6685f55SMatthew G. Knepley       for (d = 0; d < dim[s]; ++d) a[i * dim[s] + d] = o[d];
64d6685f55SMatthew G. Knepley     }
659566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(v, &a));
669566063dSJacob Faibussowitsch     PetscCall(PetscProbComputeKSStatistic(v, cdf[s], &alpha));
6763a3b9bcSJacob Faibussowitsch     PetscCheck(alpha < confidenceLevel, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "KS finds sampling does not match the distribution at confidence level %.2g", (double)confidenceLevel);
689566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&v));
69d6685f55SMatthew G. Knepley   }
709566063dSJacob Faibussowitsch   PetscCall(PetscRandomDestroy(&rnd));
71d6685f55SMatthew G. Knepley   PetscFunctionReturn(0);
72d6685f55SMatthew G. Knepley }
73d6685f55SMatthew G. Knepley 
749371c9d4SSatish Balay int main(int argc, char **argv) {
75327415f7SBarry Smith   PetscFunctionBeginUser;
769566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
779566063dSJacob Faibussowitsch   PetscCall(TestDistributions());
789566063dSJacob Faibussowitsch   PetscCall(TestSampling());
799566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
80b122ec5aSJacob Faibussowitsch   return 0;
81d6685f55SMatthew G. Knepley }
82d6685f55SMatthew G. Knepley 
83d6685f55SMatthew G. Knepley /*TEST
84d6685f55SMatthew G. Knepley 
85d6685f55SMatthew G. Knepley   test:
86d6685f55SMatthew G. Knepley     suffix: 0
87d6685f55SMatthew G. Knepley     requires: ks
88d6685f55SMatthew G. Knepley     args:
89d6685f55SMatthew G. Knepley 
90d6685f55SMatthew G. Knepley TEST*/
91