To optimize a brute force algorithm on graphs I want to compile dynamically a list of functions for a list of graphs.
(The representation I'm using for a graph is a list of pairs of integers: integers are nodes, pairs are edges.)
To create one function I need:
- the graph representation
- a
displacementlist.
displacement is constant between all the functions of graphs with $n$ nodes, but since my program operates on various $n$ and also because I don't know displacement in advance and I will actually evaluate it, I'd like to pass displacement too as a parameter for my "pure compilator function".
Here's an example of one single graph and its relative compiled function
displacement = {1, 2, 4, 8, 13, 21, 31};
graph = {{1, 2}, {2, 3}, {2, 4}};
tergetFun = Compile[{{a, _Integer, 1}}, With[{p = {1, 2, 4, 8, 13, 21, 31}}, {p[[a[[1]]]] + p[[a[[2]]]], p[[a[[2]]]] + p[[a[[3]]]], p[[a[[2]]]] + p[[a[[4]]]]}]];
It's not hard to dynamically generate the expression for the function
(p[[a[[#1]]]] + p[[a[[#2]]]]) & @@@ graph
Part::partd: Part specification a[[1]] is longer than depth of object.
Part::pkspec1: The expression a[[1]] cannot be used as a part specification.
Part::partd: Part specification a[[2]] is longer than depth of object.
(* the entire list of errors *)
(* {p[[a[[1]]]] + p[[a[[2]]]], p[[a[[2]]]] + p[[a[[3]]]], p[[a[[2]]]] + p[[a[[4]]]]} *)
Done in this way Mathematica attempts to evaluate Part, failing. Nonetheless the output is exactly the one I need.
I've tried any kind of evaluation control but this most direct and wrong(?) way of doing it is the only one actually working when I use it as argument in Compile
Compile[{{a, _Integer, 1}}, With[{p = #1}, #2]] & @@ {#1, ((p[[a[[#1]]]] + p[[a[[#2]]]]) & @@@ #2)} & @@ {displacement, graph}
(* list of errors *)
(* targetFun *)
Should I use Quiet or some form of evaluation control actually works?
Compile\GetElement? By the way I recompile the function many times because I use it in a brute force search where I map it on aPermutation@Range@nlist (So the function is listable and parallelizable)... Passing to the function this many time a constantdisplacementand a constantgraph` wouldn't be detrimental to speed? (Also I don't know how to make this general version listable) – Domenico Modica Feb 16 '22 at 18:20Compile`GetElementis undocumented. You have to look around on this site to find more details about it. – Henrik Schumacher Feb 16 '22 at 18:28CompilationTarget -> "C"for each graph I had, because looking at the improvement it seemed it wasn't worth the extra time of compilation. Now this meta-function is clearly faster than one specific non-CompilationTarget -> "C"function and at keeps pace with a specificCompilationTarget -> "C"one, thanks – Domenico Modica Feb 16 '22 at 18:45https://stackoverflow.com/questions/7918806/finding-n-th-permutation-without-computing-othersGenerating the permutations one at the time might save you shoving around a lot of memory. – Henrik Schumacher Feb 16 '22 at 18:48