ortho 0.4.1
Generate orthogonal set of functions
Requires Python: >=3.9
Keywords: orthogonal-functions regression sympy computer-algebragram-schmidt

=====
ortho
=====

.. |image01| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/phi_i_perp.svg
.. |image02| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/phi_i.svg
.. |image03| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/interval.svg
.. |image04| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/w.svg
.. |image05| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/delta.svg
.. |image06| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/i_0.svg
.. |image07| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/n.svg
.. |image08| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/L.svg
.. |image09| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/alpha_i.svg
.. |image10| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/a_ij.svg
.. |image11| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/Equation_phi_i.svg
.. |image12| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/Equation_phi_i_perp.svg
.. |image13| image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/Equation_orthogonality.svg

.. include_after_this_line

A python package to generate a set of orthogonal functions.

* `Documentation <https://ameli.github.io/ortho/index.html>`__
* `API Reference <https://ameli.github.io/ortho/api.html>`__
* `Github <https://ameli.github.io/ortho>`__

-----------
Description
-----------

This package generates a set of orthonormal functions, called |image01|, based on the set of non-orthonormal functions |image02| defined by the inverse-monomials

|image11|

The orthonormalized functions |image01| are the linear combination of the functions |image02| by

|image12|

The functions |image01| are orthonormal in the interval |image03| with respect to the weight function |image04|. That is,

|image13|

where |image05| is the Kronecker delta function. The orthogonal functions are generated by `Gram-Schmidt orthogonalization process <https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process>`__. This script produces the symbolic functions using `Sympy <https://www.sympy.org>`__, a Python computer algebraic package. An application of these orthogonal functions can be found in [1]_.

---------------------
Build and Test Status
---------------------

|codecov-devel| 

.. |y| unicode:: U+2714
.. |n| unicode:: U+2716

+----------+----------+-------+-------+-------+-------+-----------------+
| Platform | Arch     | Python Version                | Continuous      |
+          |          +-------+-------+-------+-------+ Integration     +
|          |          |  3.9  |  3.10 |  3.11 |  3.12 |                 |
+==========+==========+=======+=======+=======+=======+=================+
| Linux    | X86-64   |  |y|  |  |y|  |  |y|  |  |y|  | |build-linux|   |
+          +----------+-------+-------+-------+-------+                 +
|          | AARCH-64 |  |y|  |  |y|  |  |y|  |  |y|  |                 |
+----------+----------+-------+-------+-------+-------+-----------------+
| macOS    | X86-64   |  |y|  |  |y|  |  |y|  |  |y|  | |build-macos|   |
+          +----------+-------+-------+-------+-------+                 +
|          | ARM-64   |  |y|  |  |y|  |  |y|  |  |y|  |                 |
+----------+----------+-------+-------+-------+-------+-----------------+
| Windows  | X86-64   |  |y|  |  |y|  |  |y|  |  |y|  | |build-windows| |
+          +----------+-------+-------+-------+-------+                 +
|          | ARM-64   |  |y|  |  |y|  |  |y|  |  |y|  |                 |
+----------+----------+-------+-------+-------+-------+-----------------+

.. |build-linux| image:: https://img.shields.io/github/actions/workflow/status/ameli/ortho/build-linux.yml
   :target: https://github.com/ameli/ortho/actions?query=workflow%3Abuild-linux 
.. |build-macos| image:: https://img.shields.io/github/actions/workflow/status/ameli/ortho/build-macos.yml
   :target: https://github.com/ameli/ortho/actions?query=workflow%3Abuild-macos
.. |build-windows| image:: https://img.shields.io/github/actions/workflow/status/ameli/ortho/build-windows.yml
   :target: https://github.com/ameli/ortho/actions?query=workflow%3Abuild-windows

-------
Install
-------

Install using either of the following three methods.

~~~~~~~~~~~~~~~~~~~~
1. Install from PyPi
~~~~~~~~~~~~~~~~~~~~

|pypi| |pyversions| |format| 

Install using the package available on `PyPi <https://pypi.org/project/ortho>`__ by

::

  pip install ortho

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2. Install from Anaconda Cloud
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

|conda-version| |conda-platform|

