DIP80: phobos additions

jmh530 via Digitalmars-d digitalmars-d at puremagic.com
Thu Jun 11 14:30:19 PDT 2015


On Tuesday, 9 June 2015 at 03:26:25 UTC, Ilya Yaroshenko wrote:

> There are
> https://github.com/9il/simple_matrix and
> https://github.com/9il/cblas .
> I will try to rework them for Phobos.
>
> Any ideas and suggestions?
>

A well-supported matrix math library would definitely lead to me 
using D more. I would definitely applaud any work being done on 
this subject, but I still feel there are some enhancements (most 
seemingly minor) that would really make a matrix math library 
easy/fun to use.

Most of what I discuss below is just syntactical sugar for some 
stuff that could be accomplished with loops or std.algorithm, but 
having it built-in would make practical use of a matrix math 
library much easier. I think Armadillo implements some of these 
as member functions, whereas other languages like R and Matlab 
have them more built-in.

Disclaimer: I don't consider myself a D expert, so I could be 
horribly wrong on some of this stuff.

1) There is no support for assignment to arrays based on the 
values of another array.
int[] A = [-1, 1, 5];
int[] B = [1, 2];
int[] C = A[B];

You would have to use int[] C = A[1..2];. In this simple example, 
it’s not really a big deal, but if I have a function that returns 
B, then I can’t just throw B in there. I would have to loop 
through B and assign it to C. So the type of assignment is 
possible, but if you’re frequently doing this type of array 
manipulation, then the number of loops you need starts increasing.

2) Along the same lines, there is no support for replacing the B 
above with an array of bools like
bool[] B = [false, true, true];
or
auto B = A.map!(a => a < 0);

Again, it is doable with a loop, but this form of logical 
indexing is a pretty common idiom for people who use Matlab or R 
quite a bit.

3) In addition to being able to index by a range of values or 
bools, you would want to be able to make assignments based on 
this. So something like
A[B] = c;

This is a very common operation in R or Matlab.

4) Along the lines of #2, as an alternative to map, there is no 
support for array comparison operators. Something like
int[3] B;
B[] = A[] + 5;

works, but

bool[3] B;
B[] = A[] > 0;

doesn’t (I’m also not sure why I can’t just write auto B[] = A[] 
+ 5;, but that’s neither here nor there). Moreover, it seems like 
only the mathematical operators work in this way. Mathematical 
functions from std.math, like exp, don’t seem to work. You have 
to use map (or a loop) with exp to get the result. I don’t have 
an issue with map, per se, but it seems inconsistent when some 
things work but not others.

5) You can only assign scalars to slices of arrays. There doesn’t 
seem to be an ability to assign an array to a slice. For 
instance, in #1, I couldn’t write A[0..1] = B; or A[0, 1] = B; 
instead of what I had written for C.

6) std.range and std.algorithm seem to have much better support 
for one dimensional containers than if you want to treat a 
container as two-dimensional. If you have a two-dimensional array 
and want to use map on every element, then there’s no issue. 
However, if you want to apply a function to each column or row, 
then you’d have to use a for loop (not even foreach).

This seems to be a more difficult problem to solve than the 
others. I’m not sure what the best approach is, but it makes 
sense to look at other languages/libraries. In R, you have apply, 
which can operate on any dimensional array.  Matlab has arrayfun. 
Numpy has apply_along_axis. Armadillo has .each_col and .each_row 
(one other thing about Armadillo is that you can switch between 
what underlying matrix math library is being used, like OpenBlas 
vs. Intel MKL).


More information about the Digitalmars-d mailing list