Пример #1
0
def setInputRandomVector(inList):
    #setting the input random vector X
    myCollection = ot.DistributionCollection(len(inList))
    for index in range(len(inList)):
        myCollection[index] = ot.Distribution(inList[index])
    myDistribution = ot.ComposedDistribution(myCollection)
    VectX = ot.RandomVector(ot.Distribution(myDistribution))
    return myDistribution, VectX
Пример #2
0
 def test_ConditionalDistribution2(self):
     # The random variable is (X0, X1, X2)
     distribution = ot.Normal(3)
     # We condition X = (X0, X1, X2) given X1=2.0, X2=3.0
     conditionalIndices = [1, 2]
     conditionalReferencePoint = [2.0, 3.0]
     conditionalDistribution = ot.Distribution(
         otbenchmark.ConditionalDistribution(distribution,
                                             conditionalIndices,
                                             conditionalReferencePoint))
     # PDF
     computed = conditionalDistribution.computePDF([1.0])
     print("computed PDF=", computed)
     conditionedPDF = distribution.computePDF(
         [1.0, conditionalReferencePoint[0], conditionalReferencePoint[1]])
     n2 = ot.Normal(2)
     conditioningPDF = n2.computePDF(
         [conditionalReferencePoint[0], conditionalReferencePoint[1]])
     exact = conditionedPDF / conditioningPDF
     np.testing.assert_allclose(computed, exact)
     # CDF
     computed = conditionalDistribution.computeCDF([1.0])
     print("computed CDF=", computed)
     exact = 0.8413447460685339
     np.testing.assert_allclose(computed, exact)
     # CDF when X0 = INF, X2 = INF
     computed = conditionalDistribution.computeCDF([7.0])
     print("computed CDF=", computed)
     exact = 1.0
     np.testing.assert_allclose(computed, exact)
Пример #3
0
 def getMarginal(self, indices):
     subA = []
     subB = []
     for i in indices:
         subA.append(self.a[i])
         subB.append(self.b[i])
     return ot.Distribution(UniformNdPy(subA, subB))
Пример #4
0
 def test_ConditionalDistribution1(self):
     # The random variable is (X0, X1, X2)
     distribution = ot.Normal(3)
     # We condition with respect to X1=mu1, i.e.
     # we consider (X0, X1, X2) | X1=2
     conditionalIndices = [1]
     conditionalReferencePoint = [2.0]
     conditionalDistribution = ot.Distribution(
         otbenchmark.ConditionalDistribution(distribution,
                                             conditionalIndices,
                                             conditionalReferencePoint))
     # PDF
     computed = conditionalDistribution.computePDF([1.0, 1.0])
     print("computed PDF=", computed)
     conditionedPDF = distribution.computePDF(
         [1.0, 1.0, conditionalReferencePoint[0]])
     n1 = ot.Normal(1)
     conditioningPDF = n1.computePDF([conditionalReferencePoint[0]])
     exact = conditionedPDF / conditioningPDF
     np.testing.assert_allclose(computed, exact)
     # CDF
     computed = conditionalDistribution.computeCDF([1.0, 1.0])
     print("computed CDF=", computed)
     exact = 0.7078609817371252
     np.testing.assert_allclose(computed, exact)
     # CDF when X0 = INF, X2 = INF
     computed = conditionalDistribution.computeCDF([7.0, 7.0])
     print("computed CDF=", computed)
     exact = 1.0
     np.testing.assert_allclose(computed, exact)
Пример #5
0
 def test_ConditionalDistribution4(self):
     # Create a dimension 5 distribution
     distribution = ot.Normal(5)
     conditionalIndices = [1, 2]
     conditionalReferencePoint = [2.0, 3.0]
     conditionalDistribution = ot.Distribution(
         otbenchmark.ConditionalDistribution(distribution,
                                             conditionalIndices,
                                             conditionalReferencePoint))
     # PDF
     computed = conditionalDistribution.computePDF([1.0] * 3)
     print("computed PDF=", computed)
