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).