Skip to main content
added 409 characters in body
Source Link
xzczd
  • 68.4k
  • 9
  • 174
  • 489

#Usage

Usage

#Known issue

Known issue


BTW, it's worth mentioning that non-symbol can be used as independent variables in Compile and Experimental`CreateNumericalFunction, see this and this post for more info. (Since these are advanced topics, I'd suggest not to dive into them if you're not experienced enough. )

#Usage

#Known issue

Usage

Known issue


BTW, it's worth mentioning that non-symbol can be used as independent variables in Compile and Experimental`CreateNumericalFunction, see this and this post for more info. (Since these are advanced topics, I'd suggest not to dive into them if you're not experienced enough. )

replaced http://mathematica.stackexchange.com/ with https://mathematica.stackexchange.com/
Source Link

This post contains several code blocks, you can copy them easily with the help of importCodeimportCode.


The following is an attempt for making a general purpose function for this task:

ClearAll[allowNonSymbol]
SetAttributes[allowNonSymbol, HoldAll]
allowNonSymbol[Set[lhs_, rhs_]] := allowNonSymbol[SetDelayed[lhs, #]] &@rhs
allowNonSymbol[func_SetDelayed] := 
  With[{blank = Verbatim[#][___] & /@ (Blank | BlankSequence | BlankNullSequence)}, 
    Module[{newFunc, independentVar}, {newFunc, {independentVar}} = 
        Reap[Hold@func /. 
                var_ (holder : blank) :> 
                  RuleCondition[Sow@HoldPattern@var; Pattern[var, holder]] /. 
              var_ Verbatim[PatternTest][holder : blank, test_] :> 
                
        RuleCondition[Sow@HoldPattern@var; PatternTest[Pattern[var, holder], test]] // 
            Quiet, _, Union[#2] &]; 
      With[{rule = # -> Unique[] & /@ independentVar}, newFunc /. rule // ReleaseHold]]]

allowNonSymbol[func : Function[independentVar_, rhs__]] := 
  With[{rule = # -> Unique[] & /@ Flatten@{independentVar}}, 
    Hold[func] /. rule // ReleaseHold]

#Usage

Clear[f, relativez]
mid = z[bar]^2;
allowNonSymbol[f[z[bar] _] = mid];
allowNonSymbol[relativez[z_, z[bar] _] := z/z[bar]];
f[3]
(* 9 *)
relativez[2, 3]
(* 2/3 *)

allowNonSymbol can be used on pure function:

sin = allowNonSymbol@Function[b[1], Sin@b[1]];
Sin[2.]
(* 0.909297 *)

It can handle BlankSequence[](__) and BlankNullSequence[](___):

Clear[times, join]
allowNonSymbol[times[argu[n] __] := Times[argu[n]]]
times[2, 3, 5]
(* 30 *)
allowNonSymbol[join[lst_, ele[i] ___] := Join[lst, ele[i]]]
join[{3}]
(* {3} *)

It can also handle _h and PatternTest:

Clear[f, g]
allowNonSymbol[f[a[2] _Integer] := 2 a[2]]
f[2]
(* 4 *)
f[2.]
(* f[2.] *)
allowNonSymbol[g[a[1] _?NumericQ] := a[1]]
g[3]
Clear[a]; g[a]
(* g[a] *)

#Known issue

  1. Patterns like a[1]:{_Integer} can't be used, and it seems to be impossible to overcome the issue, because Mathematica notebook simpliy can't parse the expression:

         a[1] : {_Integer}
    

enter image description here

  1. Patterns like Pattern[a[1], {_Integer}] isn't supported yet.

This post contains several code blocks, you can copy them easily with the help of importCode.


The following is an attempt for making a general purpose function for this task:

ClearAll[allowNonSymbol]
SetAttributes[allowNonSymbol, HoldAll]
allowNonSymbol[Set[lhs_, rhs_]] := allowNonSymbol[SetDelayed[lhs, #]] &@rhs
allowNonSymbol[func_SetDelayed] := 
  With[{blank = Verbatim[#][___] & /@ (Blank | BlankSequence | BlankNullSequence)}, 
    Module[{newFunc, independentVar}, {newFunc, {independentVar}} = 
        Reap[Hold@func /. 
                var_ (holder : blank) :> 
                  RuleCondition[Sow@HoldPattern@var; Pattern[var, holder]] /. 
              var_ Verbatim[PatternTest][holder : blank, test_] :> 
                
        RuleCondition[Sow@HoldPattern@var; PatternTest[Pattern[var, holder], test]] // 
            Quiet, _, Union[#2] &]; 
      With[{rule = # -> Unique[] & /@ independentVar}, newFunc /. rule // ReleaseHold]]]

allowNonSymbol[func : Function[independentVar_, rhs__]] := 
  With[{rule = # -> Unique[] & /@ Flatten@{independentVar}}, 
    Hold[func] /. rule // ReleaseHold]

#Usage

Clear[f, relativez]
mid = z[bar]^2;
allowNonSymbol[f[z[bar] _] = mid];
allowNonSymbol[relativez[z_, z[bar] _] := z/z[bar]];
f[3]
(* 9 *)
relativez[2, 3]
(* 2/3 *)

allowNonSymbol can be used on pure function:

sin = allowNonSymbol@Function[b[1], Sin@b[1]];
Sin[2.]
(* 0.909297 *)

It can handle BlankSequence[](__) and BlankNullSequence[](___):

Clear[times, join]
allowNonSymbol[times[argu[n] __] := Times[argu[n]]]
times[2, 3, 5]
(* 30 *)
allowNonSymbol[join[lst_, ele[i] ___] := Join[lst, ele[i]]]
join[{3}]
(* {3} *)

It can also handle _h and PatternTest:

Clear[f, g]
allowNonSymbol[f[a[2] _Integer] := 2 a[2]]
f[2]
(* 4 *)
f[2.]
(* f[2.] *)
allowNonSymbol[g[a[1] _?NumericQ] := a[1]]
g[3]
Clear[a]; g[a]
(* g[a] *)

#Known issue

  1. Patterns like a[1]:{_Integer} can't be used, and it seems to be impossible to overcome the issue, because Mathematica notebook simpliy can't parse the expression:

         a[1] : {_Integer}
    

enter image description here

  1. Patterns like Pattern[a[1], {_Integer}] isn't supported yet.

This post contains several code blocks, you can copy them easily with the help of importCode.


The following is an attempt for making a general purpose function for this task:

ClearAll[allowNonSymbol]
SetAttributes[allowNonSymbol, HoldAll]
allowNonSymbol[Set[lhs_, rhs_]] := allowNonSymbol[SetDelayed[lhs, #]] &@rhs
allowNonSymbol[func_SetDelayed] := 
  With[{blank = Verbatim[#][___] & /@ (Blank | BlankSequence | BlankNullSequence)}, 
    Module[{newFunc, independentVar}, {newFunc, {independentVar}} = 
        Reap[Hold@func /. 
                var_ (holder : blank) :> 
                  RuleCondition[Sow@HoldPattern@var; Pattern[var, holder]] /. 
              var_ Verbatim[PatternTest][holder : blank, test_] :> 
                
        RuleCondition[Sow@HoldPattern@var; PatternTest[Pattern[var, holder], test]] // 
            Quiet, _, Union[#2] &]; 
      With[{rule = # -> Unique[] & /@ independentVar}, newFunc /. rule // ReleaseHold]]]

allowNonSymbol[func : Function[independentVar_, rhs__]] := 
  With[{rule = # -> Unique[] & /@ Flatten@{independentVar}}, 
    Hold[func] /. rule // ReleaseHold]

#Usage

Clear[f, relativez]
mid = z[bar]^2;
allowNonSymbol[f[z[bar] _] = mid];
allowNonSymbol[relativez[z_, z[bar] _] := z/z[bar]];
f[3]
(* 9 *)
relativez[2, 3]
(* 2/3 *)

allowNonSymbol can be used on pure function:

sin = allowNonSymbol@Function[b[1], Sin@b[1]];
Sin[2.]
(* 0.909297 *)

It can handle BlankSequence[](__) and BlankNullSequence[](___):

Clear[times, join]
allowNonSymbol[times[argu[n] __] := Times[argu[n]]]
times[2, 3, 5]
(* 30 *)
allowNonSymbol[join[lst_, ele[i] ___] := Join[lst, ele[i]]]
join[{3}]
(* {3} *)

It can also handle _h and PatternTest:

Clear[f, g]
allowNonSymbol[f[a[2] _Integer] := 2 a[2]]
f[2]
(* 4 *)
f[2.]
(* f[2.] *)
allowNonSymbol[g[a[1] _?NumericQ] := a[1]]
g[3]
Clear[a]; g[a]
(* g[a] *)

#Known issue

  1. Patterns like a[1]:{_Integer} can't be used, and it seems to be impossible to overcome the issue, because Mathematica notebook simpliy can't parse the expression:

         a[1] : {_Integer}
    

enter image description here

  1. Patterns like Pattern[a[1], {_Integer}] isn't supported yet.
Rollback to Revision 5
Source Link
xzczd
  • 68.4k
  • 9
  • 174
  • 489
ClearAll[allowNonSymbol]
SetAttributes[allowNonSymbol, HoldAll]
allowNonSymbol[lhs_ =allowNonSymbol[Set[lhs_, rhs_]rhs_]] := (allowNonSymbol[lhs :=allowNonSymbol[SetDelayed[lhs, #1]#]] &)[rhs]&@rhs
allowNonSymbol[func_SetDelayed] := 
  With[{blank = Verbatim[#][___] & /@ (Blank | BlankSequence | BlankNullSequence)}, 
    Module[{newFunc, independentVar}, {newFunc, {independentVar}} = 
        Reap[Hold@func /. 
                var_ (holder : blank) :> 
                  RuleCondition[Sow@HoldPattern@var; Pattern[var, holder]] /. 
              var_ Verbatim[PatternTest][holder : blank, test_] :> 
                
        RuleCondition[Sow@HoldPattern@var; PatternTest[Pattern[var, holder], test]] // 
            Quiet, _, Union[#2] &]; 
      With[{rule = # -> Unique[] & /@ independentVar}, newFunc /. rule // ReleaseHold]]]

allowNonSymbol[func : Function[independentVar_, rhs__]] := 
  With[{rule = # -> Unique[] & /@ Flatten@{independentVar}}, 
    Hold[func] /. rule // ReleaseHold]

allowNonSymbol[func : Compile[argu_List, rhs__]] := 
 With[{independentVar = 
    Replace[Unevaluated@argu, {{a_, __} :> HoldPattern@a, a_ :> HoldPattern@a}, {1}]},
   With[{rule = # -> Unique[] & /@ Flatten@{independentVar}}, 
     Hold[func] /. rule // ReleaseHold]]
allowNonSymbol[Compile[argu_, rhs__]] := allowNonSymbol[Compile[{argu}, rhs]]
sin = allowNonSymbol@Function[b[1], Sin@b[1]];
Sin[2.]
(* 0.909297 *)

It can be used on compiled function:

cf = allowNonSymbol@Compile[x[1], Sin[x@1] + Cos[x@1]];
cf[1]
(* 1.38177 *)
cf2 = allowNonSymbol@
   Compile[{x@2, {y@3, _Real}, {z@4, _Real, 2}}, x@2 + y@3 + Total@Flatten@z@4];
cf2[1, 2, {{2, 4}, {5, 6}}]
(* 20. *)
ClearAll[allowNonSymbol]
SetAttributes[allowNonSymbol, HoldAll]
allowNonSymbol[lhs_ = rhs_] := (allowNonSymbol[lhs := #1] &)[rhs]
allowNonSymbol[func_SetDelayed] := 
  With[{blank = Verbatim[#][___] & /@ (Blank | BlankSequence | BlankNullSequence)}, 
    Module[{newFunc, independentVar}, {newFunc, {independentVar}} = 
        Reap[Hold@func /. 
                var_ (holder : blank) :> 
                  RuleCondition[Sow@HoldPattern@var; Pattern[var, holder]] /. 
              var_ Verbatim[PatternTest][holder : blank, test_] :> 
                
        RuleCondition[Sow@HoldPattern@var; PatternTest[Pattern[var, holder], test]] // 
            Quiet, _, Union[#2] &]; 
      With[{rule = # -> Unique[] & /@ independentVar}, newFunc /. rule // ReleaseHold]]]

allowNonSymbol[func : Function[independentVar_, rhs__]] := 
  With[{rule = # -> Unique[] & /@ Flatten@{independentVar}}, 
    Hold[func] /. rule // ReleaseHold]

allowNonSymbol[func : Compile[argu_List, rhs__]] := 
 With[{independentVar = 
    Replace[Unevaluated@argu, {{a_, __} :> HoldPattern@a, a_ :> HoldPattern@a}, {1}]},
   With[{rule = # -> Unique[] & /@ Flatten@{independentVar}}, 
     Hold[func] /. rule // ReleaseHold]]
allowNonSymbol[Compile[argu_, rhs__]] := allowNonSymbol[Compile[{argu}, rhs]]
sin = allowNonSymbol@Function[b[1], Sin@b[1]];
Sin[2.]
(* 0.909297 *)

It can be used on compiled function:

cf = allowNonSymbol@Compile[x[1], Sin[x@1] + Cos[x@1]];
cf[1]
(* 1.38177 *)
cf2 = allowNonSymbol@
   Compile[{x@2, {y@3, _Real}, {z@4, _Real, 2}}, x@2 + y@3 + Total@Flatten@z@4];
cf2[1, 2, {{2, 4}, {5, 6}}]
(* 20. *)
ClearAll[allowNonSymbol]
SetAttributes[allowNonSymbol, HoldAll]
allowNonSymbol[Set[lhs_, rhs_]] := allowNonSymbol[SetDelayed[lhs, #]] &@rhs
allowNonSymbol[func_SetDelayed] := 
  With[{blank = Verbatim[#][___] & /@ (Blank | BlankSequence | BlankNullSequence)}, 
    Module[{newFunc, independentVar}, {newFunc, {independentVar}} = 
        Reap[Hold@func /. 
                var_ (holder : blank) :> 
                  RuleCondition[Sow@HoldPattern@var; Pattern[var, holder]] /. 
              var_ Verbatim[PatternTest][holder : blank, test_] :> 
                
        RuleCondition[Sow@HoldPattern@var; PatternTest[Pattern[var, holder], test]] // 
            Quiet, _, Union[#2] &]; 
      With[{rule = # -> Unique[] & /@ independentVar}, newFunc /. rule // ReleaseHold]]]

allowNonSymbol[func : Function[independentVar_, rhs__]] := 
  With[{rule = # -> Unique[] & /@ Flatten@{independentVar}}, 
    Hold[func] /. rule // ReleaseHold]
sin = allowNonSymbol@Function[b[1], Sin@b[1]];
Sin[2.]
(* 0.909297 *)
Add support for compiled function
Source Link
xzczd
  • 68.4k
  • 9
  • 174
  • 489
Loading
bug fixed
Source Link
xzczd
  • 68.4k
  • 9
  • 174
  • 489
Loading
bug fixed
Source Link
xzczd
  • 68.4k
  • 9
  • 174
  • 489
Loading
added 428 characters in body
Source Link
xzczd
  • 68.4k
  • 9
  • 174
  • 489
Loading
bug fixed
Source Link
xzczd
  • 68.4k
  • 9
  • 174
  • 489
Loading
Source Link
xzczd
  • 68.4k
  • 9
  • 174
  • 489
Loading