Install using `Anaconda cloud <https://anaconda.org/s-ameli/traceinv>`__ by

::

    conda install -c s-ameli ortho

~~~~~~~~~~~~~~~~~~~~~~~~~~~
3. Install from Source Code
~~~~~~~~~~~~~~~~~~~~~~~~~~~

|release| |licence| |implementation|

Install directly from the source code by

::

  git clone https://github.com/ameli/ortho.git
  cd ortho
  pip install .

-------
Testing
-------

To test the package, download the source code and use one of the following methods in the directory of the source code:

- *Method 1*: test locally by:

  ::
      
      python setup.py test

- *Method 2*: test in a virtual environment using ``tox``:

  ::

      pip install tox
      tox

-----
Usage
-----

The package can be used in two ways:

~~~~~~~~~~~~~~~~~~~~~
1. Import as a Module
~~~~~~~~~~~~~~~~~~~~~

.. code-block:: python

    >>> from ortho import OrthogonalFunctions
    
    >>> # Generate object of orthogonal functions
    >>> OF = OrthogonalFunctions(
    ...        start_index=1,
    ...        num_func=9,
    ...        end_interval=1,
    ...        verbose=True)
    
    >>> # Get numeric coefficients alpha[i] and a[i][j]
    >>> alpha = OF.alpha
    >>> a = OF.coeffs

    >>> # Get symbolic coefficients alpha[i] and a[i][j]
    >>> sym_alpha = OF.sym_alpha
    >>> sym_a = OF.sym_coeffs

    >>> # Get symbolic functions phi[i]
    >>> sym_phi = OF.sym_phi
    
    >>> # Print Functions
    >>> OF.print()
    
    >>> # Check mutual orthogonality of Functions
    >>> status = OF.check(verbose=True)
    
    >>> # Plot Functions
    >>> OF.plot()

The parameters are:

- ``start_index``: the index of the starting function, |image06|. Default is ``1``.
- ``num_func``: number of orthogonal functions to generate, |image07|. Default is ``9``.
- ``end_interval``: the right interval of orthogonality, |image08|. Default is ``1``.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2. Use As Standalone Application
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The standalone application can be executed in the terminal in two ways:

#. If you have installed the package, call ``ortho`` executable in terminal:

   ::

       ortho [options]

   The optional argument ``[options]`` will be explained in the next section. When the package *ortho* is installed, the executable ``ortho`` is located in the ``/bin`` directory of the python.

#. Without installing the package, the main script of the package can be executed directly from the source code by

   ::

       # Download the package
       git clone https://github.com/ameli/ortho.git

       # Go to the package source directory
       cd ortho

       # Execute the main script of the package
       python -m ortho [options]

~~~~~~~~~~~~~~~~~~
Optional arguments
~~~~~~~~~~~~~~~~~~

When the *standalone application* (the second method in the above) is called, the executable accepts some optional arguments as follows.

+--------------------------------------+------------------------------------------------------------------------------------------+
| Option                               | Description                                                                              |
+======================================+==========================================================================================+
| ``-h``, ``--help``                   | Prints a help message.                                                                   |
+--------------------------------------+------------------------------------------------------------------------------------------+
| ``-v``, ``--version``                | Prints version.                                                                          |
+--------------------------------------+------------------------------------------------------------------------------------------+
| ``-l``, ``--license``                | Prints author info, citation and license.                                                |
+--------------------------------------+------------------------------------------------------------------------------------------+
| ``-n``, ``--num-func[=int]``         | Number of orthogonal functions to generate. Positive integer. Default is 9.              |
+--------------------------------------+------------------------------------------------------------------------------------------+
| ``-s``, ``--start-func[=int]``       | Starting function index. Non-negative integer. Default is 1.                             |
+--------------------------------------+------------------------------------------------------------------------------------------+
| ``-e``, ``--end-interval[=float]``   | End of the interval of functions domains. A real number greater than zero. Default is 1. |
+--------------------------------------+------------------------------------------------------------------------------------------+
| ``-c``,\ ``--check``                 | Checks orthogonality of generated functions.                                             |
+--------------------------------------+------------------------------------------------------------------------------------------+
| ``-p``, ``--plot``                   | Plots generated functions, also saves the plot as pdf file in the current directory.     |
+--------------------------------------+------------------------------------------------------------------------------------------+

