Giter VIP home page Giter VIP logo

jannikmi / multivar_horner Goto Github PK

View Code? Open in Web Editor NEW
26.0 1.0 3.0 4.83 MB

python package implementing a multivariate Horner scheme for efficiently evaluating multivariate polynomials

Home Page: https://multivar-horner.readthedocs.io/en/latest/

License: MIT License

Python 94.08% TeX 5.49% Makefile 0.43%
math mathematics polynomials horner-scheme multivariate multivariate-polynomials hornerscheme-solver horner python python3

multivar_horner's Introduction

multivar_horner

Build status

documentation status

image

pre-commit

Total PyPI downloads

latest version on PyPI

JOSS status

image

image

multivar_horner is a python package implementing a multivariate Horner scheme ("Horner's method", "Horner's rule") for efficiently evaluating multivariate polynomials.

Quick Guide:

pip install multivar_horner

For efficiency this package is compiling the instructions required for polynomial evaluation to C by default. If you don't have a C compiler (gcc or cc) installed you also need to install numba for using an alternative method:

pip install multivar_horner[numba]

Simple example:

import numpy as np
from multivar_horner import HornerMultivarPolynomial

# input parameters defining the polynomial
#   p(x) = 5.0 + 1.0 x_1^3 x_2^1 + 2.0 x_1^2 x_3^1 + 3.0 x_1^1 x_2^1 x_3^1
coefficients = np.array([[5.0], [1.0], [2.0], [3.0]], dtype=np.float64)
exponents = np.array([[0, 0, 0], [3, 1, 0], [2, 0, 1], [1, 1, 1]], dtype=np.uint32)

# [#ops=7] p(x) = x_1 (x_1 (x_1 (1.0 x_2) + 2.0 x_3) + 3.0 x_2 x_3) + 5.0
horner_polynomial = HornerMultivarPolynomial(coefficients, exponents)
x = np.array([-2.0, 3.0, 1.0], dtype=np.float64)
p_x = horner_polynomial(x)

Also see:

multivar_horner's People

Contributors

dependabot[bot] avatar dpsanders avatar elcorto avatar jannikmi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

multivar_horner's Issues

export found horner factorisation to codes

Hi, I wonder if there's any way to convert the string representation of a found horner factorisation to codes. To be more specific, I'm looking for some functions similar to 'ccode' in Matlab or 'export' in Mathematica.
For example,
'x_1 (x_1 (x_1 (1.0 x_2) + 2.0 x_3) + 3.0 x_2 x_3) + 5.0' can give me

t1 = x_2 * x_3;
t2 = x_1 * x_2 + 2.0 * x_3;
t3 = x_1 * t2 + 3.0 * t1;
res = x_1 * t3 + 5.0;

which I can compile it in C.

test and bugfix arm architecture support

Under ARM64 this error arises:
OSError: dlopen(/Users/jmichelf/github/multivar_horner/__pycache__/eval_poly_-757448186211189212.so, 0x0006): tried: '/Users/jmichelf/github/multivar_horner/__pycache__/eval_poly_-757448186211189212.so' (mach-o file, but is an incompatible architecture (have (x86_64), need (arm64e)))

Print Horner factorisation with real coefficients

Hi,

