.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "tutorial/polar_transform.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end <sphx_glr_download_tutorial_polar_transform.py>` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_tutorial_polar_transform.py: ========================= Polar Transformation ========================= .. GENERATED FROM PYTHON SOURCE LINES 7-17 As another example, if we were interested in transforming Cartesian coordinates to polar form: .. math:: \begin{align} p_r &= \sqrt{x^2 + y^2} \\ p_{\theta} &= \tan^{-1}\left(\frac{y}{x}\right) \end{align} We can implement this with an ``ExplicitSystem`` by declaring the inputs and outputs of this system as follows: .. GENERATED FROM PYTHON SOURCE LINES 17-29 .. code-block:: Python import condor as co from condor.backend import operators as ops class PolarTransform(co.ExplicitSystem): x = input() y = input() output.r = ops.sqrt(x**2 + y**2) #output.theta = ops.atan2(y, x) output.theta = ops.atan(y/x) .. GENERATED FROM PYTHON SOURCE LINES 30-32 In general, once you've defined any system in Condor, you can just evaulate it numerically by passing in numbers: .. GENERATED FROM PYTHON SOURCE LINES 32-36 .. code-block:: Python p = PolarTransform(x=3, y=4) print(p) .. rst-class:: sphx-glr-script-out .. code-block:: none <PolarTransform: x=3, y=4> .. GENERATED FROM PYTHON SOURCE LINES 37-42 The output returned by such a call is designed for inspection to the extent that we recommend working in an interactive session or debugger, especially when getting accustomed to Condor features. For example, the outputs of an explicit system are accessible directly: .. GENERATED FROM PYTHON SOURCE LINES 42-45 .. code-block:: Python print(p.r) .. rst-class:: sphx-glr-script-out .. code-block:: none [5.] .. GENERATED FROM PYTHON SOURCE LINES 46-47 They can also be retrieved collectively: .. GENERATED FROM PYTHON SOURCE LINES 47-50 .. code-block:: Python print(p.output) .. rst-class:: sphx-glr-script-out .. code-block:: none PolartransformOutput(r=array([5.]), theta=array([0.92729522])) .. GENERATED FROM PYTHON SOURCE LINES 51-52 You can of course call it again with different arguments .. GENERATED FROM PYTHON SOURCE LINES 52-56 .. code-block:: Python print(PolarTransform(x=1, y=0).output.asdict()) .. rst-class:: sphx-glr-script-out .. code-block:: none {'r': array([1.]), 'theta': array([0.])} .. GENERATED FROM PYTHON SOURCE LINES 57-72 While the *binding* of the results in a datastructure is nice, the real benefit of constructing condor models is in calling iterative solvers. For example, we could perform symbolic manipulation to define another ``ExplicitSystem`` with :math:`x = r\cos\theta` and :math:`y = r\sin\theta`. Or we can we use Condor to numerically solve this algebraic system of equations using an ``AlgebraicSystem`` by declaring the input radius and angle as ``parameter``\s and the solving variables for :math:`x` and :math:`y`. Mathematically, we are defining the system of algebraic equations .. math:: r &= p_r (x^*, y^*) \\ \theta &= p_{\theta} (x^*, y^*) and letting an iterative solver find the solution :math:`x^*,y^*` satisfying both residual equations given parameters :math:`r` and :math:`\theta`. In Condor, .. GENERATED FROM PYTHON SOURCE LINES 72-93 .. code-block:: Python class CartesianTransform(co.AlgebraicSystem): # r and theta are input parameters r = parameter() theta = parameter() # solver will vary x and y to satisfy the residuals x = variable(initializer=1) y = variable(initializer=0) # get r, theta from solver's x, y p = PolarTransform(x=x, y=y) # residuals to converge to 0 residual(r == p.r) residual(theta == p.theta) out = CartesianTransform(r=1, theta=ops.pi / 4) print(out.x, out.y) .. rst-class:: sphx-glr-script-out .. code-block:: none [0.70710678] [0.70710678] .. GENERATED FROM PYTHON SOURCE LINES 94-100 Note also that passing the inputs (or any intermediates) to plain numeric functions that can handle symbolic objects as well as pure numerical objects (float or numpy arrays) could work for this simple example. However, since we *embedded* the ``PolarTransform`` model in this solver, the system evaluated with the solved variable values is directly accessible if the ``bind_embedded_models`` option is ``True`` (which it is by default), as in: .. GENERATED FROM PYTHON SOURCE LINES 100-104 .. code-block:: Python print(out.p.output) .. rst-class:: sphx-glr-script-out .. code-block:: none PolartransformOutput(r=array([1.]), theta=array([0.78539816])) .. GENERATED FROM PYTHON SOURCE LINES 105-110 Note that this has multiple solutions due to the form of the algebraic relationship of the polar/rectangular transformation. The :class:`AlgebraicSystem` uses Newton's method as the solver, so the solution that is found depends on the initial conditions. The :attr:`initializer` attribute on the :attr:`variable` field determines the initial position. For example, .. GENERATED FROM PYTHON SOURCE LINES 110-116 .. code-block:: Python CartesianTransform.set_initial(x=-1, y=-1) out = CartesianTransform(r=1, theta=ops.pi / 4) print(out.variable) .. rst-class:: sphx-glr-script-out .. code-block:: none CartesiantransformVariable(x=array([-0.70710678]), y=array([-0.70710678])) .. GENERATED FROM PYTHON SOURCE LINES 117-119 An additional :attr:`warm_start` attribute determines whether the initializer is over-wrriten. Since the default is true, we can inspect the initializer values, .. GENERATED FROM PYTHON SOURCE LINES 119-122 .. code-block:: Python print(CartesianTransform.x.initializer, CartesianTransform.y.initializer) .. rst-class:: sphx-glr-script-out .. code-block:: none [-0.70710678] [-0.70710678] .. GENERATED FROM PYTHON SOURCE LINES 123-124 and re-solve with attr:`warm_start` False .. GENERATED FROM PYTHON SOURCE LINES 124-127 .. code-block:: Python CartesianTransform.y.warm_start = False .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.025 seconds) .. _sphx_glr_download_tutorial_polar_transform.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: polar_transform.ipynb <polar_transform.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: polar_transform.py <polar_transform.py>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: polar_transform.zip <polar_transform.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_