Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/nataf stability #192

Merged
merged 4 commits into from
Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/code/surrogates/gpr/plot_gpr_custom2D.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
y_act = np.array(r2model.qoi_list).reshape(x1g.shape[0], x1g.shape[1])

fig1 = plt.figure()
ax = fig1.gca(projection='3d')
ax = fig1.add_subplot(projection='3d')
surf = ax.plot_surface(x1g, x2g, y_act, cmap=cm.coolwarm, linewidth=0, antialiased=False)
ax.set_zlim(-1, 15)
ax.zaxis.set_major_locator(LinearLocator(10))
Expand Down
6 changes: 3 additions & 3 deletions docs/code/surrogates/pce/plot_pce_camel.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def function(x, y):
f = function(X1_, X2_)

fig = plt.figure(figsize=(10, 6))
ax = fig.gca(projection='3d')
ax = fig.add_subplot(projection='3d')
surf = ax.plot_surface(X1_, X2_, f, rstride=1, cstride=1, cmap='gnuplot2', linewidth=0, antialiased=False)
ax.set_title('True function')
ax.set_xlabel('$x_1$', fontsize=15)
Expand All @@ -95,7 +95,7 @@ def function(x, y):
# %%

fig = plt.figure(figsize=(10, 6))
ax = fig.gca(projection='3d')
ax = fig.add_subplot(projection='3d')
ax.scatter(x[:, 0], x[:, 1], y, s=20, c='r')

ax.set_title('Training data')
Expand Down Expand Up @@ -168,7 +168,7 @@ def function(x, y):
# %%

fig = plt.figure(figsize=(10,6))
ax = fig.gca(projection='3d')
ax = fig.add_subplot(projection='3d')
ax.scatter(x_test[:,0], x_test[:,1], y_test, s=1)

ax.set_title('PCE predictor')
Expand Down
6 changes: 3 additions & 3 deletions docs/code/surrogates/pce/plot_pce_sphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def function(x,y):
f = function(X1_, X2_)

fig = plt.figure(figsize=(10,6))
ax = fig.gca(projection='3d')
ax = fig.add_subplot(projection='3d')
surf = ax.plot_surface(X1_, X2_, f, rstride=1, cstride=1, cmap='gnuplot2', linewidth=0, antialiased=False)
ax.set_title('True function')
ax.set_xlabel('$x_1$', fontsize=15)
Expand All @@ -90,7 +90,7 @@ def function(x,y):
# %%

fig = plt.figure(figsize=(10,6))
ax = fig.gca(projection='3d')
ax = fig.add_subplot(projection='3d')
ax.scatter(x[:,0], x[:,1], y, s=20, c='r')

ax.set_title('Training data')
Expand Down Expand Up @@ -156,7 +156,7 @@ def function(x,y):
# %%

fig = plt.figure(figsize=(10,6))
ax = fig.gca(projection='3d')
ax = fig.add_subplot(projection='3d')
ax.scatter(x_test[:,0], x_test[:,1], y_test, s=1)

ax.set_title('PCE predictor')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class LearningFunction(ABC):
def __init(self, ordered_parameters=None, **kwargs):
self.parameters = kwargs
self.ordered_parameters = (ordered_parameters if not None else tuple(kwargs.keys()))
self.ordered_parameters = (ordered_parameters if ordered_parameters is not None else tuple(kwargs.keys()))
if len(self.ordered_parameters) != len(self.parameters):
raise ValueError("Inconsistent dimensions between order_params tuple and params dictionary.")

Expand Down
65 changes: 34 additions & 31 deletions src/UQpy/transformations/Nataf.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ class Nataf:

@beartype
def __init__(
self,
distributions: Union[Distribution, DistributionList],
samples_x: Union[None, np.ndarray] = None,
samples_z: Union[None, np.ndarray] = None,
jacobian: bool = False,
corr_z: Union[None, np.ndarray] = None,
corr_x: Union[None, np.ndarray] = None,
itam_beta: Union[float, int] = 1.0,
itam_threshold1: Union[float, int] = 0.001,
itam_threshold2: Union[float, int] = 0.1,
itam_max_iter: int = 100,
self,
distributions: Union[Distribution, DistributionList],
samples_x: Union[None, np.ndarray] = None,
samples_z: Union[None, np.ndarray] = None,
jacobian: bool = False,
corr_z: Union[None, np.ndarray] = None,
corr_x: Union[None, np.ndarray] = None,
itam_beta: Union[float, int] = 1.0,
itam_threshold1: Union[float, int] = 0.001,
itam_threshold2: Union[float, int] = 0.1,
itam_max_iter: int = 100,
):
"""
Transform random variables using the Nataf or Inverse Nataf transformation
Expand Down Expand Up @@ -73,7 +73,7 @@ def __init__(
self.dist_object = distributions
self.samples_x: NumpyFloatArray = samples_x
"""Random vector of shape ``(nsamples, n_dimensions)`` with prescribed probability distributions."""
self.samples_z:NumpyFloatArray = samples_z
self.samples_z: NumpyFloatArray = samples_z
"""Standard normal random vector of shape ``(nsamples, n_dimensions)``"""
self.jacobian = jacobian
self.jzx: NumpyFloatArray = None
Expand All @@ -98,17 +98,17 @@ def __init__(
elif all(isinstance(x, Normal) for x in distributions):
self.corr_z = self.corr_x
else:
self.corr_z, self.itam_error1, self.itam_error2 =\
self.corr_z, self.itam_error1, self.itam_error2 = \
self.itam(self.dist_object, self.corr_x, self.itam_max_iter, self.itam_beta,
self.itam_threshold1, self.itam_threshold2,)
self.itam_threshold1, self.itam_threshold2, )
elif corr_z is not None:
self.corr_z = corr_z
if np.all(np.equal(self.corr_z, np.eye(self.n_dimensions))):
self.corr_x = self.corr_z
elif all(isinstance(x, Normal) for x in distributions):
self.corr_x = self.corr_z
else:
self.corr_x = self.distortion_z2x(self.dist_object, self.corr_z)
self.corr_x = self.distortion_z2x(self.dist_object, self.corr_z, n_gauss_points=128)

self.H: NumpyFloatArray = cholesky(self.corr_z, lower=True)
"""The lower triangular matrix resulting from the Cholesky decomposition of the correlation matrix
Expand All @@ -119,10 +119,10 @@ def __init__(

@beartype
def run(
self,
samples_x: Union[None, np.ndarray] = None,
samples_z: Union[None, np.ndarray] = None,
jacobian: bool = False,
self,
samples_x: Union[None, np.ndarray] = None,
samples_z: Union[None, np.ndarray] = None,
jacobian: bool = False,
):
"""
Execute the Nataf transformation or its inverse.
Expand Down Expand Up @@ -160,15 +160,15 @@ def run(

@staticmethod
def itam(
distributions: Union[
DistributionContinuous1D,
JointIndependent,
list[Union[DistributionContinuous1D, JointIndependent]]],
corr_x,
itam_max_iter: int = 100,
itam_beta: Union[float, int] = 1.0,
itam_threshold1: Union[float, int] = 0.001,
itam_threshold2: Union[float, int] = 0.01,
distributions: Union[
DistributionContinuous1D,
JointIndependent,
list[Union[DistributionContinuous1D, JointIndependent]]],
corr_x,
itam_max_iter: int = 100,
itam_beta: Union[float, int] = 1.0,
itam_threshold1: Union[float, int] = 0.001,
itam_threshold2: Union[float, int] = 0.01,
):
"""
Calculate the correlation matrix :math:`\mathbf{C_Z}` of the standard normal random vector
Expand Down Expand Up @@ -236,7 +236,8 @@ def itam(
return corr_z, itam_error1, itam_error2

@staticmethod
def distortion_z2x(distributions: Union[Distribution, list[Distribution]], corr_z: np.ndarray):
def distortion_z2x(distributions: Union[Distribution, list[Distribution]], corr_z: np.ndarray,
n_gauss_points: int = 1024):
"""
This is a method to calculate the correlation matrix :math:`\mathbf{C_x}` of the random vector
:math:`\mathbf{x}` given the correlation matrix :math:`\mathbf{C_z}` of the standard normal random vector
Expand All @@ -248,12 +249,14 @@ def distortion_z2x(distributions: Union[Distribution, list[Distribution]], corr
This method is part of the :class:`.Nataf` class.
:param corr_z: The correlation matrix (:math:`\mathbf{C_z}`) of the standard normal vector **Z** .
Default: The ``identity`` matrix.
:param n_gauss_points: The number of integration points used for the numerical integration of the
correlation matrix (:math:`\mathbf{C_Z}`) of the standard normal random vector **Z**
:return: Distorted correlation matrix (:math:`\mathbf{C_X}`) of the random vector **X**.
"""
logger = logging.getLogger(__name__)
z_max = 8
z_min = -z_max
ng = 128
ng = n_gauss_points

eta, w2d, xi = calculate_gauss_quadrature_2d(ng, z_max, z_min)

Expand All @@ -268,7 +271,7 @@ def distortion_z2x(distributions: Union[Distribution, list[Distribution]], corr
@staticmethod
def calculate_corr_x(corr_x, corr_z, marginals, eta, w2d, xi, is_joint):
if all(hasattr(m, "moments") for m in marginals) and all(
hasattr(m, "icdf") for m in marginals
hasattr(m, "icdf") for m in marginals
):
for i in range(len(marginals)):
i_cdf_i = marginals[i].icdf
Expand Down