I am trying to learn a bit more about uncertainty propagation. I was given the following equation:
Z(X,Y) = X cos(bY) + c cos(bY)^2 + d cos(bY) + e
where X and Y are random variables defined in [0, 20] and [0, 2π], respectively. b, c, d and e are fixed parameters. Disregarding the covariance and expanding the derivatives for the uncertainty propagation, I obtained:
ΔZ = ((ΔX cos(bY))^2 + ΔY^{2}(-X b sin(bY) - 2bc sin (bY)cos(bY) - bd sin(bY))^{2})^{1/2}
Considering: b, c, d and e = 1.00227229, 5.65590608, 8.88519144, 1.27034426 for X = 12, how can I maximize ΔX and ΔY for the given X, and Y at f.ex. π/2), in order that ΔZ <= 2?
Further relations:
σY = α/K^β, where K = X/ΔX, with α and β = 2.57061306, 1.3422771.
X = κ/P^ω, where P = ΔY/ΔX, with κ and ω = 2.95784715, 0.54292534.
ΔY < π/6 for X/ΔX > 5
ΔY <= π
ΔX <= 6
This is my approach to the problem:
import numpy as np
from scipy.optimize import minimize
# Define constants
b_val = 1.00227229
c_val = 5.65590608
d_val = 8.88519144
e_val = 1.27034426
alpha = 2.57061306
beta = 1.3422771
kappa = 2.95784715
omega = 0.54292534
phi = 4.48318522
psi = 0.2592947
# Set the given X value
X_val = 12
# Define the function Z and its partial derivatives
def Z_func(X, Y):
return X * np.cos(b_val * Y) + c_val * np.cos(b_val * Y)**2 + d_val * np.cos(b_val * Y) + e_val
def dZ_dX_func(X, Y):
return np.cos(b_val * Y)
def dZ_dY_func(X, Y):
return -X * b_val * np.sin(b_val * Y) - 2 * c_val * b_val * np.sin(b_val * Y) * np.cos(b_val * Y) - d_val * b_val * np.sin(b_val * Y)
# Define the constraint function
def delta_z_constraint(vars, X, Y):
Delta_X, Delta_Y = vars
Delta_Z = np.sqrt((dZ_dX_func(X, Y) * Delta_X)**2 + (dZ_dY_func(X, Y) * Delta_Y)**2)
return 2 - Delta_Z # Ensure Delta_Z is less than or equal to 2
def alpha_beta_constraint(vars):
Delta_X, Delta_Y = vars
K = X_val / Delta_X
return Delta_Y - alpha / K**beta
def kappa_omega_constraint(vars):
Delta_X, Delta_Y = vars
P = Delta_Y / Delta_X
W = kappa / P**omega
return W
def phi_psi_constraint(vars):
Delta_X, Delta_Y = vars
P = Delta_Y / Delta_X
W = kappa / P**omega
R = W / Delta_Y
Delta_Z = np.sqrt((dZ_dX_func(X_val, Y_val) * Delta_X)**2 + (dZ_dY_func(X_val, Y_val) * Delta_Y)**2)
return phi / R**psi - Delta_Z
def additional_constraints(initial_guess):
Delta_X, Delta_Y = initial_guess
def constraint1(vars):
Delta_X, _ = vars
return Delta_X - 6
def constraint2(vars):
_, Delta_Y = vars
return np.pi - Delta_Y
def constraint3(vars):
Delta_X, _ = vars
return 5 - Delta_X
def constraint4(vars):
Delta_X, Delta_Y = vars
if X_val / Delta_X > 5:
return np.pi - Delta_Y
else:
return np.pi / 6 - Delta_Y
return [constraint1, constraint2, constraint3, constraint4]
# Set initial guess for Delta_X and Delta_Y
initial_guess = [.05, 0.1]
# Set bounds for Delta_X and Delta_Y
bounds = [(.1,5), (np.deg2rad(0.1), np.pi/6)]
# Define the range of angles
angles = [0,90, 180]
# Loop over the angles
for angle in angles:
# Set the angle value
Y_val = np.radians(angle)
# Define the constraint dictionaries for the optimizer
constraints = [
{'type': 'ineq', 'fun': delta_z_constraint, 'args': (X_val, Y_val)},
{'type': 'ineq', 'fun': alpha_beta_constraint},
{'type': 'ineq', 'fun': phi_psi_constraint}
]
# Perform optimization for the current angle
result = minimize(lambda x: -np.sum(x), initial_guess, bounds=bounds, constraints=constraints)
# Check if the optimization was successful
if result.success:
max_Delta_X, max_Delta_Y = result.x
print(f"Angle: {angle} degrees")
print("Maximum Delta_X:", max_Delta_X)
print("Maximum Delta_Y:", np.rad2deg(max_Delta_Y))
else:
print(f"Angle: {angle} degrees - Optimization failed")
I am struggling to add ‘additional_constraints’ to my problem. Further suggestions around the topic are welcome.