Пример #6
0
def GenerateExperiencePlan(paras_range=paras_ris_range, n_sample=50000):
    """
    """
    for k, v in paras_range.items():
        assert v[0] < v[1], 'ERROR of v[0]>=v[1] for ranges {}'.format(k)

    # le nombre de paramètre doit être proportionné au dimension de ranges
    len_actual_parameters = len(paras_range)
    # Specify the input random vector.
    # instance de classe densite de proba a definir
    myCollection = ot.DistributionCollection(len_actual_parameters)

    for i, p_name in enumerate(paras_range):
        distribution = ot.Uniform(paras_range[p_name][0],
                                  paras_range[p_name][1])
        myCollection[i] = ot.Distribution(distribution)
    myDistribution = ot.ComposedDistribution(myCollection)
    vectX = ot.RandomVector(ot.Distribution(myDistribution))

    # Sample the input random vector.
    Xsample = GenerateSample(vectX, n_sample, method='QMC')
    xsample = np.array(Xsample)
    return xsample
Пример #7
0
 def test_DrawPDF(self):
     # The random variable is (X0, X1, X2)
     distribution = ot.Normal(3)
     # We condition with respect to X1=mu1, i.e.
     # we consider (X0, X1, X2) | X1=2
     conditionalIndices = [1]
     conditionalReferencePoint = [2.0]
     conditionalDistribution = ot.Distribution(
         otbenchmark.ConditionalDistribution(distribution,
                                             conditionalIndices,
                                             conditionalReferencePoint))
     # Avoid failing on CircleCi
     # _tkinter.TclError: no display name and no $DISPLAY environment variable
     try:
         graph = conditionalDistribution.drawPDF()
         _ = otv.View(graph)
     except Exception as e:
         print(e)
Пример #8
0
 def test_ConditionalDistribution3(self):
     # Do not condition anything.
     distribution = ot.Normal(3)
     conditionalIndices = []
     conditionalReferencePoint = []
     conditionalDistribution = ot.Distribution(
         otbenchmark.ConditionalDistribution(distribution,
                                             conditionalIndices,
                                             conditionalReferencePoint))
     # PDF
     computed = conditionalDistribution.computePDF([1.0, 1.0, 1.0])
     print("computed PDF=", computed)
     exact = distribution.computePDF([1.0, 1.0, 1.0])
     np.testing.assert_allclose(computed, exact)
     # CDF
     computed = conditionalDistribution.computeCDF([1.0, 1.0, 1.0])
     print("computed CDF=", computed)
     exact = distribution.computeCDF([1.0, 1.0, 1.0])
     np.testing.assert_allclose(computed, exact)
     # CDF when X0 = INF, X2 = INF
     computed = conditionalDistribution.computeCDF([7.0, 7.0, 7.0])
     print("computed CDF=", computed)
     exact = 1.0
     np.testing.assert_allclose(computed, exact)
Пример #9
0
from __future__ import print_function
import openturns as ot
import chaospy as cp
import numpy as np

# A chaospy Triangle distribution
d0 = cp.Triangle(2.0, 3.5, 4.0)
d1 = cp.Kumaraswamy(2.0, 3.0, -1.0, 4.0)
d2 = cp.J(d0, d1)
for chaospy_dist in [d0, d1, d2]:
    np.random.seed(42)

    # create an openturns distribution
    py_dist = ot.ChaospyDistribution(chaospy_dist)
    distribution = ot.Distribution(py_dist)

    print('distribution=', distribution)
    print('realization=', distribution.getRealization())
    sample = distribution.getSample(10)
    print('sample=', sample[0:5])
    point = [2.6]*distribution.getDimension()
    print('pdf= %.6g' % distribution.computePDF(point))
    cdf = distribution.computeCDF(point)
    print('cdf= %.6g' % cdf)
    print('mean=', distribution.getMean())
    print('mean(sampling)=', sample.computeMean())
    print('std=', distribution.getStandardDeviation())
    print('std(sampling)=', sample.computeStandardDeviationPerComponent())
    print('skewness=', distribution.getSkewness())
    print('skewness(sampling)=', sample.computeSkewness())
        param.extend(self.b)
        return param

    def getParameterDescription(self):
        paramDesc = ['a_' + str(i) for i in range(len(self.a))]
        paramDesc.extend(['b_' + str(i) for i in range(len(self.a))])
        return paramDesc

    def setParameter(self, parameter):
        dim = len(self.a)
        for i in range(dim):
            self.a[i] = parameter[i]
            self.b[i] = parameter[dim + i]


myDist = ot.Distribution(UniformNdPy([0.0] * 2, [2.0] * 2))

st = ot.Study()
fileName = 'PyDIST.xml'
st.setStorageManager(ot.XMLStorageManager(fileName))

st.add("myDist", myDist)
st.save()

print('saved dist=', myDist)

