LinearCombinations.jl

A Julia package to work with formal linear combinations
Author matthias314
Popularity
2 Stars
Updated Last
3 Months Ago
Started In
November 2023

LinearCombinations.jl

This Julia package allows to work with formal linear combinations and linear maps. Multilinear maps and tensors are also supported. The terms appearing in a linear combination can be of any type, and coefficients can be in any commutative ring with unit. The overall aim of the package is to provide functions that are efficient and easy to use.

The package comes with an extensive documentation.

Examples

For simplicity we use Char and String as term types and integers, rationals or floating-point numbers as coefficients.

We start with some linear combinations. They are of type Linear, which can store any number of term-coefficient pairs. Term type and coefficient type are automatically determined to be Char and Int in the following example.

julia> a = Linear('x' => 1, 'y' => 2)
x+2*y

julia> typeof(a)
Linear{Char, Int64}

julia> b = Linear('z' => 3, 'w' => -1)
-w+3*z

julia> c = a + 2*b - 'v'
-2*w+x+2*y-v+6*z

julia> c['y'], c['u']
(2, 0)

Linear combinations with non-concrete types are also possible.

julia> p = Linear{AbstractVector,Real}([1,2,3] => 5, 4:6 => 1//2)
1//2*4:6+5*[1, 2, 3]

julia> [4,5,6] - 2*p   # [4,5,6] is equal to 4:6
-10*[1, 2, 3]

Next we define a linear function mapping terms to terms. This is done with the help of the macro @linear.

julia> @linear f; f(x::Char) = uppercase(x)
f (generic function with 2 methods)

julia> f(a)
2*Y+X

Another linear function, this time mapping terms to linear combinations.

julia> @linear g; g(x::Char) = Linear(f(x) => 1, x => -1)
g (generic function with 2 methods)

julia> g(a)
2*Y-x-2*y+X

Multiplication is bilinear by default. Recall that multiplying Char or String values in Julia means concatenation.

julia> a * 'w'
xw+2*yw

julia> a * b
-xw+6*yz-2*yw+3*xz

The next example is a user-defined bilinear function. Bilinearity is achieved by the macro @multilinear.

julia> @multilinear h; h(x, y) = x*y*x
h (generic function with 2 methods)

julia> h(a, b)
-xwx+3*xzx+12*yzy+6*xzy+6*yzx-2*ywx-2*xwy-4*ywy

Here is a user-defined multilinear function with a variable number of arguments.

julia> @multilinear j; j(x::Char...) = *(x...)
j (generic function with 2 methods)

julia> j(a)
x+2*y

julia> j(a, b)
-xw+6*yz-2*yw+3*xz

julia> j(a, b, a)
-xwx+3*xzx+12*yzy+6*xzy+6*yzx-2*ywx-2*xwy-4*ywy

In the following example we define a tensor and swap the two components of each summand.

julia> t = tensor(a, b)
3*xz-xw-2*yw+6*yz

julia> swap(t)
-2*wy+6*zy-wx+3*zx

We finally take the tensor product of the functions f and g and apply it to t.

julia> k = tensor(f, g)
fg

julia> k(Tensor('x', 'z'))
-Xz+XZ

julia> k(t)
-3*Xz-XW+2*Yw+6*YZ+Xw-6*Yz+3*XZ-2*YW