# Fast element-wise division of matrix, generated from vector with Outer, and another matrix

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.

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

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.

• 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. – ThunderBiggi Dec 13 '18 at 6:43
• See my edit for a parallelized version. – Henrik Schumacher Dec 13 '18 at 7:03
• I am using arbitrary precision numbers, so I guess 'Compile' is not really an option. – ThunderBiggi Dec 13 '18 at 7:38
• Also, interestingly, but on my machine, with Mathematica 11.3, a is faster than b though still slower than the other two. – ThunderBiggi Dec 13 '18 at 7:42
• Yeah, I was also surprised that a was so slow on my machine. I don't know what to think about it... – Henrik Schumacher Dec 13 '18 at 7:51

{{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)$$
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)$$