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$
3
  • $\begingroup$ What is the length of m in practical use? $\endgroup$ Dec 13, 2018 at 3:03
  • $\begingroup$ You can try m/(n ConstantArray[m, Length[m]]) and see how fast it is. $\endgroup$
    – C. E.
    Dec 13, 2018 at 5:22
  • $\begingroup$ @ΑλέξανδροςΖεγγ I editted my question to include some information on that. $\endgroup$ Dec 13, 2018 at 6:46

2 Answers 2

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$
6
  • $\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$ Dec 13, 2018 at 6:43
  • $\begingroup$ See my edit for a parallelized version. $\endgroup$ Dec 13, 2018 at 7:03
  • $\begingroup$ I am using arbitrary precision numbers, so I guess 'Compile' is not really an option. $\endgroup$ Dec 13, 2018 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$ Dec 13, 2018 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$ Dec 13, 2018 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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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