Types for Variables

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Types for Variables

Julia Developer mailing list
Hi,

I would like to discuss a very fundamental idea since I am unsure if this is idea is just stupid or perhaps revolutionary:

Let's solve a trivial linear equation system in Julia:

x + y = 3
x - y = 1

Solution:
---
julia> [1 1;1 -1] \ [3;1]
2-element Array{Float64,1}:
 2.0
 1.0
---
What if x and y were Variable objects? The Code could look like this:
---
julia> x = Variable(Float64), y = Variable(Float64)
(Variable{Float64}(0.0), Variable{Float64}(0.0))
julia> roots!([x + y - 3;
                      x - y - 1])
(Variable{Float64}(2.0), Variable{Float64}(1.0))
---
x and y would be objects of type Variable{Float64}. The "!" in the function roots! indicates that the values of x and y are changed to match the solution of the equation system. This would require to overload the +, - and all other operators for Variable objects. These operations could be saved in the Variable objects, including their arguments. Thus, the Variable type could look something like this.

Variable{NUM<:Number}
   fun::Function
   arg::Tuple{Vararg{Variable}}
   val::NUM
end

The whole syntax tree of expressions could be stored this way.
For the trivial linear equation system this makes perhaps not too much of a difference. But what if we had an underdetermined equation system?

julia> z = Variable(Float64);
julia> roots!([x + y + z;
                      x - y - 1])

You may remember from school that this has infinitely many solutions: c*xh+xp, where c ist a constant factor, and xh and xp are the homogeneous and particular solution, respetively. Perhaps you know that using \ and nullspace you can compute xh and xp. But Julia could do this automatically and introduce even a new Variable object for c.

Moreover, we could add a Type Parameter LIN<:Linearity to the Variable type. For "nonlinear" objects, the roots! function could be overloaded to find a numerical solution via e.g. Newton's method like

roots!(exp(x)+x)

Introducing Integer Variables like

julia> n = Variable(Int);

could be used to define Mixed Integer Problems and so on.

One could even imagine objects that represent Function variables that encapsulate the discretization to solve boundary value problems.

One could design algorithms that perform both numerical and symbolic transformations by manipulating the syntax tree which, in contrast to symbolic computing with expressions, is efficient.

I am very curious what you think about this idea and if perhaps somebody is already working in this direction.

Cheers

Thorsten
Reply | Threaded
Open this post in threaded view
|

Re: Types for Variables

Chris Foster
The general approach you've described here is definitely useful for
high level representations of mathematical problems - see both
Convex.jl and JuMP as good examples of what can be achieved.
Convex.jl in particular has a system for dealing with symbolic
variables and expressions which is similar in spirit.

Cheers,
~Chris

On Sun, Mar 13, 2016 at 2:53 AM, 'Thorsten Dahmen' via julia-dev
<[hidden email]> wrote:

> Hi,
>
> I would like to discuss a very fundamental idea since I am unsure if this is
> idea is just stupid or perhaps revolutionary:
>
> Let's solve a trivial linear equation system in Julia:
>
> x + y = 3
> x - y = 1
>
> Solution:
> ---
> julia> [1 1;1 -1] \ [3;1]
> 2-element Array{Float64,1}:
>  2.0
>  1.0
> ---
> What if x and y were Variable objects? The Code could look like this:
> ---
> julia> x = Variable(Float64), y = Variable(Float64)
> (Variable{Float64}(0.0), Variable{Float64}(0.0))
> julia> roots!([x + y - 3;
>                       x - y - 1])
> (Variable{Float64}(2.0), Variable{Float64}(1.0))
> ---
> x and y would be objects of type Variable{Float64}. The "!" in the function
> roots! indicates that the values of x and y are changed to match the
> solution of the equation system. This would require to overload the +, - and
> all other operators for Variable objects. These operations could be saved in
> the Variable objects, including their arguments. Thus, the Variable type
> could look something like this.
>
> Variable{NUM<:Number}
>    fun::Function
>    arg::Tuple{Vararg{Variable}}
>    val::NUM
> end
>
> The whole syntax tree of expressions could be stored this way.
> For the trivial linear equation system this makes perhaps not too much of a
> difference. But what if we had an underdetermined equation system?
>
> julia> z = Variable(Float64);
> julia> roots!([x + y + z;
>                       x - y - 1])
>
> You may remember from school that this has infinitely many solutions:
> c*xh+xp, where c ist a constant factor, and xh and xp are the homogeneous
> and particular solution, respetively. Perhaps you know that using \ and
> nullspace you can compute xh and xp. But Julia could do this automatically
> and introduce even a new Variable object for c.
>
> Moreover, we could add a Type Parameter LIN<:Linearity to the Variable type.
> For "nonlinear" objects, the roots! function could be overloaded to find a
> numerical solution via e.g. Newton's method like
>
> roots!(exp(x)+x)
>
> Introducing Integer Variables like
>
> julia> n = Variable(Int);
>
> could be used to define Mixed Integer Problems and so on.
>
> One could even imagine objects that represent Function variables that
> encapsulate the discretization to solve boundary value problems.
>
> One could design algorithms that perform both numerical and symbolic
> transformations by manipulating the syntax tree which, in contrast to
> symbolic computing with expressions, is efficient.
>
> I am very curious what you think about this idea and if perhaps somebody is
> already working in this direction.
>
> Cheers
>
> Thorsten