# Operator algebra design

**URL:** <https://discourse.julialang.org/t/operator-algebra-design/34104>\
**Category:** General Usage\
**Created:** [February 3, 2020, 7:23am UTC](https://discourse.julialang.org/t/operator-algebra-design/34104 "2020-02-03T07:23:15Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sleort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sleort/32/4875_2.png) [@Sleort](https://discourse.julialang.org/u/Sleort)\
**Post date:** [February 3, 2020, 7:23am UTC](https://discourse.julialang.org/t/operator-algebra-design/34104/1 "2020-02-03T07:23:15Z")

</div>

Although I can easily construct an operator algebra in Julia using closures, I wonder if this is the best/most “Julian” way of doing it. As an example, take the following code

```julia
import Base: +, -, *, /

abstract type AbstractOperator end

#Some concrete operator type:
struct MyOperator{T} <: AbstractOperator
    x::T
end
MyOperator() = MyOperator(rand())

(f::MyOperator)(x) = f.x + x

#Operations on operators:
struct OperatorOperation{O, F<:AbstractOperator, G<:AbstractOperator} <: AbstractOperator
    op::O
    f::F
    g::G
end

(h::OperatorOperation)(x) = h.op(h.f(x), h.g(x))

for op ∈ (:+, :-, :*, :/)
    @eval Base.$op(f::AbstractOperator, g::AbstractOperator) = OperatorOperation($op, f, g)
end

```

After which I can do

```julia
op = MyOperator() #Make an operator
op(1.0) #Evaluate for some input.

op = MyOperator() + MyOperator(1) #Make a slightly more involved operator
op(1.0) #Evaluate for some input.

op = let #An even more involved operator
    op = MyOperator()
    for i = 1:100
        ⋆ = rand((+,-,*,/)) #Randomly select binary operations, just to make the case non-trivial.
        op = op ⋆ MyOperator()
    end
    op
end
op(1.0) #Evaluate for some input.

```

All of the above works just fine, but the (massive) type signature\* of the last example made me wonder if this approach is the recommended way to go in Julia… Or is there some better pattern to use\*\*?

\*Sure, I can make my own pretty printing of `AbstractOperator`, but that’s beside the point…  
\*\*Sure, the example above could (and should) be optimized by e.g. combining the sum of two `MyOperator`s into one, but that’s also somewhat beside the point…

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 3, 2020, 7:44am UTC](https://discourse.julialang.org/t/operator-algebra-design/34104/2 "2020-02-03T07:44:10Z")

</div>

This could be an idiomatic approach, provided your application is type stable, ie operator types are predictable from inputs that construct them, are stored in [homogeneous containers](https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-containers-with-abstract-type-parameters-1), etc.

The large type signature is not problematic _per se_, only if you get into some combinatorial explosion in your application.

These questions are difficult to answer without some context though.

---

<div class="post-metadata">

**Author:** ![Sleort](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sleort/32/4875_2.png) [@Sleort](https://discourse.julialang.org/u/Sleort)\
**Post date:** [February 3, 2020, 8:17am UTC](https://discourse.julialang.org/t/operator-algebra-design/34104/3 "2020-02-03T08:17:02Z")

</div>

Thanks. Good to know!

(In my application, I will only construct a few operators during a “modeling stage”, after which they will be used in some heavier calculations. I was a bit worried that the huge type signature might be a sign of a bad design… 😅)

---

<div class="post-metadata">

**Author:** ![abulak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abulak/32/28314_2.png) [@abulak](https://discourse.julialang.org/u/abulak)\
**Post date:** [February 3, 2020, 11:24am UTC](https://discourse.julialang.org/t/operator-algebra-design/34104/4 "2020-02-03T11:24:47Z")

</div>

If you need to create just a few of these operators and evaluate them repetitively, this might be ok. but please note that you need to compile the composition every time:

```julia
julia> myops = [MyOperator() for i in 1:100];

julia> ops = rand((+,-,*,/), 100);

julia> @time op = let res = MyOperator(), ops = ops, X = myops
           for (op, x) in zip(ops, X)
              res = op(res, x)
           end
           res
       end;
 0.770064 seconds (514.76 k allocations: 29.287 MiB, 1.12% gc time)
julia> @time op = let res = MyOperator(), ops = ops, X = myops
           for (op, x) in zip(ops, X)
              res = op(res, x)
           end
           res
       end;
  0.000255 seconds (1.30 k allocations: 67.563 KiB)
julia> ops = rand((+,-,*,/), 100);

julia> myops = [MyOperator() for i in 1:100];

julia> @time op = let res = MyOperator(), ops = ops, X = myops
           for (op, x) in zip(ops, X)
              res = op(res, x)
           end
           res
       end;
  0.780709 seconds (514.70 k allocations: 29.269 MiB, 1.13% gc time)

```

---

<div class="post-metadata">

**Author:** ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)\
**Post date:** [February 3, 2020, 11:47am UTC](https://discourse.julialang.org/t/operator-algebra-design/34104/5 "2020-02-03T11:47:42Z")

</div>

I played with that idea in the context of static operator algebra:

[https://github.com/mschauer/StaticLinearMaps.jl/blob/master/src/StaticLinearMaps.jl](https://github.com/mschauer/StaticLinearMaps.jl/blob/master/src/StaticLinearMaps.jl)
