gonum / matrix

Matrix packages for the Go language [DEPRECATED]
446 stars 51 forks source link

Chaining for Arithmetic like multiplication, addition of matrices? #53

Closed c2akula closed 9 years ago

c2akula commented 9 years ago

Hey guys, I wanted to know, if it's possible to make chaining available to multiplication and addition of matrices? It would be a lot helpful in use cases such as:

    A6s = A6*(c[13]*A6 + c[11]*A4 + c[9]*A2)
    c[i] == constant and A6, A4, A2 are matrices

    U = A * (A6s + c[7]*A6 + c[5]*A4 + c[3]*A2 + c[1]*I)

Such situations, chaining makes it much more easy on writing code.

btracey commented 9 years ago

This is not possible. Go does not allow operator overloading.

jonlawlor commented 9 years ago

It isn't possible with operator overloading, but it is possible to create expression trees that are lazily evaluated that could produce the same effect, including the in place modification that matrix currently allows for improved performance. There might be something interesting in that approach. As an example, the (not at all performant!) rel package that I put together uses them to implement query rewrite for relational algebra. It might be useful to do something similar in linear algebra, because the expression trees could notice that (for example) some operations result in symmetric matrices and take advantage of that during evaluation without having a dimensional explosion of types and methods.

btracey commented 9 years ago

You could make some sort of meta language that does that. People have done similar things for Python. I don't see how you would do that in Go and be performant. The easy way to "recognize operations result in a symmetric matrix" is by providing such functions, for example, the Dsyr and Dsyr2 functions in BLAS. We can also allow performant chaining by having a function func (d *Dense) MulGroup(a ... Matrix) That uses dynamic programming to figure out an optimal multiplication order.

c2akula commented 9 years ago

+1 the variadic implementation. Would it mean that the MulGroup routine would return the result or put it into the receiver?

btracey commented 9 years ago

Put it in the receiver most likely.

jonlawlor commented 9 years ago

I'll fiddle around with the idea a bit. I don't know if much will come of it other than my own edification.

kortschak commented 9 years ago

The other issue not mentioned here by others is that — even disregarding the use of infix operators and their overloading which will never be included in Go given past sentiments expressed on golang-nuts — chaining requires that the func return the same type and that it has the following methods in its method set. The consequence of this is that Matrix would be a very large interface and by API fixation be essentially non-extensible (biogo.matrix and GoMatrix both took this approach). During the API design discussion that preceeded gonum/matrix coding, we decided that this was not a good approach to take. The upshot of all of this is that you would need to type assert at each operation. (This also explains why we assign to the receiver rather than use the language's assignment operators).

jonlawlor commented 9 years ago

As long as it satisfies the same interface set it would be fine. The way I did this previously is to have 2 types of matrices: "literal" and "derived". You would still want the derived ones to implement things like matrix algebra, etc, so the interface would remain the same. There would be an additional operation, which would correspond to LINQ's fetch, which would turn a derived matrix into a literal one.

I am most likely not seeing some pitfalls but as I'll see if I can put something together when time permits. I don't have any expectation of it replacing the current implementation, but it might be interesting regardless.

jonlawlor commented 9 years ago

Also, I don't know if you've seen this already, but https://www.youtube.com/watch?v=PXoG0WX0r_E has Rob Pike working on an Ivy interpreter, which includes matrix-ish arithmetic. The part starting 18m+ may be of particular interest.

UserAB1236872 commented 9 years ago

If we started a symbolic computing package this sort of thing would be more doable, but I don't know if we have anyone with experience in the morass that is symbolic computing.