Compute the Jacobian of a discipline analytically

In this example, we will compute the Jacobians of some outputs of a MDODiscipline with respect to some inputs, based on its analytical derivatives.

from __future__ import annotations

from gemseo.disciplines.analytic import AnalyticDiscipline
from numpy import array

First, we create a discipline, e.g. an AnalyticDiscipline:

discipline = AnalyticDiscipline({"y": "a**2+b", "z": "a**3+b**2"})

We can execute it with its default input values:

discipline.execute()
print(discipline.local_data)
{'a': array([0.]), 'b': array([0.]), 'z': array([0.]), 'y': array([0.])}

or with custom ones:

discipline.execute({"a": array([1.0])})
print(discipline.local_data)
{'a': array([1.]), 'b': array([0.]), 'z': array([1.]), 'y': array([1.])}

Then, we use the method MDODiscipline.linearize() to compute the derivatives:

jacobian_data = discipline.linearize()
print(jacobian_data)
{}

There is no Jacobian data because we need to set the input variables against which to compute the Jacobian of the output ones. For that, we use the method add_differentiated_inputs(). We also need to set these output variables: with the method add_differentiated_outputs(). For instance, we may want to only compute the derivative of "z" with respect to "a":

discipline.add_differentiated_inputs(["a"])
discipline.add_differentiated_outputs(["z"])
jacobian_data = discipline.linearize()
print(jacobian_data)
defaultdict(<function default_dict_factory at 0x7fea8aa525e0>, {'z': defaultdict(None, {'a': array([[0.]])})})

By default, GEMSEO uses MDODiscipline.default_inputs as input data for which to compute the Jacobian on. We can change them with input_data:

jacobian_data = discipline.linearize(input_data={"a": array([1.0])})
print(jacobian_data)
defaultdict(<function default_dict_factory at 0x7fea8aa525e0>, {'z': defaultdict(None, {'a': array([[3.]])})})

We can also force the discipline to compute the derivatives of all the outputs with respect to all the inputs:

jacobian_data = discipline.linearize(compute_all_jacobians=True)
print(jacobian_data)
defaultdict(<function default_dict_factory at 0x7fea8aa525e0>, {'y': defaultdict(None, {'a': array([[0.]]), 'b': array([[1.]])}), 'z': defaultdict(None, {'a': array([[0.]]), 'b': array([[0.]])})})

Total running time of the script: ( 0 minutes 0.026 seconds)

Gallery generated by Sphinx-Gallery