Утилита для извлечения переменных из выражения - PullRequest
9 голосов
/ 01 мая 2011

Я ищу утилиту, которая бы взяла выражение и извлекла все переменные в этом выражении.Следующие пять примеров охватывают почти все мои шаблоны переменных

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 ]

8 голосов
/ 01 мая 2011

Вот некоторый код, который я использую, чтобы получить «переменные» в различных типах выражений (списки, уравнения, неравенства и внутри числовых функций).

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}]}

Это может быть расширено для обработки большего класса выражений, например Boolean, математика с фиктивными переменными (например, Sum или Integrate), некоторые программные конструкции. Ожидайте, что острая проблема появится.

Анекдот. Еще в прошлом тысячелетии кто-то из Отдела ядра запланировал встречу, чтобы обсудить вопрос «Что такое переменная?» Это было в рамках Mathematica, а не общей математики или CS. Тем не менее, это неуловимо, потому что разные функции предъявляют разные требования к таким объектам. Я решил ответить, что в тот день я заболею (запланированной встречей). Я не помню, спрашивали ли меня, откуда я это знал заранее ...

Даниэль Лихтблау

4 голосов
/ 01 мая 2011

Очевидный (но предположительно неправильный) подход будет выглядеть так:

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]
  ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...