Compute the L2 norm of a Field

Hi!

We have a Field with index parameter in 2D and scalar value and we want to compute its L^2 norm:

\|X\|_{L^2}^2 = \int_\mathcal{D} X(\omega,{\bf t})^2 d{\bf t}

Is there a method in OT to compute this? Otherwise, it is necessary to take into account the function values and the volume of the vertices with Mesh.computeWeights(), which is doable more requires some computations.

Best regards,

Michaël

It is quite tricky. I can see several options:

• Approximate the true squared L^2 norm using a quadrature rule in the spirit of the midpoint rule (it is exactly this rule for 1D meshes). For that, use mesh.computeWeights()
• Compute the the exact squared L^2 norm of a piecewise interpolation of the field given its values at the vertices. For that, use mesh.computeP1Gram()

Here is a script to compare these options, as well as reference values obtained using adaptive quadratures of the model or the P_1 interpolation:

import openturns as ot

integrator = ot.GaussKronrod(65536, 1e-15, ot.GaussKronrodRule(ot.GaussKronrodRule.G7K15))

# The reference function
model = ot.SymbolicFunction("x", "sin(x+x^2/4)")
# An helper function
square = ot.SymbolicFunction("x", "x^2")

N = 10
domain = ot.Interval(-2.0, 2.0)
mesh = ot.IntervalMesher([N]).build(domain)

# Here we deform the mesh in order to have a nonuniform sampling of the domain
deform = ot.SymbolicFunction("x", "x+0.1*sin(pi_*x)")
mesh.setVertices(deform(mesh.getVertices()))

# g = mesh.draw()
# Show(g)

###################################################
###################################################
refL2NormSquared = integrator.integrate(ot.ComposedFunction(square, model), domain)[0]
print("refL2NormSquared   =%.12g" % refL2NormSquared, "rel. err=%.4e" % abs(1-refL2NormSquared/refL2NormSquared))
##############################################################################
# Mid-point approximation of the true squared L2 norm using the mesh weights #
##############################################################################
values = model(mesh.getVertices())
field = ot.Field(mesh, values)
fieldSquared = ot.ValueFunction(square, mesh)(field)
weightL2NormSquared = fieldSquared.asPoint().dot(mesh.computeWeights())
print("weightL2NormSquared=%.12g" % weightL2NormSquared, "rel. err=%.4e" % abs(1-weightL2NormSquared/refL2NormSquared))
########################################################################
# Exact squared L2 norm of a P1 interpolation using the P1 Gram matrix #
########################################################################
gram = mesh.computeP1Gram()
gramL2NormSquared = values.asPoint().dot(gram*values.asPoint())
print("gramL2NormSquared  =%.12g" % gramL2NormSquared, "rel. err=%.4e" % abs(1-gramL2NormSquared/refL2NormSquared))
#########################################################################
# Exact squared L2 norm of a P1 interpolation using adaptive quadrature #
#########################################################################
myFieldSquaredFunction = ot.ComposedFunction(square, ot.Function(ot.P1LagrangeEvaluation(field)))


I get the following results:

refL2NormSquared   =1.82317483123 rel. err=0.0000e+00
weightL2NormSquared=1.84393295915 rel. err=1.1386e-02
gramL2NormSquared  =1.74962050461 rel. err=4.0344e-02