dist = ot.Distribution()

st = ot.Study()
st.setStorageManager(ot.XMLStorageManager(fileName))
Пример #11
0
        paramDesc.extend(['b_' + str(i) for i in range(len(self.a))])
        return paramDesc

    def setParameter(self, parameter):
        dim = len(self.a)
        for i in range(dim):
            self.a[i] = parameter[i]
            self.b[i] = parameter[dim + i]


for pyDist in [UniformNdPy(), UniformNdPy([0.] * 2, [1.] * 2)]:

    print("pyDist=", pyDist)

    # Instance creation
    myDist = ot.Distribution(pyDist)
    print("myDist=", repr(myDist))

    # Copy constructor
    newRV = ot.Distribution(myDist)

    # Dimension
    dim = myDist.getDimension()
    print('dimension=', dim)

    # Realization
    X = myDist.getRealization()
    print('realization=', X)

    # Sample
    X = myDist.getSample(5)
Пример #12
0
                                     ot.TruncatedDistribution.UPPER)
graph = truncated.drawPDF()
view = viewer.View(graph)

# %%
# truncated on both bounds
truncated = ot.TruncatedDistribution(distribution, 0.2, 1.5)
graph = truncated.drawPDF()
view = viewer.View(graph)

# %%
# Define a multivariate distribution
dimension = 2
size = 70
sample = ot.Normal(dimension).getSample(size)
ks = ot.KernelSmoothing().build(sample)

# %%
# Truncate it between (-2;2)^n
bounds = ot.Interval([-2.0] * dimension, [2.0] * dimension)
truncatedKS = ot.Distribution(ot.TruncatedDistribution(ks, bounds))

# %%
# Draw its PDF
graph = truncatedKS.drawPDF([-2.5] * dimension, [2.5] * dimension,
                            [256] * dimension)
graph.add(ot.Cloud(truncatedKS.getSample(200)))
graph.setColors(["blue", "red"])
view = viewer.View(graph)
plt.show()
Пример #13
0
#! /usr/bin/env python

import openturns as ot

ot.TESTPREAMBLE()

# Instantiate one distribution object
dim = 3
R = ot.CorrelationMatrix(dim)
for i in range(dim - 1):
    R[i, i + 1] = 0.25
copula = ot.SklarCopula(
    ot.Distribution(ot.Normal([1.0, 2.0, 3.0], [2.0, 3.0, 1.0], R)))
copulaRef = ot.NormalCopula(R)
print("Copula ", repr(copula))
print("Copula ", copula)
print("Mean      =", repr(copula.getMean()))
print("Mean (ref)=", repr(copulaRef.getMean()))
ot.ResourceMap.SetAsUnsignedInteger("GaussKronrod-MaximumSubIntervals", 20)
ot.ResourceMap.SetAsScalar("GaussKronrod-MaximumError",  1.0e-4)
print("Covariance      =", repr(copula.getCovariance()))
ot.ResourceMap.SetAsUnsignedInteger("GaussKronrod-MaximumSubIntervals", 100)
ot.ResourceMap.SetAsScalar("GaussKronrod-MaximumError",  1.0e-12)
print("Covariance (ref)=", repr(copulaRef.getCovariance()))

# Is this copula an elliptical distribution?
print("Elliptical distribution= ", copula.isElliptical())

# Is this copula elliptical ?
print("Elliptical copula= ", copula.hasEllipticalCopula())
Пример #14
0
        return log_pdf

    def setParameter(self, parameter):
        self.beta = parameter[0]
        self.alpha = parameter[1]

    def getParameter(self):
        return [self.beta, self.alpha]


# %%
# Convert to :class:`~openturns.Distribution`

# %%

conditional = ot.Distribution(CensoredWeibull())

# %%
# Observations, prior, initial point and proposal distributions
# -------------------------------------------------------------
#
# Define the observations

# %%

Tobs = np.array([4380, 1791, 1611, 1291, 6132, 5694, 5296, 4818, 4818, 4380])
fail = np.array([True] * 4 + [False] * 6)
x = ot.Sample(np.vstack((Tobs, fail)).T)

# %%
# Define a uniform prior distribution for :math:`\alpha` and a Gamma prior distribution for :math:`\beta`.
import openturns as ot
from matplotlib import pyplot as plt
from openturns.viewer import View
ot.RandomGenerator.SetSeed(0)

