2
$\begingroup$

I'd like to create a distance matrix with an expensive distance function.

To explore how to do this for a simpler case, consider these three ways of creating a Euclidean distance matrix:

  1. Using a DistanceFunction in DistanceMatrix
  2. Using EuclideanDistance in Outer
  3. Using DistanceMatrix directly

The second method is 2.3 times faster than the first. The third method is 880 times faster than the first.

pts = RandomReal[{0, 1}, {1000, 3}];
RepeatedTiming[DistanceMatrix[pts, DistanceFunction -> (EuclideanDistance[#1, #2] &)];]
RepeatedTiming[Outer[EuclideanDistance[#1, #2] &, pts, pts, 1];]
RepeatedTiming[DistanceMatrix[pts];]

I'm trying to use FunctionCompile to speed up the second method and can't find a way to do it.

Here is what I've tried:

Creating a compiled version of EuclideanDistance

distance = FunctionCompile@
      Function[
{Typed[x, TypeSpecifier["NumericArray"]["Real64", 1]], Typed[y, TypeSpecifier["NumericArray"]["Real64", 1]]},
       Module[{dx = x - y}, Sqrt[dx . dx]]
       ]

which works and has code signature:

codeSignature = {TypeSpecifier["NumericArray"]["Real64", 1], 
  TypeSpecifier["NumericArray"]["Real64", 1]} -> "Real64"

I can't figure out how to compile Outer:

outer = FunctionCompile@
  Function[{Typed[x, TypeSpecifier["NumericArray"]["Real64", 1]]},
   Module[{outer},
    outer = Typed[KernelFunction[Outer],
      {codeSignature,
        TypeSpecifier["NumericArray"]["Real64", 1], 
        TypeSpecifier["NumericArray"]["Real64", 1], 
        Typed[level, "Integer16"]} -> 
       TypeSpecifier["NumericArray"]["Real64", 2]
      ];
    outer[distance, x, x, 1]
    ]
   ]

I get a TypeError, no matching candidate, and something about Unintialized.

Can anyone give me a working example so I can compile a different distance function?

$\endgroup$

0

Your Answer

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