用于从表达式中提取变量的实用程序

时间:2011-05-01 05:21:56

标签: wolfram-mathematica

我正在寻找一个能够获取表达式并提取该表达式中所有变量的实用程序。 以下五个例子涵盖了我的所有变量模式

a,Subscript[a,....],Subscript[a,...][...],a[...],a[...][...]

以下是两个测试用例。

expr1 = -Log[Subscript[\[Mu], 2][]] Subscript[\[Mu], 2][] - 
   Log[Subscript[\[Mu], 2][2]] Subscript[\[Mu], 2][2] + 
   Log[Subscript[\[Beta], 1, 2][]] Subscript[\[Beta], 1, 2][] + 
   Log[2] Subscript[\[Beta], 1, 2][1] + 
   Log[Subscript[\[Beta], 1, 2][1]] Subscript[\[Beta], 1, 2][1] + 
   Log[2] Subscript[\[Beta], 1, 2][2] + 
   Log[Subscript[\[Beta], 1, 2][2]] Subscript[\[Beta], 1, 2][2] + 
   Log[Subscript[\[Beta], 2, 3][]] Subscript[\[Beta], 2, 3][] + 
   Log[Subscript[\[Beta], 2, 3][2]] Subscript[\[Beta], 2, 3][2] + 
   Log[2] Subscript[\[Beta], 2, 3][3] + 
   Log[Subscript[\[Beta], 2, 3][3]] Subscript[\[Beta], 2, 3][3];

expr2 = Log[\[Beta][{1, 2}][{}]] \[Beta][{1, 2}][{}] + 
  Log[2] \[Beta][{1, 2}][{1}] + 
  Log[\[Beta][{1, 2}][{1}]] \[Beta][{1, 2}][{1}] + 
  Log[2] \[Beta][{1, 2}][{2}] + 
  Log[\[Beta][{1, 2}][{2}]] \[Beta][{1, 2}][{2}] + 
  Log[\[Beta][{2, 3}][{}]] \[Beta][{2, 3}][{}] + 
  Log[\[Beta][{2, 3}][{2}]] \[Beta][{2, 3}][{2}] + 
  Log[2] \[Beta][{2, 3}][{3}] + 
  Log[\[Beta][{2, 3}][{3}]] \[Beta][{2, 3}][{3}] - 
  Log[\[Mu][{2}][{}]] \[Mu][{2}][{}] - 
  Log[\[Mu][{2}][{2}]] \[Mu][{2}][{2}]

On[Assert];
Assert[Union@extractVariables@expr1 === Union[Variables[expr1][[9 ;;]]]]
Assert[Union@extractVariables@expr2 === Union[Variables[expr2][[9 ;;]]]]

这是MrWizard的解决方案

extractVariables[formula_] := (
   pat = _Symbol[___][___] | Subscript[_Symbol, __][___] | Subscript[_Symbol, __] | _Symbol;
   Union@Cases[formula, pat, -1]
);

2 个答案:

答案 0 :(得分:8)

以下是我用来获取各种表达式(列表,方程式,不等式和内部数值函数)中的“变量”的一些代码。

headlist = {Or, And, Equal, Unequal, Less, LessEqual, Greater, 
   GreaterEqual, Inequality};

getAllVariables[f_?NumericQ] := Sequence[]
getAllVariables[{}] := Sequence[]
getAllVariables[t_] /; MemberQ[headlist, t] := Sequence[]

getAllVariables[ll_List] := 
 Flatten[Union[Map[getAllVariables[#] &, ll]]]

getAllVariables[Derivative[n_Integer][f_][arg__]] := 
 getAllVariables[{arg}]

getAllVariables[f_Symbol[arg__]] := 
 Module[{fvars}, 
  If[MemberQ[Attributes[f], NumericFunction] || MemberQ[headlist, f], 
   fvars = getAllVariables[{arg}],(*else*)fvars = f[arg]];
  fvars]

getAllVariables[other_] := other

提供测试的一个例子:

在[36]中:= getAllVariables [expr2]

Out [36] = {[Beta] [{1,2}] [{}],[Beta] [{1,2}] [{1}],[Beta] [{1,     2}] [{2}],[Beta] [{2,3}] [{}],[Beta] [{2,3}] [{2}],[Beta] [{2,     3}] [{3}],[Mu] [{2}] [{}],[Mu] [{2}] [{2}]}

这可以扩展到处理更大类的表达式,例如布尔值,带虚拟变量的数学(例如Sum或Integrate),一些程序构造。期待棘手的问题出现。

轶事:回到上一个千禧年,核心部门的某个人安排了一次会议,讨论“什么是变量?”的问题。这是在Mathematica的背景下,而不是一般数学或CS。同样,这是一个难以捉摸的事情,因为不同的功能似乎对这些实体有不同的要求。我自己的看法是回答我那天(预定的会议)会生病。我不记得是否有人问过我之前是怎么知道的......

Daniel Lichtblau

答案 1 :(得分:4)

明显(但可能是不正确的)方法是:

pat = _Symbol[___][___] | Subscript[_Symbol, __][___] |  Subscript[_Symbol, __] | _Symbol;

Cases[expr1, pat, -1]
Cases[expr2, pat, -1]

但坦率地说,我不明白你的问题,不知道出了什么问题。


如果这对您有效,那么我建议:

extractVariables[formula_] := 
  With[{pat = _Symbol[___][___] | Subscript[_Symbol, __][___] | Subscript[_Symbol, __] | _Symbol},
    Union@Cases[formula, pat, -1]
  ]