Let's say I am given a vector $v=(5,2,-2,-4,3)^T$ and $\alpha \in \{-1,1\} $. I want to find all indices $(\alpha,i)$ such that $\alpha v_i >0$, where $v_i$ is the $i$th entry of the vector $v$ given. For example, $(1,1),(-1,3)$ are possibilities. Is there a way to implement this in WM given a vector $v$ and the $\alpha$'s? I want it to output all such possibilities of $(\alpha,i)$ if possible.
3 Answers
Method 1: Calculate all products
We can calculate all the products of the terms via KroneckerProduct
and simply find where the positive ones are, and then get the right indices.
vec = {5, 2, -2, -4, 3};
indset = {-1, 1};
KroneckerProduct[indset, vec] (*"Multiply" the two lists*);
Position[%, _?Positive] (*Find where the positive results are*);
{indset[[#1]], #2} & @@@ % (*Map the indset indices to the actual values*)
{{-1, 3}, {-1, 4}, {1, 1}, {1, 2}, {1, 5}}
Method 2: Pairing Like-Sign Terms
We can also use the fact that a positive product can only result from the multiplication of like-signed terms. Therefore each of the indices of the positive entries in the non-index list necessarily have to be accompanied by each of the positive entries in the index list. Similarly for the negatives of each.
GroupBy[
Transpose@{vec, Range@Length@vec} (*{{element, index},..}*),
(*Group by the sign of the element*) Sign@*First -> Last (*Take the index*)
]
(*<|1 -> {1, 2, 5}, -1 -> {3, 4}|>*)
GroupBy[indset, Sign]
(*<|-1 -> {-1}, 1 -> {1}|>*)
Tuples[{%[#], %%[#]}] & /@ {-1, 1} // Catenate (*Every like-sign term pairs with every other like-sign term*)
{{-1, 3}, {-1, 4}, {1, 1}, {1, 2}, {1, 5}}
v = {5, 2, -2, -4, 3};
a = {-1, 1};
Select[Positive[First @ # v[[Last @ #]]] &]@Tuples[{a, Range @ Length @ v}]
{{-1, 3}, {-1, 4}, {1, 1}, {1, 2}, {1, 5}}
As noted by ubpdqn, for the particular case in OP, we can work with Sign[v]
:
MapIndexed[Flatten @* List] @ Sign @ v
{{1, 1}, {1, 2}, {-1, 3}, {-1, 4}, {1, 5}}
For this particular problem, this is essentially:
Table[{Sign[v[[j]]], j}, {j, Length[v]}]
or more outrageously:
Reap[MapThread[
Sow[#1, #2] &, {Sign[v],
Range[Length[v]]}], _, {#2[[1]], #1} &][[2]]