~~~~~~~~~~
Parameters
~~~~~~~~~~

The variables |image06|, |image07|, and |image08| can be set in the script by the following arguments,

+-------------+----------------------+---------------------------------+
| Variable    | Variable in script   | Option                          |
+=============+======================+=================================+
| |image06|   | ``start_index``      | ``-s``, or ``--start-func``     |
+-------------+----------------------+---------------------------------+
| |image07|   | ``num_func``         | ``-n``, or ``--num-func``       |
+-------------+----------------------+---------------------------------+
| |image08|   | ``end_interval``     | ``-e``, or ``--end-interval``   |
+-------------+----------------------+---------------------------------+

~~~~~~~~
Examples
~~~~~~~~

#. Generate nine orthogonal functions from index 1 to 9 (defaults)

   ::

        ortho

#. Generate eight orthogonal functions from index 1 to 8

   ::

        ortho -n 8

#. Generate nine orthogonal functions from index 0 to 8

   ::

        ortho -s 0

#. Generate nine orthogonal functions that are orthonormal in the interval [0,10]

   ::

        ortho -e 10

#. Check orthogonality of each two functions, plot the orthonormal functions and save the plot to pdf

   ::

        ortho -c -p

#. A complete example:

   ::

        ortho -n 9 -s 1 -e 1 -c -p

------
Output
------

-  Displays the orthogonal functions as computer algebraic symbolic functions. An example a set of generated functions is shown below.

::

    phi_1(t) =  sqrt(x)
    phi_2(t) =  sqrt(6)*(5*x**(1/3) - 6*sqrt(x))/3
    phi_3(t) =  sqrt(2)*(21*x**(1/4) - 40*x**(1/3) + 20*sqrt(x))/2
    phi_4(t) =  sqrt(10)*(84*x**(1/5) - 210*x**(1/4) + 175*x**(1/3) - 50*sqrt(x))/5
    phi_5(t) =  sqrt(3)*(330*x**(1/6) - 1008*x**(1/5) + 1134*x**(1/4) - 560*x**(1/3) + 105*sqrt(x))/3
    phi_6(t) =  sqrt(14)*(1287*x**(1/7) - 4620*x**(1/6) + 6468*x**(1/5) - 4410*x**(1/4) + 1470*x**(1/3) - 196*sqrt(x))/7
    phi_7(t) =  5005*x**(1/8)/2 - 10296*x**(1/7) + 17160*x**(1/6) - 14784*x**(1/5) + 6930*x**(1/4) - 1680*x**(1/3) + 168*sqrt(x)
    phi_8(t) =  sqrt(2)*(19448*x**(1/9) - 90090*x**(1/8) + 173745*x**(1/7) - 180180*x**(1/6) + 108108*x**(1/5) - 37422*x**(1/4) + 6930*x**(1/3) - 540*sqrt(x))/3
    phi_9(t) =  sqrt(5)*(75582*x**(1/10) - 388960*x**(1/9) + 850850*x**(1/8) - 1029600*x**(1/7) + 750750*x**(1/6) - 336336*x**(1/5) + 90090*x**(1/4) - 13200*x**(1/3) + 825*sqrt(x))/5

-  Displays readable coefficients, |image09| and |image10| of the functions. For instance,

::

      i      alpha_i                                    a_[ij]
    ------  ----------   -----------------------------------------------------------------------
    i = 1:  +sqrt(2/2)   [1                                                                    ]
    i = 2:  -sqrt(2/3)   [6,   -5                                                              ]
    i = 3:  +sqrt(2/4)   [20,  -40,    21                                                      ]
    i = 4:  -sqrt(2/5)   [50,  -175,   210,   -84                                              ]
    i = 5:  +sqrt(2/6)   [105, -560,   1134,  -1008,   330                                     ]
    i = 6:  -sqrt(2/7)   [196, -1470,  4410,  -6468,   4620,   -1287                           ]
    i = 7:  +sqrt(2/8)   [336, -3360,  13860, -29568,  34320,  -20592,   5005                  ]
    i = 8:  -sqrt(2/9)   [540, -6930,  37422, -108108, 180180, -173745,  90090,  -19448        ]
    i = 9:  +sqrt(2/10)  [825, -13200, 90090, -336336, 750750, -1029600, 850850, -388960, 75582]

