<jupyter_start><jupyter_text>Defining Partial Derivatives on Implicit ComponentsFor [ImplicitComponent](../../features/core_features/working_with_components/implicit_component.ipynb) instances, you will provide partial derivatives of **residuals with respect to inputs and outputs**. Note that this is slightly different than what you do for [ExplicitComponent instances](partial_derivs_explicit.ipynb), but the general procedure is similar:1. Declare the partial derivatives via `declare_partials`.2. Specify their values via `linearize`.Residual values are computed in the `apply_nonlinear` method, so those equations are the ones you will differentiate. For the sake of complete clarity, if your `ImplicitComponent` does happen to define a `solve_nonlinear` method, then you will still provide derivatives of the `apply_nonlinear` method to OpenMDAO.Here is a simple example to consider:<jupyter_code>class QuadraticComp(om.ImplicitComponent):
    """
    A Simple Implicit Component representing a Quadratic Equation.

    R(a, b, c, x) = ax^2 + bx + c

    Solution via Quadratic Formula:
    x = (-b + sqrt(b^2 - 4ac)) / 2a
    """

    def setup(self):
        self.add_input('a', val=1.)
        self.add_input('b', val=1.)
        self.add_input('c', val=1.)
        self.add_output('x', val=0.)

    def setup_partials(self):
        self.declare_partials(of='x', wrt='*')

    def apply_nonlinear(self, inputs, outputs, residuals):
        a = inputs['a']
        b = inputs['b']
        c = inputs['c']
        x = outputs['x']
        residuals['x'] = a * x ** 2 + b * x + c

    def solve_nonlinear(self, inputs, outputs):
        a = inputs['a']
        b = inputs['b']
        c = inputs['c']
        outputs['x'] = (-b + (b ** 2 - 4 * a * c) ** 0.5) / (2 * a)

    def linearize(self, inputs, outputs, partials):
        a = inputs['a']
        b = inputs['b']
        c = inputs['c']
        x = outputs['x']

        partials['x', 'a'] = x ** 2
        partials['x', 'b'] = x
        partials['x', 'c'] = 1.0
        partials['x', 'x'] = 2 * a * x + b

        self.inv_jac = 1.0 / (2 * a * x + b)<jupyter_output><empty_output><jupyter_text>In this component, `x` is an output, and you take derivatives with respect to it. This might seem a bit strange to you if you're used to thinking about things from an [ExplicitComponent](partial_derivs_explicit.ipynb) perspective. But for implicit components it is necessary, because the values of those outputs are determined by a solver, like [NewtonSolver](../../features/building_blocks/solvers/newton.ipynb), which will need to know those derivatives. They are also necessary for the total derivative computations across the whole model. So if your residual is a function of one or more of the component outputs, make sure you provide those partials to OpenMDAO. Check That Your Derivatives Are Correct!<jupyter_code>from openmdao.test_suite.components.quad_implicit import QuadraticComp

p = om.Problem()

p.model.add_subsystem('quad', QuadraticComp())

p.setup()

p.check_partials(compact_print=True);<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11555842479018721, 'fraction_numerical': 0.007424144609425436, 'mean_word_length': 3.5573529411764704, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '93973', 'license': 'Apache-2.0', 'n_tokens_mistral': 968, 'n_tokens_neox': 926, 'n_words': 326, 'path': 'openmdao/docs/openmdao_book/advanced_user_guide/analytic_derivatives/partial_derivs_implicit.ipynb', 'repo_name': 'sebasgo/OpenMDAO', 'size': '3098'}