Page MenuHomec4science

quadrature_sampler.py
No OneTemporary

File Metadata

Created
Tue, May 7, 07:59

quadrature_sampler.py

# Copyright (C) 2018 by the RROMPy authors
#
# This file is part of RROMPy.
#
# RROMPy is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# RROMPy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with RROMPy. If not, see <http://www.gnu.org/licenses/>.
#
import numpy as np
from .generic_sampler import GenericSampler
from rrompy.utilities.base.types import Np1D, Tuple, List, paramList
from rrompy.utilities.exception_manager import RROMPyException
from rrompy.utilities.base import lowDiscrepancy, kroneckerer
from rrompy.parameter import checkParameterList
__all__ = ['QuadratureSampler']
class QuadratureSampler(GenericSampler):
"""Generator of quadrature sample points."""
allowedKinds = ["UNIFORM", "CHEBYSHEV", "GAUSSLEGENDRE"]
def __init__(self, lims:paramList, kind : str = "UNIFORM",
scaling : List[callable] = None,
scalingInv : List[callable] = None):
super().__init__(lims = lims, scaling = scaling,
scalingInv = scalingInv)
self.kind = kind
def __str__(self) -> str:
return "{}_{}".format(super().__str__(), self.kind)
def __repr__(self) -> str:
return self.__str__() + " at " + hex(id(self))
@property
def kind(self):
"""Value of kind."""
return self._kind
@kind.setter
def kind(self, kind):
if kind.upper() not in self.allowedKinds:
raise RROMPyException("Generator kind not recognized.")
self._kind = kind.upper()
def generatePoints(self, n:List[int]) -> Tuple[paramList, Np1D]:
"""Array of sample points and array of weights."""
if not hasattr(n, "__len__"): n = [n]
super().generatePoints(n)
nleft, nright = 1, np.prod(n)
xmat = np.empty((nright, self.npar), dtype = self.lims.dtype)
w = np.ones(nright)
for d in range(self.npar):
nright //= n[d]
a, b = self.lims[0](d), self.lims[1](d)
if self.scaling is not None:
a, b = self.scaling[d](a), self.scaling[d](b)
c, r = (a + b) / 2., (a - b) / 2.
dAbs = 2. * np.abs(r)
if self.kind == "UNIFORM":
xd = np.linspace(a, b, n[d])
wd = dAbs / n[d] * np.ones(n[d])
elif self.kind == "CHEBYSHEV":
nodes, weights = np.polynomial.chebyshev.chebgauss(n[d])
xd = c + r * nodes
wd = dAbs / np.pi * weights[:]
elif self.kind == "GAUSSLEGENDRE":
nodes, weights = np.polynomial.legendre.leggauss(n[d])
xd = c + r * nodes[::-1]
wd = dAbs * weights[::-1]
if len(xd) > 1:
fejerOrdering = [n[d] - 1] + lowDiscrepancy(n[d] - 1)
xd = xd[fejerOrdering]
wd = wd[fejerOrdering]
if self.scalingInv is not None:
xd = self.scalingInv[d](xd)
xmat[:, d] = kroneckerer(xd, nleft, nright)
w *= kroneckerer(wd, nleft, nright)
nleft *= n[d]
x, _ = checkParameterList(xmat, self.npar)
return x, w

Event Timeline