2
$\begingroup$

Consider the following function:

func[a_, b_, c_, d_, x_] = (a + b + c + d)*x;
aval = 1;
bval = 2;
ccval = 3;
dval = 4;
Hold@Compile[{x, _Real}, func[aval, bval, ccval, dval, x], 
     CompilationTarget -> "C", RuntimeOptions -> "Speed"] /. 
   OwnValues@aval/.OwnValues@bval/.OwnValues@ccval/.OwnValues@dval /.DownValues@func // ReleaseHold

The code [email protected]@.. is very long. Is it possible to shorten it so OwnValues@ would be used only once?

For DownValues, I do not experience such problems:

rule = Flatten[
   DownValues /@ {func}];

And then

Hold@Compile[{x, _Real}, func[aval, bval, ccval, dval, x], CompilationTarget -> "C", RuntimeOptions -> "Speed"]/.OwnValues@aval/.OwnValues@bval/.OwnValues@ccval/.OwnValues@dval//.rule// ReleaseHold

The same construction as in rule does not work for OwnValues:

rule = Flatten[OwnValues /@ {aval, bval, ccval, dval}];

OwnValues::sym: Argument 1 at position 1 is expected to be a symbol.

$\endgroup$

3 Answers 3

5
$\begingroup$

Would this be acceptable solution?

Compile[...] /. Flatten[OwnValues /@ (Unevaluated@{aval, bval, ccval, dval})]

Obviosuly, you can make an auxilliary function

SetAttributes[injectDefs, HoldAll];
injectDefs[symbs_] := Flatten[OwnValues /@ (Unevaluated@symbs)]

Compile[...] /. injectDefs[{aval, bval, ccval, dval}]
$\endgroup$
2
$\begingroup$

Define

 repl={{name, value}.,..}. 

Then you always can use

 expr/.Rule@@@repl 

 expr/.RuleDelayed@@@repl

 f@@Subtract@@@repl
 
 And@@Equal@@@repl

and this one ends it use

  Set@@@repl  
$\endgroup$
1
  • 2
    $\begingroup$ Thanks! However, I do not see how to apply these points directly to my question. $\endgroup$ May 18, 2023 at 11:58
2
$\begingroup$

OwnValues works with string names:

rule = Flatten[OwnValues /@ {"aval", "bval", "ccval", "dval"}];

Alternative approach independent of number of symbols and their names:

Hold@Compile[{x, _Real}, func[aval, bval, ccval, dval, x], 
   CompilationTarget -> "C", RuntimeOptions -> "Speed"] //
 # //. Flatten@
    Cases[#, 
     s_Symbol?(Function[s, 
         Context[Unevaluated@s] === "Global`" && 
          ValueQ[s, Method -> "SymbolDefinitionsPresent"], HoldAll]) :>
       Join[OwnValues[s], DownValues[s]], Infinity, Heads -> True] &
$\endgroup$
9
  • $\begingroup$ Thanks! A very elegant solution. Just a stupid question: is it okay to have simultaneously DownValues@func and OwnValues@func, as well as those for aval etc? $\endgroup$ May 21, 2023 at 9:19
  • $\begingroup$ Also, in Mathematica 12.1, it says: ValueQ::argx: ValueQ called with 2 arguments; 1 argument is expected.. Does it mean that it is inconsistent with older versions of Mathematica? $\endgroup$ May 21, 2023 at 13:00
  • $\begingroup$ Finally, why in ValueQ the option is SymbolDefinitionsPresent but no OwnValuesPresent? $\endgroup$ May 21, 2023 at 13:27
  • 1
    $\begingroup$ @JohnTaylor Join[OwnValues[s], DownValues[s]] should be ok. If there are OwnValues, they will be applied first, which is what happens normally. If there are no values, OwnValues[s] returns {}, so all the rules you get are DownValues[s]. -- I'm using 13.2. I guess they hadn't added the options to ValueQ in 12.1. I don't see a real problem with just omitting it: If no values, then Join[OwnValues[s], DownValues[s]] returns {}. No values for a global symbol in Compile is usually a mistake anyway. -- You'll have to ask WRI why ValueQ has the options it does. I don't know. $\endgroup$
    – Michael E2
    May 21, 2023 at 15:31
  • 1
    $\begingroup$ @JohnTaylor In 13.2 ValuesQ[func] returns False and ValueQ[func, Method -> "SymbolDefinitionsPresent"] returns True. (Actually, going back to one of your earlier questions, the default ValueQ[s] is probably the same as what you meant by "OwnValuesPresent". What's missing is DownValuesPresentOnly. As well as other logical combinations of *Values, I suppose.) $\endgroup$
    – Michael E2
    May 21, 2023 at 19:45

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.