1
$\begingroup$

Compile generates the following error (CompiledFunction::cflist: Nontensor object generated; proceeding with uncompiled evaluation.) upon execution of this simple function fn1[pt, opentri] and how to resolve the issue? Note that the function without Compile works fine.

ClearAll[fn1];
Block[{temp, firstelem},
 fn1 = Compile[{{sourcept, _Real, 1}, {ls, _Real, 3}},
   (firstelem = #[[1]];
      If[Chop[firstelem - sourcept, 10^-8] == {0., 0., 0.},
       #,
       RotateLeft[#, First[Position[#, sourcept]] - 1]]) & /@ ls
   ,
   CompilationTarget -> "C", RuntimeOptions -> "Speed"
   ]
 ]

where pt = {-0.01645930097046247042591460285620996729`8.,0.4325228008917327838`8.,0.4127145715152158445`8.}; and the second argument is:

opentri = {{{0.1575639491896651811`8., 0.8930167660947179176`8., 
     0.4037575264860177038`8.}, \
{-0.01645930097046247042591460285620996729`8., 
     0.4325228008917327838`8., 
     0.4127145715152158445`8.}, {0.4333460612444884896`8., 
     0.4168931919652226759`8., 
     0.4581710563101135114`8.}}, \
{{-0.01645930097046247042591460285620996729`8., 
     0.4325228008917327838`8., 
     0.4127145715152158445`8.}, {0.1437933000929649541`8., 
     0.02310394547537703360817751274680631468`8., 
     0.5810140906075491607`8.}, {0.4333460612444884896`8., 
     0.4168931919652226759`8., 
     0.4581710563101135114`8.}}, {{0.1437933000929639549`8., 
     0.02310394547537703360817751274680631468`8., 
     0.5810140906075491607`8.}, \
{-0.01645930097046247042591460285620996729`8., 
     0.4325228008917327838`8., 
     0.4127145715152158445`8.}, {-0.2408181610124800476`8., 
     0.02828371955366073067783538874664372997`8., 
     0.4989092540607453774`8.}}, \
{{-0.01645930097046247042591460285620996729`8., 
     0.4325228008917327838`8., 
     0.4127145715152158445`8.}, {-0.4529706655450617403`8., 
     0.4675525533083570995`8., 
     0.4698128950000378667`8.}, {-0.2408181610124800476`8., 
     0.02828371955366073067783538874664372997`8., 
     0.4989092540607453774`8.}}, {{-0.4529706655450614072`8., 
     0.4675525533083570995`8., 
     0.4698128950000378667`8.}, \
{-0.0164593009704621373590072153092478402`8., 
     0.4325228008917327838`8., 
     0.4127145715152158445`8.}, {-0.2248024098901401924`8., 
     0.8607932575117263063`8., 
     0.4368553172652774874`8.}}, \
{{-0.0164593009704621373590072153092478402`8., 
     0.4325228008917327838`8., 
     0.4127145715152158445`8.}, {0.1575639491896651811`8., 
     0.8930167660947179176`8., 
     0.4037575264860177038`8.}, {-0.2248024098901401924`8., 
     0.8607932575117263063`8., 0.4368553172652774874`8.}}};
$\endgroup$
5
  • 1
    $\begingroup$ Block should be inside Compile. This isn't the root of problem, of course. $\endgroup$
    – xzczd
    Jul 1, 2021 at 1:45
  • $\begingroup$ @xzczd thanks. any idea what maybe going wrong? the function works without Compile, albeit each subfunction is compilable $\endgroup$
    – Ali Hashmi
    Jul 1, 2021 at 1:57
  • $\begingroup$ Interesting. I can boil down the problem to the following: posfunc = Compile[{{lsmember, _Real, 2}, {pt, _Real, 1}}, Position[lsmember, pt]]; posfunc[opentri[[-2]], pt] But I'm not sure why. $\endgroup$
    – xzczd
    Jul 1, 2021 at 2:28
  • 1
    $\begingroup$ Oh, I see, the precision of your data is 8, but the only allowed precision in Compile is MachinePrecision, when opentri and pt are fed into fn1, the data actually changes, so Position fails. $\endgroup$
    – xzczd
    Jul 1, 2021 at 2:38
  • $\begingroup$ @xzczd thanks. posted the modified function below. this one does not issue the warning. $\endgroup$
    – Ali Hashmi
    Jul 1, 2021 at 2:56

2 Answers 2

2
$\begingroup$

Let me extend my comments to an answer. The problem can be boiled down to the following:

posfunc = 
  Compile[{{lsmember, _Real, 2}, {pt, _Real, 1}}, Position[lsmember, pt]];
posfunc[opentri[[-2]], pt]
(* {} *)

while

Position[opentri[[-2]], pt]
(* {{2}} *)

Why? Because the precision of the inputs is 8, but the only allowed precision for approximate number in Compile is MachinePrecision, when opentri and pt are fed into fn1, the data actually changes, so Position fails in Compile. (BTW it's a bit surprising to me that Position takes precision into account, I dimly thought things like Position[{1.000001`2}, 1.000002`2] should output {}! )

So, how to fix the code? Here's my solution, which makes use of quicksort:

cf = 
 Compile[{{pt, _Real, 1}, {ls, _Real, 3}}, 
  RotateLeft[#, Ordering[#\[Transpose] - pt // Transpose // Abs, 1] - 1] & /@ ls];

rst = cf[pt, opentri]; // RepeatedTiming
(* {0.0000203921, Null} *)

(* fn1 from Ali's answer: *)
rst2 = fn1[pt, opentri]; // RepeatedTiming
(* {0.0000371906, Null} *)

rst == rst2
(* True *)
$\endgroup$
2
  • $\begingroup$ Will accept yours as the answer ! thanks :) $\endgroup$
    – Ali Hashmi
    Jul 1, 2021 at 3:16
  • $\begingroup$ @Ali Feel free to wait for a while for better answers :) $\endgroup$
    – xzczd
    Jul 1, 2021 at 3:17
1
$\begingroup$

partly based on xzczd's suggestion we can rewrite the function

fn1 = Compile[{{sourcept, _Real, 1}, {ls, _Real, 3}},
  Block[{temp, firstelem, vec, pos = 0},
   (vec = #;
      firstelem = Compile`GetElement[vec, 1];
      If[Chop[firstelem - sourcept, 10^-8] == {0., 0., 0.},
       vec,
       Which[
        Chop[Compile`GetElement[vec,2] - sourcept, 10^-8] == {0.,0.,0.},
        pos = 2,
        Chop[Compile`GetElement[vec,3] - sourcept, 10^-8] == {0.,0.,0.},
        pos = 3
        ];
       RotateLeft[vec, pos - 1]
       ]) & /@ ls
   ], CompilationTarget -> "C", RuntimeOptions -> "Speed", 
  CompilationOptions -> {"ExpressionOptimization" -> True, 
    "InlineExternalDefinitions" -> True}];
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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