-  Displays the matrix of the mutual inner product of functions to check orthogonality (using option ``-c``). An example of the generated matrix of the mutual inner product of functions is shown below.

::

    [[1 0 0 0 0 0 0 0 0]
     [0 1 0 0 0 0 0 0 0]
     [0 0 1 0 0 0 0 0 0]
     [0 0 0 1 0 0 0 0 0]
     [0 0 0 0 1 0 0 0 0]
     [0 0 0 0 0 1 0 0 0]
     [0 0 0 0 0 0 1 0 0]
     [0 0 0 0 0 0 0 1 0]
     [0 0 0 0 0 0 0 0 1]]

-  Plots the set of functions (using option ``-p``) and saves the plot in the current directory. An example of a generated plot is shown below.

.. image:: https://raw.githubusercontent.com/ameli/ortho/main/docs/source/images/orthogonal_functions.svg
    :align: center

--------
Citation
--------

.. [1] Ameli, S., and Shadden. S. C. (2022). Interpolating Log-Determinant and Trace of the Powers of Matrix **A** + t **B**. *Statistics and Computing* 32, 108. |paper-doi| |paper-arxiv|
.. [2] Ameli, S. (2022). ameli/ortho: (v0.2.0). Zenodo. |code-doi|

.. |travis-devel| image:: https://img.shields.io/travis/com/ameli/ortho
   :target: https://travis-ci.com/github/ameli/ortho
.. |codecov-devel| image:: https://img.shields.io/codecov/c/github/ameli/ortho
   :target: https://codecov.io/gh/ameli/ortho
.. |licence| image:: https://img.shields.io/github/license/ameli/ortho
   :target: https://opensource.org/licenses/BSD-3-Clause
.. |travis-devel-linux| image:: https://img.shields.io/travis/com/ameli/ortho?env=BADGE=linux&label=build&branch=main
   :target: https://travis-ci.com/github/ameli/ortho
.. |travis-devel-osx| image:: https://img.shields.io/travis/com/ameli/ortho?env=BADGE=osx&label=build&branch=main
   :target: https://travis-ci.com/github/ameli/ortho
.. |travis-devel-windows| image:: https://img.shields.io/travis/com/ameli/ortho?env=BADGE=windows&label=build&branch=main
   :target: https://travis-ci.com/github/ameli/ortho
.. |implementation| image:: https://img.shields.io/pypi/implementation/ortho
.. |pyversions| image:: https://img.shields.io/pypi/pyversions/ortho
.. |format| image:: https://img.shields.io/pypi/format/ortho
.. |pypi| image:: https://img.shields.io/pypi/v/ortho
.. |conda| image:: https://anaconda.org/s-ameli/ortho/badges/installer/conda.svg
   :target: https://anaconda.org/s-ameli/ortho
.. |platforms| image:: https://img.shields.io/conda/pn/s-ameli/ortho?color=orange?label=platforms
   :target: https://anaconda.org/s-ameli/ortho
.. |conda-version| image:: https://img.shields.io/conda/v/s-ameli/ortho
   :target: https://anaconda.org/s-ameli/ortho
.. |release| image:: https://img.shields.io/github/v/tag/ameli/ortho
   :target: https://github.com/ameli/ortho/releases/
.. |conda-platform| image:: https://anaconda.org/s-ameli/ortho/badges/platforms.svg
   :target: https://anaconda.org/s-ameli/ortho
.. |code-doi| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.6395268.svg
   :target: https://doi.org/10.5281/zenodo.6395268
.. |paper-doi| image:: https://img.shields.io/badge/doi-10.1007%2Fs11222--022--10173--4-green
   :target: https://doi.org/10.1007/s11222-022-10173-4
.. |paper-arxiv| image:: https://img.shields.io/badge/arXiv-2009.07385 [math.NA]-%23B31B1B
   :target: https://doi.org/10.48550/arXiv.2009.07385