5
$\begingroup$
m = {a, b, c};
n = {{e, r, t}, {y, u, i}, {g, h, j}};
k = Outer[Divide, m, m];
k/n

gives

{{1/e, a/(b r), a/(c t)}, {b/(a y), 1/u, b/(c i)}, {c/(a g), c/(b h), 
  1/j}}

I want to do this with very large matrices filled with numbers of arbitrary precision. Is there a faster way?

EDIT

The sizes I am looking at for my practical applications start at 20000 and 20000^2 for the vector and matrix, respectively (of course the examples don't have to be with that many).

I am also interested in any method that might parallelise well.

$\endgroup$
  • $\begingroup$ What is the length of m in practical use? $\endgroup$ – Αλέξανδρος Ζεγγ Dec 13 '18 at 3:03
  • $\begingroup$ You can try m/(n ConstantArray[m, Length[m]]) and see how fast it is. $\endgroup$ – C. E. Dec 13 '18 at 5:22
  • $\begingroup$ @ΑλέξανδροςΖεγγ I editted my question to include some information on that. $\endgroup$ – ThunderBiggi Dec 13 '18 at 6:46
6
$\begingroup$
m = RandomReal[{-1, 1}, {2000}];
n = RandomReal[{-1, 1}, {2000, 2000}];
a = Outer[Divide, m, m]/n; // RepeatedTiming // First
b = Map[#/m &, MapThread[#1 #2 &, {m, 1/n}]]; // 
  RepeatedTiming // First
c = m /(ConstantArray[m, Length[m]] n); // RepeatedTiming // First
d = KroneckerProduct[m, 1./m]/n; // RepeatedTiming // First
a == b == c == d

0.958

0.128

0.0281

0.0236

True

Edit

A parallelized version

cf = Compile[{{x, _Real}, {y, _Real, 1}, {z, _Real, 1}},
   x/(y z),
   CompilationTarget -> "C",
   RuntimeAttributes -> {Listable},
   Parallelization -> True,
   RuntimeOptions -> "Speed"
   ];
e = cf[m, n, m]; // RepeatedTiming // First
a == e

0.0096

True

Timing has been measured on a Quad Core CPU which shows that this does not scale too well. Btw., the timing with CompilationTarget -> "C" is only 4% slower, so there is always no point to compile it into a library.

$\endgroup$
  • $\begingroup$ I was just typing a comparison of the answers so far, but you were first. I wouldn't've expected that KroneckerProduct would be that quick. Any ideas on any way that might parallelise well? I will edit my question to include that as well. $\endgroup$ – ThunderBiggi Dec 13 '18 at 6:43
  • $\begingroup$ See my edit for a parallelized version. $\endgroup$ – Henrik Schumacher Dec 13 '18 at 7:03
  • $\begingroup$ I am using arbitrary precision numbers, so I guess 'Compile' is not really an option. $\endgroup$ – ThunderBiggi Dec 13 '18 at 7:38
  • $\begingroup$ Also, interestingly, but on my machine, with Mathematica 11.3, a is faster than b though still slower than the other two. $\endgroup$ – ThunderBiggi Dec 13 '18 at 7:42
  • $\begingroup$ Yeah, I was also surprised that a was so slow on my machine. I don't know what to think about it... $\endgroup$ – Henrik Schumacher Dec 13 '18 at 7:51
4
$\begingroup$

Pretty printing your result gives...

{{1/e, a/(b r), a/(c t)}, {b/(a y), 1/u, b/(c i)}, {c/(a g), c/(b h),1/j}}//MatrixForm

$\left( \begin{array}{ccc} \frac{1}{e} & \frac{a}{b r} & \frac{a}{c t} \\ \frac{b}{a y} & \frac{1}{u} & \frac{b}{c i} \\ \frac{c}{a g} & \frac{c}{b h} & \frac{1}{j} \\ \end{array} \right)$

Try this, it avoids constructing the huge Outer[ ] matrix

Map[#/m &, MapThread[#1 #2 &, {m, 1/n}]] // MatrixForm

$\left( \begin{array}{ccc} \frac{1}{e} & \frac{a}{b r} & \frac{a}{c t} \\ \frac{b}{a y} & \frac{1}{u} & \frac{b}{c i} \\ \frac{c}{a g} & \frac{c}{b h} & \frac{1}{j} \\ \end{array} \right)$

$\endgroup$

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.