<div>Thanks for the feedback!</div><br><div class="gmail_quote">On 4 April 2012 10:21, Michael Chen <span dir="ltr"><<a href="mailto:sth4nth@gmail.com">sth4nth@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

another btw, there is also another great c++ linear algebra library<br>
besides Eigen: Amardillo which has very simple matlab like interface<br>
 and performs on a par with Eigen.<br></blockquote><div> </div><div>I'll look into it, thanks.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On Wed, Apr 4, 2012 at 5:14 PM, Michael Chen <<a href="mailto:sth4nth@gmail.com">sth4nth@gmail.com</a>> wrote:<br>
> Btw, I really don't like the matrix api to be member functions. It is<br>
> hard for user to extend the library in an unified way. It is also ugly<br>
> when you want to chain the function calls.</div></div></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">
><br>
> On Wed, Apr 4, 2012 at 5:09 PM, Michael Chen <<a href="mailto:sth4nth@gmail.com">sth4nth@gmail.com</a>> wrote:<br>
>> For the Point 4, I really like to have high order functions like<br>
>> reduceRow and reduceCol. then the function argument is simply the<br>
>> reduceRow!foo(0,mat), here the foo is not a function operating on the<br>
>> whole column but simply a function of two elements (e.g.<br>
>> reduceRow!("a+b")(0,mat)). Or even better we could have a general<br>
>> reduce function with row and col as template parameter so that we can<br>
>> do reduce!(foo,row)(0,mat). I dont know whether we can optimize such<br>
>> reduce function for different matrix type, but such a function will be<br>
>> extremely useful from a user perspective</div></div></blockquote><div><br></div><div><div>Well, as I said before, there's nothing stopping us from providing the free functions that call the member functionsl. However there is something stopping us from not providing a member function alternative. D's lack of ADL means we would not allow easy extensibility of possible operations. Say Alice invents a new kind of matrix type, the DiagonalMatrix type which stores its elements in a 1D array (this isn't exactly how it would work with the design we have, she would in fact have to define a storage type, but bear with me). If she wants to implement sum on her matrix, she can't simply add a specialisation to the sum( T ) function because of the lack of ADL. If instead we implemented sum(T) as:</div>

<div><br></div><div>auto sum( T )( T matrix ) {</div><div>     static if( is( typeof( T.init.sum() ) ) )</div><div>         return matrix.sum;</div><div>     else</div><div>         return reduce!"a+b"( 0, matrix.elements() );</div>

<div>}</div><div><br></div><div>then Alice could simply define a DiagonalMatrix.sum() method that wouldn't need to go through all the zero elements, for example. The idea of rowReduce and columnReduce still works - we can provide this for when a user wants to use her own operation for reducing. We could also have a way of automatically optimising rowReduce!"a+b"( mat ) by calling mat.rowwise().sum() if the operation is available - but that wouldn't be exactly high priority.</div>

</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">.<br>
>><br>
>> On Tue, Apr 3, 2012 at 7:20 PM, Cristi Cobzarenco<br>
>> <<a href="mailto:cristi.cobzarenco@gmail.com">cristi.cobzarenco@gmail.com</a>> wrote:<br>
>>><br>
>>><br>
>>> On 3 April 2012 02:37, Caligo <<a href="mailto:iteronvexor@gmail.com">iteronvexor@gmail.com</a>> wrote:<br>
>>>><br>
>>>> I've read **Proposed Changes and Additions**, and I would like to<br>
>>>> comment and ask a few questions if that's okay.  BTW, I've used Eigen<br>
>>>> a lot and I see some similarities here, but a direct rewrite may not<br>
>>>> be the best thing because D > C++.<br>
>>>><br>
>>>> 2.  Change the matrix & vector types, adding fixed-sized matrix<br>
>>>> support in the process.<br>
>>>><br>
>>>> This is a step in the right direction I think, and by that I'm talking<br>
>>>> about the decision to remove the difference between a Vector and a<br>
>>>> Matrix.  Also, fixed-size matrices are also a must.  There is<br>
>>>> compile-time optimization that you won't be able to do for<br>
>>>> dynamic-size matrices.<br>
>>>><br>
>>>><br>
>>>> 3. Add value arrays (or numeric arrays, we can come up with a good name).<br>
>>>><br>
>>>> I really don't see the point for these.  We have the built-in arrays<br>
>>>> and the one in Phobos (which will get even better soon).<br>
>>><br>
>>><br>
>>> The point of these is to have light-weight element wise operation support.<br>
>>> It's true that in theory the built-in arrays do this. However, this library<br>
>>> is built on top BLAS/LAPACK, which means operations on large matrices will<br>
>>> be faster than on D arrays. Also, as far as I know, D doesn't support<br>
>>> allocating dynamic 2-D arrays (as in not arrays of arrays), not to mention<br>
>>> 2-D slicing (keeping track of leading dimension).<br>
>>> Also I'm not sure how a case like this will be compiled, it may or may not<br>
>>> allocate a temporary:<br>
>>><br>
>>> a[] = b[] * c[] + d[] * 2.0;<br>
>>><br>
>>> The expression templates in SciD mean there will be no temporary allocation<br>
>>> in this call.<br>
>>><br>
>>>><br>
>>>><br>
>>>> 4. Add reductions, partial reductions, and broadcasting for matrices and<br>
>>>> arrays.<br>
>>>><br>
>>>> This one is similar to what we have in Eigen, but I don't understand<br>
>>>> why the operations are member functions (even in Eigen).  I much<br>
>>>> rather have something like this:<br>
>>>><br>
>>>> rowwise!sum(mat);<br>
>>>><br>
>>>> Also, that way the users can use their own custom functions with much<br>
>>>> ease.<br>
>>><br>
>>><br>
>>> There is a problem with this design. You want each matrix type (be it<br>
>>> general, triangular, sparse or even an expression node)  do be able to<br>
>>> define its own implementation of sum: calling the right BLAS function and<br>
>>> making whatever specific optimisations they can. Since D doesn't have<br>
>>> argument dependent look-up (ADL), users can't provide specialisations for<br>
>>> their own types. The same arguments apply to rowwise() and columnwise()<br>
>>> which will return proxies specific to the matrix type. You could do<br>
>>> something like this, in principle:<br>
>>><br>
>>> auto sum( T )( T mat ) {<br>
>>>   return mat.sum();<br>
>>> }<br>
>>><br>
>>> And if we want that we can add it, but this will provide no addition in<br>
>>> extensibility. By the way, you can use std.algorithm with matrices since<br>
>>> they offer range functionality, but it will be much slower to use<br>
>>> reduce!mySumFunction(mat) than mat.sum() which uses a BLAS backend.<br>
>>><br>
>>><br>
>>>><br>
>>>><br>
>>>><br>
>>>> 6. Add support for interoperation with D built-in arrays (or pointers).<br>
>>>><br>
>>>> So I take that Matrix is not a sub-type?  why? If we have something like<br>
>>>> this:<br>
>>>><br>
>>>> struct Matrix(Real, size_t row, size_t col) {<br>
>>>><br>
>>>>  Real[row*col] data;<br>
>>>>  alias data this;<br>
>>>> }<br>
>>>><br>
>>>> then we wouldn't need any kind of interoperation with built-in arrays,<br>
>>>> would we?  I think this would save us a lot of headache.<br>
>>>><br>
>>>> That's just me and I could be wrong.<br>
>>><br>
>>><br>
>>> Inter-operation referred more to having a matrix object wrapping a pointer<br>
>>> to an already available piece of memory - maybe allocated through a region<br>
>>> allocator, maybe resulting from some other library. This means we need to<br>
>>> take care of different strides and different storage orders which cannot be<br>
>>> handled by built-in arrays. Right now, matrices wrap ref-counted<br>
>>> copy-on-write array types (ArrayData in the current code) - we decided last<br>
>>> year that we don't want to use the garbage collector, because of its current<br>
>>> issues. Also I would prefer not using the same Matrix type for<br>
>>> pointer-wrappers and normal matrices because the former must have reference<br>
>>> semantics while the latter have value semantics. I think it would be<br>
>>> confusing if some matrices would copy their data and some would share<br>
>>> memory.<br>
>>><br>
>>>><br>
>>>><br>
>>>> I've got to tell you though, I'm very excited about this project and<br>
>>>> I'll be watching it closely.<br>
>>>><br>
>>>> cheers.<br>
>>><br>
>>> ---<br>
>>> Cristi Cobzarenco<br>
>>> BSc in Artificial Intelligence and Computer Science<br>
>>> University of Edinburgh<br>
>>> Profile: <a href="http://www.google.com/profiles/cristi.cobzarenco" target="_blank">http://www.google.com/profiles/cristi.cobzarenco</a><br>
>>><br>
</div></div></blockquote></div><br>