From: Daniel Flatin on
I work in an environment where another system is the dominant analysis tool. In
porting some code to my preferred work environment, Mathematica, I find
that I occasionally need to reinvent functionality found in the other system. One
such function is find(). In that system, this function returns all the
non-zero indices in an array. Usually, this test array is the
consequence of a logical operation on each element, so that in the that system

indx == find(A > 3);

returns all the indices for which elements of A are greater than 3. I
have replicated this functionality in Mathematica, and I wanted to both
share it, and maybe get some input in how I could make it more
efficient or more elegant. One of the ways I learn to program in
Mathematica is to analyze all the various responses to simple questions
here, and I am hoping to steer the process here.

Here is my function:

findIndex[ array_?ArrayQ, test_ ] :== Module[
{n==Length[Dimensions[array]],idx},
idx == Cases[MapIndexed[If[test[#1],#2]&,array,{n}],{__Integer},n];
If[n====1,Flatten[idx],idx]
]

example:

(* set a *)

a ==
{{{0.08896779137,0.08522648397},{0.1162297255,0.4316697935}},{{0.6409512512,0.3506400003},{0.1156346501,0.9537010025}},{{0.8820963106,0.9962655552},{0.004333293427,0.727745896}}};

(*

get indices *)

indx == findIndex[a, 0.3 < # < 0.7&]

output:

{{1, 2, 2}, {2, 1, 1}, {2, 1, 2}}

and to verify this is a valid result:

Extract[a,indx]

returns

{0.4316697935,0.6409512512,0.3506400003}

as does

Select[Flatten[a], 0.3 < # < 0.7&]

Note that this function is quite a bit like Position[] except that it
works on results of a logical comparison rather than a pattern.
Position, on the other hand, has some a feature I view as a virtue. It
can operate on non-array objects, in fact, it can operate on non-list
objects.

If any readers has some insight into a more compact, elegant, or
Mathematica-like approach to this findIndex function, please feel free
to respond.

Anyway, thanks for your time, and in advance for your thoughts.
Dan

From: Vivek Joshi on
Unless I am missing the point. This seems similar to,

Position[a, u_/; 0.3 < u < 0.7 ]

{{1,2,2},{2,1,1},{2,1,2}}

Vivek

On 3/8/10 5:15 AM, Daniel Flatin wrote:
> I work in an environment where another system is the dominant analysis tool. In
> porting some code to my preferred work environment, Mathematica, I find
> that I occasionally need to reinvent functionality found in the other system. One
> such function is find(). In that system, this function returns all the
> non-zero indices in an array. Usually, this test array is the
> consequence of a logical operation on each element, so that in the that system
>
> indx == find(A> 3);
>
> returns all the indices for which elements of A are greater than 3. I
> have replicated this functionality in Mathematica, and I wanted to both
> share it, and maybe get some input in how I could make it more
> efficient or more elegant. One of the ways I learn to program in
> Mathematica is to analyze all the various responses to simple questions
> here, and I am hoping to steer the process here.
>
> Here is my function:
>
> findIndex[ array_?ArrayQ, test_ ] :== Module[
> {n==Length[Dimensions[array]],idx},
> idx == Cases[MapIndexed[If[test[#1],#2]&,array,{n}],{__Integer},n];
> If[n====1,Flatten[idx],idx]
> ]
>
> example:
>
> (* set a *)
>
> a ==
> {{{0.08896779137,0.08522648397},{0.1162297255,0.4316697935}},{{0.6409512512,0.3506400003},{0.1156346501,0.9537010025}},{{0.8820963106,0.9962655552},{0.004333293427,0.727745896}}};
>
> (*
>
> get indices *)
>
> indx == findIndex[a, 0.3< #< 0.7&]
>
> output:
>
> {{1, 2, 2}, {2, 1, 1}, {2, 1, 2}}
>
> and to verify this is a valid result:
>
> Extract[a,indx]
>
> returns
>
> {0.4316697935,0.6409512512,0.3506400003}
>
> as does
>
> Select[Flatten[a], 0.3< #< 0.7&]
>
> Note that this function is quite a bit like Position[] except that it
> works on results of a logical comparison rather than a pattern.
> Position, on the other hand, has some a feature I view as a virtue. It
> can operate on non-array objects, in fact, it can operate on non-list
> objects.
>
> If any readers has some insight into a more compact, elegant, or
> Mathematica-like approach to this findIndex function, please feel free
> to respond.
>
> Anyway, thanks for your time, and in advance for your thoughts.
> Dan
>
>


From: bsyehuda on
a=a = RandomReal[1, {10, 10}];

(*option 1*)
res1 = Position[a, x_ /; 0.3 < x < 0.7]
(*option 2 *)
res2=res2 = Position[a, x_?(0.3 < # < 0.7 &)]

(*option 3*)
you can also define a function

f[x_,xmin_,xmax_]:=cmin<x<xmax
res3=Position[a, x_ /; f[x]]

res1==res2==res3
returns
True

no need for more complicated code (which I usually consider less elegant)

yehuda

On Mon, Mar 8, 2010 at 1:15 PM, Daniel Flatin <dflatin(a)rcn.com> wrote:

> I work in an environment where another system is the dominant analysis
> tool. In
> porting some code to my preferred work environment, Mathematica, I find
> that I occasionally need to reinvent functionality found in the other
> system. One
> such function is find(). In that system, this function returns all the
> non-zero indices in an array. Usually, this test array is the
> consequence of a logical operation on each element, so that in the that
> system
>
> indx == find(A > 3);
>
> returns all the indices for which elements of A are greater than 3. I
> have replicated this functionality in Mathematica, and I wanted to both
> share it, and maybe get some input in how I could make it more
> efficient or more elegant. One of the ways I learn to program in
> Mathematica is to analyze all the various responses to simple questions
> here, and I am hoping to steer the process here.
>
> Here is my function:
>
> findIndex[ array_?ArrayQ, test_ ] :== Module[
> {n==Length[Dimensions[array]],idx},
> idx == Cases[MapIndexed[If[test[#1],#2]&,array,{n}],{__Integer},n];
> If[n====1,Flatten[idx],idx]
> ]
>
> example:
>
> (* set a *)
>
> a ==
>
> {{{0.08896779137,0.08522648397},{0.1162297255,0.4316697935}},{{0.6409512512,0.3506400003},{0.1156346501,0.9537010025}},{{0.8820963106,0.9962655552},{0.004333293427,0.727745896}}};
>
> (*
>
> get indices *)
>
> indx == findIndex[a, 0.3 < # < 0.7&]
>
> output:
>
> {{1, 2, 2}, {2, 1, 1}, {2, 1, 2}}
>
> and to verify this is a valid result:
>
> Extract[a,indx]
>
> returns
>
> {0.4316697935,0.6409512512,0.3506400003}
>
> as does
>
> Select[Flatten[a], 0.3 < # < 0.7&]
>
> Note that this function is quite a bit like Position[] except that it
> works on results of a logical comparison rather than a pattern.
> Position, on the other hand, has some a feature I view as a virtue. It
> can operate on non-array objects, in fact, it can operate on non-list
> objects.
>
> If any readers has some insight into a more compact, elegant, or
> Mathematica-like approach to this findIndex function, please feel free
> to respond.
>
> Anyway, thanks for your time, and in advance for your thoughts.
> Dan
>
>


From: Sjoerd C. de Vries on
Hi Dan,

Position can do this too. Two possible formats using PatternTest and
Condition respetively:

Position[a, x_?((0.3 < # < 0.7) &)]

Position[a, x_ /; (0.3 < x < 0.7)]

By the way, I don't know whether this happened because of cutting and
pasting of your code, but all your assignments use == (Equals) instead
of = (Set).

Cheers -- Sjoerd


Cheers On Mar 8, 1:15 pm, Daniel Flatin <dfla...(a)rcn.com> wrote:
> I work in an environment where another system is the dominant analysis to=
ol. In
> porting some code to my preferred work environment, Mathematica, I find
> that I occasionally need to reinvent functionality found in the other sys=
tem. One
> such function is find(). In that system, this function returns all the
> non-zero indices in an array. Usually, this test array is the
> consequence of a logical operation on each element, so that in the that s=
ystem
>
> indx == find(A > 3);
>
> returns all the indices for which elements of A are greater than 3. I
> have replicated this functionality in Mathematica, and I wanted to both
> share it, and maybe get some input in how I could make it more
> efficient or more elegant. One of the ways I learn to program in
> Mathematica is to analyze all the various responses to simple questions
> here, and I am hoping to steer the process here.
>
> Here is my function:
>
> findIndex[ array_?ArrayQ, test_ ] :== Module[
> {n==Length[Dimensions[array]],idx},
> idx == Cases[MapIndexed[If[test[#1],#2]&,array,{n}],{__Integer},n=
];
> If[n====1,Flatten[idx],idx]
> ]
>
> example:
>
> (* set a *)
>
> a ==
> {{{0.08896779137,0.08522648397},{0.1162297255,0.4316697935}},{{0.64095125=
12,0.3506400003},{0.1156346501,0.9537010025}},{{0.8820963106,0.9962655552},=
{0.004333293427,0.727745896}}};
>
> (*
>
> get indices *)
>
> indx == findIndex[a, 0.3 < # < 0.7&]
>
> output:
>
> {{1, 2, 2}, {2, 1, 1}, {2, 1, 2}}
>
> and to verify this is a valid result:
>
> Extract[a,indx]
>
> returns
>
> {0.4316697935,0.6409512512,0.3506400003}
>
> as does
>
> Select[Flatten[a], 0.3 < # < 0.7&]
>
> Note that this function is quite a bit like Position[] except that it
> works on results of a logical comparison rather than a pattern.
> Position, on the other hand, has some a feature I view as a virtue. It
> can operate on non-array objects, in fact, it can operate on non-list
> objects.
>
> If any readers has some insight into a more compact, elegant, or
> Mathematica-like approach to this findIndex function, please feel free
> to respond.
>
> Anyway, thanks for your time, and in advance for your thoughts.
> Dan


From: Bill Rowe on
On 3/8/10 at 6:15 AM, dflatin(a)rcn.com (Daniel Flatin) wrote:

>I work in an environment where another system is the dominant
>analysis tool. In porting some code to my preferred work
>environment, Mathematica, I find that I occasionally need to
>reinvent functionality found in the other system. One such function
>is find(). In that system, this function returns all the non-zero
>indices in an array. Usually, this test array is the consequence of
>a logical operation on each element, so that in the that system

>indx == find(A > 3);

>returns all the indices for which elements of A are greater than 3.
>I have replicated this functionality in Mathematica, and I wanted to
>both share it, and maybe get some input in how I could make it more
>efficient or more elegant. One of the ways I learn to program in
>Mathematica is to analyze all the various responses to simple
>questions here, and I am hoping to steer the process here.

>Here is my function:

>findIndex[ array_?ArrayQ, test_ ] :== Module[
>{n==Length[Dimensions[array]],idx}, idx ==
>Cases[MapIndexed[If[test[#1],#2]&,array,{n}],{__Integer},n];
>If[n====1,Flatten[idx],idx]
>]

>example:

>(* set a *)

>a ==
>{{{0.08896779137,0.08522648397},{0.1162297255,0.4316697935}},{{0.
>6409512512,0.3506400003},{0.1156346501,0.
>9537010025}},{{0.8820963106,0.9962655552},{0.004333293427,0.
>727745896}}};

>indx == findIndex[a, 0.3 < # < 0.7&]

>output:

>{{1, 2, 2}, {2, 1, 1}, {2, 1, 2}}

>If any readers has some insight into a more compact, elegant, or
>Mathematica-like approach to this findIndex function, please feel
>free to respond.

Elegance is somewhat subjective. But here is another approach.

In[21]:= Most[ArrayRules[SparseArray[Clip[a, {.3, .7}, {0,
0}]]]] /.
HoldPattern[a_ -> _] :> a

Out[21]= {{1, 2, 2}, {2, 1, 1}, {2, 1, 2}}

This could be made more general by replacing Clip with a
function that makes the elements you aren't interested in 0.
That function would then applied to each element using Map.