  1666133100

## Sparse multivariate polynomials

This package provides support for working with sparse multivariate polynomials in Julia.

This package is superseded by MultivariatePolynomials.jl and is no longer maintained.

## Installation

In the Julia REPL run

``````Pkg.add("MultiPoly")
``````

## The MPoly type

Multivariate polynomials are stored in the type

``````struct MPoly{T}
terms::OrderedDict{Vector{Int},T}
vars::Vector{Symbol}
end
``````

Here each item in the dictionary `terms` corresponds to a term in the polynomial, where the key represents the monomial powers and the value the coefficient of the monomial. Each of the keys in `terms` should be a vector of integers whose length equals `length(vars)`.

## Constructing polynomials

For constructing polynomials you can use the generators of the polynomial ring:

``````julia> using MultiPoly

julia> x, y = generators(MPoly{Float64}, :x, :y);

julia> p = (x+y)^3
MultiPoly.MPoly{Float64}(x^3 + 3.0x^2*y + 3.0x*y^2 + y^3)
``````

For the zero and constant one polynomials use

``````zero(MPoly{Float64})
one(MPoly{Float64})
``````

where you can optionally supply the variables of the polynomials with `vars = [:x, :y]`.

Alternatively you can construct a polynomial using a dictionary for the terms:

``````MPoly{Float64}(terms, vars)
``````

For example, to construct the polynomial `1 + x^2 + 2x*y^3` use

``````julia> using MultiPoly, DataStructures

julia> MPoly{Float64}(OrderedDict([0,0] => 1.0, [2,0] => 1.0, [1,3] => 2.0), [:x, :y])
MultiPoly.MPoly{Float64}(1.0 + x^2 + 2.0x*y^3)
``````

Laurent polynomials may be constructed too:

``````x^1 * y^2 + x^1 * y^(-2) + x^(-1) * y^2 + x^(-1) * y^(-2)
``````

## Polynomial arithmetic

The usual ring arithmetic is supported and MutliPoly will automatically deal with polynomials in different variables or having a different coefficient type. Examples:

``````julia> using MultiPoly

julia> x, y = generators(MPoly{Float64}, :x, :y);

julia> z = generator(MPoly{Int}, :z)
MPoly{Int64}(z)

julia> x+z
MPoly{Float64}(x + z)

julia> vars(x+z)
3-element Array{Symbol,1}:
:x
:y
:z
``````

## Evaluating a polynomial

To evaluate a polynomial P(x,y, ...) at a point (x0, y0, ...) the `evaluate` function is used. Example:

``````julia> p = (x+x*y)^2
MultiPoly.MPoly{Float64}(x^2 + 2.0x^2*y + x^2*y^2)

julia> evaluate(p, 3.0, 2.0)
81.0
``````

## Calculus

MultiPoly supports integration and differentiation. Currently the integrating constant is set to 0. Examples:

``````julia> p = x^4 + y^4
MultiPoly.MPoly{Float64}(x^4 + y^4)

julia> diff(p, :x)
MultiPoly.MPoly{Float64}(4.0x^3)

julia> diff(p, :y, 3)
MultiPoly.MPoly{Float64}(24.0y)

julia> integrate(p, :x, 2)
MultiPoly.MPoly{Float64}(0.03333333333333333x^6 + 0.5x^2*y^4)
``````

Integrations which would involve integrating a term with a -1 power raise an error. This example can be intergrated once, but not twice, in `:x` and can't be integrated in `:y`:

``````julia> q = x^(-2) * y^(-1);
julia> integrate(q, :y)
ERROR: ArgumentError: can't integrate 1 times in y as it would involve a -1 power requiring a log term``````

Author: Daviddelaat
Source Code: https://github.com/daviddelaat/MultiPoly.jl  1666121220

## FixedPolynomials

FixedPolynomials.jl is a library for really fast evaluation of multivariate polynomials. Here are the latest benchmark results.

Since `FixedPolynomials` polynomials are optimised for fast evaluation they are not suited for construction of polynomials. It is recommended to construct a polynomial with an implementation of MultivariatePolynomials.jl, e.g. DynamicPolynomials.jl, and to convert it then into a `FixedPolynomials.Polynomial` for further computations.

## Getting started

Here is an example on how to create a `Polynomial` with `Float64` coefficients:

``````using FixedPolynomials
import DynamicPolynomials: @polyvar

@polyvar x y z

f = Polynomial{Float64}(x^2+y^3*z-2x*y)
``````

To evaluate `f` you simply have to pass in a `Vector{Float64}`

``````x = rand(3)
f(x) # alternatively evaluate(f, x)
``````

But this is not the fastest way possible. In order to achieve the best performance we need to precompute some things and also preallocate intermediate storage. For this we have `GradientConfig` and `JacobianConfig`. For single polynomial the API is as follows

``````cfg = GradientConfig(f) # this can be reused!
f(x) == evaluate(f, x, cfg)
# We can also compute the gradient of f at x
map(g -> g(x), ∇f) == gradient(f, x, cfg)
``````

We also have support for systems of polynomials:

``````cfg = JacobianConfig([f, f]) # this can be reused!
[f(x), f(x)] == evaluate([f, f] x, cfg)
# We can also compute the jacobian of [f, f] at x
jacobian(f, x, cfg)``````

Author: JuliaAlgebra
Source Code: https://github.com/JuliaAlgebra/FixedPolynomials.jl  1638933629

## The Line Integral | A Visual Introduction for Beginners

This video gives a brief introduction to the line integral. I talk about line integrals over scalar fields and line integrals over vector fields along with a few sample problems.

A line integral (sometimes called a path integral) is the integral of some function along a curve. One can integrate a scalar-valued function along a curve, obtaining for example, the mass of a wire from its density. One can also integrate a certain type of vector-valued functions along a curve. These vector-valued functions are the ones where the input and output dimensions are the same, and we usually represent them as vector fields.

3D Plotters(by far the best): https://www.math3d.org/

This video was animated using manim: https://github.com/3b1b/manim
Source code for the animations: https://github.com/vivek3141/videos 