Otmorris - sensitivity from imported full factorial design

Hello,

I would like to know if it is possible to import a full factorial DoE with results and run a Morris sensitivity analysis on it. I think it may be, since each point of the grid is evaluated, and the last thing to do is to select n trajectories with k points. I did not fully test it, but after reading the documentation, I don’t think is is possible.
Am I wrong?
Is there any transformation required to create manually an object otmorris.MorrisExperimentGrid().generate() from a full factorial DoE (e.g. to define trajectories)?

1 Like

Hi

It might be possible, but not directly.

Have a look at the following example:

import openturns as ot
import otmorris

# First let us create a full fact DOE (Box)
# To make things easier we do it in dim 2

# The function
f = ot.SymbolicFunction(["x","y"], ["x+2*y"])

levels = [4, 5]
bounds = ot.Interval(2)
x = ot.Box(levels, bounds).generate()
# Response
y = f(x)

# Now we use MorrisExperimentGrid
# We need to increment number of levels by two in each direction
# Indeed OT.Box does it (as number of points per direction is level + 2)
levels_morris = [_ + 2 for _ in levels]
morris_experiment = otmorris.MorrisExperimentGrid(levels_morris, 20)
ot.RandomGenerator.SetSeed(0)
X = morris_experiment.generate()

# Visual validation: make sure that all points belong to the FullFact
import matplotlib.pylab as plt
fig, ax = plt.subplots()
ax.plot(x[:,0], x[:,1], "b.", alpha=0.5, label="Box")
ax.plot(X[:,0], X[:,1], "r.", label="Morris")
ax.legend(loc=0)
fig.show()

# Now for morris it becomes easy
# we create a function from full fact. DOE
fhat = ot.DatabaseFunction(x, y)
Y = fhat(X)

Here is an example of the output (graph):

1 Like

Thank you very much ! A last thing I don’t understand: where are trajectories stored ? Are they, or the order is implicit (e.g. the order in the sample) ?

yes. In dimension d, we need d+1 points to define a trajectory.
In the previous example, we asked 20 trajectories so X is of size 60

We can draw trajectories:

import matplotlib._color_data as mcd
import numpy as np
colors = list(mcd.XKCD_COLORS.values())
selected_colors = np.random.choice(colors, 20)
np.random.seed(1)
fig, ax = plt.subplots()
for k in range(20):
    trajectory = X[k * 3: (k+1)*3]
    for i in range(2):
        x, y = trajectory[i,0], trajectory[i,1]
        dx, dy = trajectory[i+1,0] - x, trajectory[i+1,1] - y
        ax.arrow(x, y, dx, dy, head_width=0.01, head_length=0.01, 
                 head_starts_at_zero=True, length_includes_head=True, 
                 color=selected_colors[k])

1 Like

Perfectly clear, thank you !