# Generate sample with the given plane
distribution = ot.ComposedDistribution(
    [ot.Exponential(), ot.Triangular(-1.0, -0.5, 1.0)])
marginalSizes = ot.Indices([3, 6])
experiment = ot.GaussProductExperiment(
    ot.Distribution(distribution), marginalSizes)

sample = experiment.generate()

# Create an empty graph
graph = ot.Graph("Gauss product experiment", "x1", "x2", True, "")

# Create the cloud
cloud = ot.Cloud(sample, "blue", "fsquare", "")

# Then, draw it
graph.add(cloud)

fig = plt.figure(figsize=(4, 4))
axis = fig.add_subplot(111)
axis.set_xlim(auto=True)
View(graph, figure=fig, axes=[axis], add_legend=False)
import openturns as ot
from matplotlib import pyplot as plt
from openturns.viewer import View
ot.RandomGenerator.SetSeed(0)

# Generate sample with the given plane
distribution = ot.ComposedDistribution(
    ot.DistributionCollection(
        [ot.Exponential(), ot.Triangular(-1.0, -0.5, 1.0)]))
marginalDegrees = ot.Indices([3, 6])
myPlane = ot.GaussProductExperiment(ot.Distribution(distribution),
                                    marginalDegrees)

sample = myPlane.generate()

# Create an empty graph
graph = ot.Graph("", "x1", "x2", True, "")

# Create the cloud
cloud = ot.Cloud(sample, "blue", "fsquare", "")

# Then, draw it
graph.add(cloud)
fig = plt.figure(figsize=(4, 4))
plt.suptitle("Gauss product experiment")
axis = fig.add_subplot(111)
axis.set_xlim(auto=True)
View(graph, figure=fig, axes=[axis], add_legend=False)
Пример #17
0
conditionedDistribution = ot.Normal()
conditioningDistributionCollection = []
# First conditioning distribution: continuous/continuous
atoms = [ot.Uniform(0.0, 1.0), ot.Uniform(1.0, 2.0)]
conditioningDistributionCollection.append(ot.ComposedDistribution(atoms))
# Second conditioning distribution: discrete/continuous
atoms = [ot.Binomial(3, 0.5), ot.Uniform(1.0, 2.0)]
#conditioningDistributionCollection.append(ot.ComposedDistribution(atoms))
# Third conditioning distribution: dirac/continuous
atoms = [ot.Dirac(0.0), ot.Uniform(1.0, 2.0)]
conditioningDistributionCollection.append(ot.ComposedDistribution(atoms))


for conditioning in conditioningDistributionCollection:
    print("conditioning distribution=", conditioning)
    observationsDistribution = ot.Distribution(conditionedDistribution)
    observationsDistribution.setParameter(conditioning.getMean())
    observations = observationsDistribution.getSample(observationsSize)
    distribution  = ot.PosteriorDistribution(ot.ConditionalDistribution(conditionedDistribution, conditioning), observations)
    dim = distribution.getDimension()
    print("Distribution ", distribution)
    print("Distribution ", distribution)
    print("range=", distribution.getRange())
    mean = distribution.getMean()
    print("Mean ", mean)
    print("Covariance ", distribution.getCovariance())
    # Is this distribution an elliptical distribution?
    print("Elliptical distribution= ", distribution.isElliptical())

    # Has this distribution an elliptical copula?
    print("Elliptical copula= ", distribution.hasEllipticalCopula())
#! /usr/bin/env python

from __future__ import print_function
import openturns as ot
import os

ot.TESTPREAMBLE()

d = ot.Distribution()

# load
study = ot.Study()
study.setStorageManager(ot.XMLStorageManager('pyd.xml'))
study.load()
study.fillObject('d', d)

print(d.getKurtosis())
print(d.computePDF([0.5]))
print(d.computeCDF([0.5]))

os.remove('pyd.xml')
	polyColl[i] = ot.HermiteFactory()

enumerateFunction = ot.LinearEnumerateFunction(dim)
multivariateBasis = ot.OrthogonalProductPolynomialFactory(polyColl, enumerateFunction)

basisSequenceFactory = ot.LARS()
fittingAlgorithm = ot.CorrectedLeaveOneOut()
approximationAlgorithm = ot.LeastSquaresMetaModelSelectionFactory(basisSequenceFactory, fittingAlgorithm)

evalStrategy = ot.LeastSquaresStrategy(Data, Result,  approximationAlgorithm)