I would like to print the whole Horner polynomial with real coefficients (instead of c's).

This should not be too difficult but I am having some troubles dwelling into your code and your well thought but convoluted data structures.

Thank you!

Enable evaluation of multiple inputs at once on a single polynomial

At the moment, I have to evaluate the polynomial one at a time through this library. It is not possible to give multiple inputs at once through a 2D numpy array, and get multiple outputs in return.

Could this perhaps be more easily possible through the numba backend?

Error in running code

I tried to run one example in the documentation page, and it gave me a type error in one of the helper functions:
TypeError("coefficients must be given as numpy.ndarray")

Code below:

import numpy as np

from multivar_horner.multivar_horner import HornerMultivarPolynomial

horner_polynomial = HornerMultivarPolynomial(coefficients, exponents)
coefficients = [5.0, 1.0, 2.0, 3.0]
exponents = [[0, 0, 0], [3, 1, 0], [2, 0, 1], [1, 1, 1]]
horner_polynomial = HornerMultivarPolynomial(
    coefficients, exponents, rectify_input=True
)
horner_polynomial = HornerMultivarPolynomial(coefficients, exponents, keep_tree=True)

Improve Optimal Factorisation Heuristic

Optimal Horner Factorisation A* search:
The current heuristic to estimate the minimal number of required operations (lower bound) is to optimistic. This often causes every possible factorisation to be evaluated. For larger polynomials this makes this algorithm infeasible. -> Make the heuristic more accurate.

Attention: Tradeoff between accuracy of heuristic (how many factorisations are being skipped) and the time required to compute the heuristic for every node (is it cheaper to just try a factorisation?)

minimize numerical error

Optimise the factorisation such that it minimizes the numerical error during evaluation.
take the magnitude of the coefficients... into account during factorization.
The effects of Horner factorizations on the numerical error have been considered in

[3] J. M. Peña and T. Sauer, “On the multivariate Horner scheme”, SIAM journal on numerical analysis, vol. 37, no. 4, pp. 1186–1197, 2000.

[4] J. M. Peña and T. Sauer, “On the multivariate Horner scheme II: Running error analysis”, Computing, vol. 65, no. 4, pp. 313–322, 2000.

add newton method

add the newton raphson method to the implementation.
as sample code in example.py not in code. (<- simple algorithm and often personal adjustments useful for users)

optimise factor evaluation

optimise factor evaluation in order to save instructions ('factor factorisation'):
a monomial factor consists of scalar factors and in turn some monomial factors consist of other monomial factors
-> the result of evaluating a factor can be reused for evaluating other factors containing it
-> find the optimal 'factorisation' of the factors themselves
-> set the factorisation_idxs of each factor in order to link the evaluation appropriately

idea:
choose 'Goedel IDs' as the monomial factor ids
then the id of a monomial is the product of the ids of its scalar factors
find the highest possible divisor among all factor ids
(corresponds to the 'largest' factor included in the monomial)
this leads to a minimal factorisation ('factorisation tree') for evaluating the monomial values quickly

allow multi coefficient polynomials

a user might want to represent and evaluate multiple polynomials (different coefficients) with the same properties.
This is useful e.g. for gradients (= partial derivative polynomial for each dimension)!
add support for 2D coefficient arrays and adjust Numba jit compilation.
then the gradient can be returned as a single polynomial with the same exponents but 2D coefficients or multiple distinct polynomials with smaller exponent matrices.
The naivel canonical polynomial evaluation for 2D coefficient arrays can benefit from reusing intermediary results.
If someone wants to work on this let me know here. I have example code ready for this already.

optimise naive representation

add option to improve naive representation by also compiling a recipe for evaluation.
thereby avoid the unnecessary operations of the matrix representation
factorise monomials (improved evaluation of monomials, reuse value)

recode factorisation in functional paradigm

currently the factorisation progress has been coded in highly unefficient OOP style.
move towards more pythonic functional paradigm
use data classes as containers for the properties
use only functions processing data classes (as input arguments)

improve efficiency of implementation

factorisation is comparatively slow since coded in pure python.
find ways to optimise.
e.g. code time critical factorisation modules in C(++), parallelisation...

optimise space requirement

after building a factorisation tree for the factors themselves (#12)
use its structure to cleverly reuse storage space
-> use compiler construction theory: minimal assembler register assignment, 'graph coloring'...

ModuleNotFound Error on fresh install

In an empty directory, I create a ./venv folder and run the following:
python -m venv .\venv\

I am on Python 3.8.10 on a Windows 10 machine.

I update pip to the latest version with:
python -m pip install --upgrade pip

I am on pip 22.1.2

I then run:
pip install multivar_horner[numba]

Running pip freeze shows the following:

llvmlite==0.38.1
multivar-horner==3.0.0
numba==0.55.2
numpy==1.22.4

I then open up a python command line, and attempt to import the Multivar Polynomial, as shown in the Getting Started docs:

(venv) PS F:\Downloads\HornerTest> python
Python 3.8.10 (tags/v3.8.10:3d8993a, May  3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.

>>> import numpy as np
>>> from multivar_horner.multivar_horner import HornerMultivarPolynomial
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "F:\Downloads\HornerTest\venv\lib\site-packages\multivar_horner\__init__.py", line 2, in <module>
    from multivar_horner.classes.abstract_poly import load_pickle
ModuleNotFoundError: No module named 'multivar_horner.classes'
>>>

Please let me know what I might be doing wrong here!

compute all optimal factorisations

add new function (feature) to compute all optimal horner factorisations of a given polynomial.

The existing A* search has to be adapted to not terminate once the first full factorisation has been found, but instead collect all fully factorized optimal solutions until the next best factorisation in the heap has a higher cost estimate

Attention: do not remove an entire factorisation subtree, but just one realisation each time!

For common polynomials the optimal factorisations can be precomputed and stored. This data can perhaps also be used to learn better heuristics for factorizing more optimally in less time.

JOSS submission: quality of writing

I found a few minor things in the paper that should be improved:

  • The sentence "Representing multivariate polynomials of arbitrary degree also in canonical form, computing derivatives of polynomials and evaluating polynomials at a given point are further features of the package." doesn't read well; the problem is the "also". I would rephrase the entire sentence to something like "In addition, the package allows to/offers..."
  • "can be helpful always when" should instead be "can be helpful whenever". In addition, perhaps I would change the "can be helpful" to "is useful" or so.
  • "The polynomial p is the sum of 5 monomials" There are only four monomials.

This issue is part of the JOSS review (openjournals/joss-reviews#2392).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.