0
$\begingroup$

I have a very large set of equations eqs with variables denoted by capital letters like PVA[2], QA[2], etc. and small letters like ica[1,2], tr[2,3] etc. And I have variables denoted by Greek letters like alfa, beta etc. My goal is to create three lists of variables, one including only capital letters, the other only small letter etc. The order of the elements is not important but variables in the final lists should not be repeated. That is, PM[1] may appear in several equations in the system but the list of variables with capital letter should include this variable only once, no repetition. Here is an example of a system of equations to use for this simple question. Thanks.

eqs={
WF[2] WFDIST[2, 2] == (PVA[2] QA[2] \[Alpha][2, 2])/QF[2, 2],
EG[1] == PQ[1] qg[1] + PQ[2] qg[2] + tr[1, 3] + tr[2, 3],
QINT[1, 1] == ica[1, 1] QA[1],
QINT[1, 2] == ica[1, 2] QA[2],
QINT[2, 1] == ica[2, 1] QA[1],
QINT[2, 2] == ica[2, 2] QA[2],
QX[1] == QA[1] \[Theta][1, 1] + QA[2] \[Theta][2, 1],
QX[2] == QA[1] \[Theta][1, 2] + QA[2] \[Theta][2, 2],
QQ[2] == aq[2] (QD[2]^-\[Rho]q[2] (1 - \[Delta]q[2]) + 
QM[2]^-\[Rho]q[2] \[Delta]q[2])^(-(1/\[Rho]q[2]))
};
$\endgroup$
3
$\begingroup$
category[expr_] := Module[{fc = StringTake[ToString@expr, 1]},
   Which[
    MemberQ[CharacterRange["a", "z"], fc], 1,
    MemberQ[CharacterRange["A", "Z"], fc], 2,
    True, 3]];

categories[expr_] :=
 Cases[expr, _[_?NumericQ ..], Infinity] //
    Union //
   (* SortBy[#, category] & //
  SplitBy[#, category] & *)
  GatherBy[#, category] & (* EDIT: more efficient *)

eqs = {
   WF[2] WFDIST[2, 2] == (PVA[2] QA[2] α[2, 2])/QF[2, 2],
   EG[1] == PQ[1] qg[1] + PQ[2] qg[2] + tr[1, 3] + tr[2, 3],
   QINT[1, 1] == ica[1, 1] QA[1],
   QINT[1, 2] == ica[1, 2] QA[2],
   QINT[2, 1] == ica[2, 1] QA[1],
   QINT[2, 2] == ica[2, 2] QA[2],
   QX[1] == QA[1] θ[1, 1] + QA[2] θ[2, 1],
   QX[2] == QA[1] θ[1, 2] + QA[2] θ[2, 2],
   QQ[2] == 
    aq[2] (QD[2]^-ρq[2] (1 - δq[2]) + 
        QM[2]^-ρq[2] δq[2])^(-(1/ρq[2]))};

categories[eqs]

(* {{aq[2], ica[1, 1], ica[1, 2], ica[2, 1], ica[2, 2], qg[1], qg[2], 
  tr[1, 3], tr[2, 3]}, {EG[1], PQ[1], PQ[2], PVA[2], QA[1], QA[2], 
  QD[2], QF[2, 2], QINT[1, 1], QINT[1, 2], QINT[2, 1], QINT[2, 2], 
  QM[2], QQ[2], QX[1], QX[2], WF[2], 
  WFDIST[2, 2]}, {α[2, 2], δq[2], θ[1, 
   1], θ[1, 2], θ[2, 1], θ[2, 2], ρq[2]}} *)
$\endgroup$
1
$\begingroup$

Here is one option, if you don't mind converting back and forth from strings:

st = ToString[InputForm[eqs]];
st2 = StringReplace[st, Whitespace -> ""];

(* Uppercase variables *)
uppercase = 
 Union[ToExpression[
   StringCases[st2, RegularExpression["[A-Z]+\[[0-9]+,*[0-9]*\]"]]]]

 (* {EG[1], PQ[1], PQ[2], PVA[2], QA[1], QA[2], QD[2], QF[2, 2], 
 QINT[1, 1], QINT[1, 2], QINT[2, 1], QINT[2, 2], QM[2], QQ[2], QX[1], 
 QX[2], WF[2], WFDIST[2, 2]} *)


(* Lowercase variables *)
lowercase = 
 Union[ToExpression[
   StringCases[st2, RegularExpression["[a-z]+\[[0-9]+,*[0-9]*\]"]]]]

 (* {aq[2], ica[1, 1], ica[1, 2], ica[2, 1], ica[2, 2], q[2], qg[1], 
 qg[2], tr[1, 3], tr[2, 3]} *)


(* variables containing greek letters, possibly mixed with lowercase a-z *)
greek = Union[
  ToExpression[
   StringCases[st2, 
    RegularExpression[
     "[a-z]*[\[Alpha]-\[Omega]]+[a-z]*\[[0-9]+,*[0-9]*\]"]]]]

  (* {\[Alpha][2, 2], \[Delta]q[2], \[Theta][1, 1], \[Theta][1, 
  2], \[Theta][2, 1], \[Theta][2, 2], \[Rho]q[2]} *)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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