order = 3
P = enumerateFunction.getStrataCumulatedCardinal(order)
truncatureBasisStrategy = ot.FixedStrategy(multivariateBasis, P)

polynomialChaosAlgorithm = ot.FunctionalChaosAlgorithm(Data, Result, ot.Distribution(myDistribution), truncatureBasisStrategy, evalStrategy)

polynomialChaosAlgorithm.run()

The_Result = polynomialChaosAlgorithm.getResult()
Error = The_Result.getRelativeErrors()

ChaosRV = ot.FunctionalChaosRandomVector(The_Result)
Mean = ChaosRV.getMean()[0]
StD = np.sqrt(ChaosRV.getCovariance()[0,0])

print("")
print("Response mean : ", Mean)
print("")
print("Response standard deviation : ", StD)
print("")
Пример #20
0
# 2D Normal with scale & correlation
# This allows checking that Normal::getRoughness is well implemented
corr = ot.CorrelationMatrix(2)
corr[1, 0] = 0.3
distribution = ot.Normal([0, 0], [1, 2], corr)
ott.assert_almost_equal(distribution.getRoughness(),
                        compute_roughness_sampling(distribution))

distribution = ot.Epanechnikov()
ott.assert_almost_equal(distribution.getRoughness(), 3/5)

distribution = ot.Triangular()
ott.assert_almost_equal(distribution.getRoughness(), 2/3)

distribution = ot.Distribution(Quartic())
ott.assert_almost_equal(distribution.getRoughness(), 5/7)

# Testing Histogram ==> getSingularities
distribution = ot.HistogramFactory().buildAsHistogram(ot.Uniform(0, 1).getSample(100000))
ott.assert_almost_equal(distribution.getRoughness(), 1.0, 5e-4, 1e-5)
# Compute the roughness using width and height
width = distribution.getWidth()
height = distribution.getHeight()
roughness = sum([width[i] * height[i]**2 for i in range(len(height))])
ott.assert_almost_equal(distribution.getRoughness(), roughness)

# Large dimension with independent copula
# With small rho value, we should have results similar to 
# independent copula. But here we use the sampling method
# This allows the validation of this sampling method
Пример #21
0
            if X[i] < self.a[i]:
                return 0.0
            prod *= (min(self.b[i], X[i]) - self.a[i])
        return prod / self.factor

    def computePDF(self, X):
        for i in range(len(self.a)):
            if X[i] < self.a[i]:
                return 0.0
            if X[i] > self.b[i]:
                return 0.0
        return 1.0 / self.factor

    def getMean(self):
        mu = []
        for i in range(len(self.a)):
            mu.append(0.5 * (self.a[i] + self.b[i]))
        return mu


d = ot.Distribution(UniformNdPy())
print(d.getKurtosis())
print(d.computePDF([0.5]))
print(d.computeCDF([0.5]))

# save
study = ot.Study()
study.setStorageManager(ot.XMLStorageManager('pyd.xml'))
study.add('d', d)
study.save()
Пример #22
0
#§ 2. Random vector definition
# Create the marginal distributions of the input random vector
dict_distribution = {
    "PARE0":ot.Normal(7032392.1, 20700.0),
    "QARE0":ot.Normal(2142.972222, 8.5),
    "TARE0":ot.Normal(500.2497543, 3.0),
    "QGSS0":ot.Normal(183.713226, 0.75),
    "QGRE0":ot.Normal(1922.331218, 8.5),
    "PGCT0":ot.Normal(6.54e6, 6.40e4),
}

# Create the input probability distribution
collectionMarginals = ot.DistributionCollection()
for distribution in list(dict_distribution.values()):
    collectionMarginals.add(ot.Distribution(distribution))

inputDistribution = ot.ComposedDistribution(collectionMarginals)

# Give a description of each component of the input distribution
inputDistribution.setDescription(list(dict_distribution.keys()))
inputRandomVector = ot.RandomVector(inputDistribution)

