I have a list of the form:
{1,1, (1 if x>y, -1 if y>=x), -1}
I want to count the number of 1's in the list. The output I'm looking for is something of the form:
3 if x>y
2 if y>= x
How can I achieve this?
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityI have a list of the form:
{1,1, (1 if x>y, -1 if y>=x), -1}
I want to count the number of 1's in the list. The output I'm looking for is something of the form:
3 if x>y
2 if y>= x
How can I achieve this?
countPW[ls_, pat_] := Module[{
cf = MapAt[Count[Flatten@#, pat] &, #, {{1, ;;, 1}, {2}}] &,
pwe = PiecewiseExpand[Append[Cases[_If]@ls, Cases[Except[_If]]@ls]]},
PiecewiseExpand[#, Method -> {"ConditionSimplifier" -> FullSimplify}] & @ cf @ pwe]
Examples:
list1 = {1, 1, If[x > y, 1, -1], -1};
countPW[list1, -1 | 1]
4
countPW[list1, 1] // TeXForm
$\begin{cases} 2 & x\leq y \\ 3 & \text{True} \end{cases}$
countPW[list1, -1] // TeXForm
$\begin{cases} 2 & x\leq y \\ 1 & \text{True} \end{cases}$
list2 = {1, 1, If[x > y, 1, -1], If[z > w, 1, -1], -1};
countPW[list2, -1 | 1]
5
countPW[list2, 1] // TeXForm
$\begin{cases} 2 & x\leq y\land w\geq z \\ 3 & \neg (w<z\veebar x\leq y) \\ 4 & \text{True} \end{cases}$
countPW[list2, -1] // TeXForm
$\begin{cases} 3 & x\leq y\land w\geq z \\ 2 & \neg (w<z\veebar x\leq y) \\ 1 & \text{True} \end{cases}$
list3 = {1, 1, 2, If[x > y, {1, 2, 3, -1}, -1], If[z > w, {1, 3, 4}, {2, 2, -1}], -1};
countPW[list3, 2 | -1] // TeXForm
$\begin{cases} 3 & x\leq y\land w<z \\ 6 & x\leq y\land w\geq z \\ 4 & x>y\land w<z \\ 7 & \text{True} \end{cases}$
If the conditional expression is written in the Mathematica form
expr = {1, 1, If[x > y, 1, -1], -1, If[x > y, 1, -1], -1};
then we could define a function
Clear[count]
count[expr_, patt_] := Block[{cond, alt1, alt2},
{cond, alt1, alt2} =
FirstCase[expr, item_If :> List @@ item];
If[cond,
Evaluate[Count[expr /. cond :> True, patt]],
Evaluate[Count[expr /. cond :> False, patt]]]
]
which counts the patterns in the conditional expression
count[expr, 1]
(* If[x > y, 4, 2] *)
count[expr, -1]
(* If[x > y, 2, 4] *)
Note that count
assumes, but does not check for, identical first arguments of each If
.
In no way is this the best solution, but this does the job.
l = Piecewise[{{1, x > y}, {-1, x <= y}}]
list = RandomChoice[{1, -1, l}, 5]
(*{Piecewise[{{1, x > y}, {-1, x <= y}}], -1, 1, Piecewise[{{1, x > y}, {-1, x <= y}}], -1}*)
Count[Assuming[#, Refine /@ list], 1] & /@ {x > y, x <= y}
(*3,1*)
x>y
and then if the list is already in that form,Count[list, 1]
should work. Clarity is needed as to how the list looks like. $\endgroup$