#§
def run_demo(with_initialization_script, seed=None, n_simulation=None):
    """Run the demonstration

    Parameters
    ----------
    with_initialization_script : Boolean, whether or not to use an
    initialization script. If not (default), appropriate start values are
        py_dist = UniformNdPy(subA, subB)
        return ot.Distribution(py_dist)

    def computeQuantile(self, prob, tail=False):
        q = 1.0 - prob if tail else prob
        quantile = self.a
        for i in range(len(self.a)):
            quantile[i] += q * (self.b[i] - self.a[i])
        return quantile


# %%
# Let us instantiate the distribution:

# %%
distribution = ot.Distribution(UniformNdPy([5, 6], [7, 9]))

# %%
# And plot the `cdf`:

# %%
graph = distribution.drawCDF()
graph.setColors(["blue"])
view = viewer.View(graph)

# %%
# We can easily generate sample:

# %%
distribution.getSample(5)
Пример #24
0
        paramDesc.extend(['b_' + str(i) for i in range(len(self.a))])
        return paramDesc

    def setParameter(self, parameter):
        dim = len(self.a)
        for i in range(dim):
            self.a[i] = parameter[i]
            self.b[i] = parameter[dim + i]


for pyDist in [UniformNdPy(), UniformNdPy([0.] * 2, [1.] * 2)]:

    print("pyDist=", pyDist)

    # Instance creation
    myDist = ot.Distribution(pyDist)
    print("myDist=", repr(myDist))

    # Copy constructor
    newRV = ot.Distribution(myDist)

    # Dimension
    dim = myDist.getDimension()
    print('dimension=', dim)

    # Realization
    X = myDist.getRealization()
    print('realization=', X)

    # Sample
    X = myDist.getSample(5)
    def drawConditionalPDF(self, referencePoint):
        """
        Draw the PDF of the conditional distribution.

        Within the grid, duplicate X and Y axes labels are removed, so that
        the minimum amount of labels are printed, reducing the risk of overlap.

        Each i-th graphics of the diagonal of the plot present the
        conditional distribution:
        X | Xi=referencePoint[i].

        Each (i,j)-th graphics of the diagonal of the plot present the
        conditional distribution:
        X | Xi=referencePoint[i], Xi=referencePoint[j]
        for i different from j.

        Parameters
        ----------
        referencePoint : ot.Point
            The conditioning point value.
        """
        description = self.distribution.getDescription()
        inputDimension = self.distribution.getDimension()
        fig = pl.figure(figsize=(12, 12))
        _ = fig.suptitle("Iso-values of conditional PDF")
        for i in range(inputDimension):
            # Diagonal part :
            # PDF(xi) where x(j != i) is equal to the reference
            # Create the cross cut function
            crossCutIndices = []
            crossCutReferencePoint = []
            for k in range(inputDimension):
                if k != i:
                    crossCutIndices.append(k)
                    crossCutReferencePoint.append(referencePoint[k])
            conditionalDistribution = ot.Distribution(
                otb.ConditionalDistribution(self.distribution, crossCutIndices,
                                            crossCutReferencePoint))
            # Draw
            graph = conditionalDistribution.drawPDF()
            graph.setXTitle(description[i])
            graph.setLegends([""])
            index = 1 + i * inputDimension + i
            ax = fig.add_subplot(inputDimension, inputDimension, index)
            _ = otv.View(graph, figure=fig, axes=[ax])
            # Lower triangle : y(xi, xj) where x(k != i and k != j)
            # is equal to the reference
            for j in range(i):
                # Draw the cross cut (Xi, Xj), where all other variables
                # are set to the reference value
                # Create the cross cut function
                crossCutIndices = []
                crossCutReferencePoint = []
                for k in range(inputDimension):
                    if k != i and k != j:
                        crossCutIndices.append(k)
                        crossCutReferencePoint.append(referencePoint[k])
                conditionalDistribution = ot.Distribution(
                    otb.ConditionalDistribution(self.distribution,
                                                crossCutIndices,
                                                crossCutReferencePoint))
                # Draw
                graph = conditionalDistribution.drawPDF()
                # Workaround for https://github.com/openturns/openturns/issues/1230
                # The ConditionalDistribution should manage the description, but
                # cannot because of a limitation in OT.
                # Explanation: j is the column number in the plot grid
                graph.setXTitle(description[j])
                # Explanation: i is the row number in the plot grid
                graph.setYTitle(description[i])
                print("Descr = ", i, j)
                # Remove unnecessary labels
                # Only the last bottom i-th row has a X axis title
                if i < inputDimension - 1:
                    graph.setXTitle("")
                # Only the first left column has a Y axis title
                if j > 0:
                    graph.setYTitle("")
                graph.setTitle("Iso-values of conditional PDF")
                index = 1 + i * inputDimension + j
                ax = fig.add_subplot(inputDimension, inputDimension, index)
                _ = otv.View(graph, figure=fig, axes=[ax])
        return fig