MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: How to use Thread when second argument to function is a list

  • To: mathgroup at smc.vnet.net
  • Subject: [mg86388] Re: How to use Thread when second argument to function is a list
  • From: Albert Retey <awnl at arcor.net>
  • Date: Mon, 10 Mar 2008 02:03:15 -0500 (EST)
  • References: <fr0cqr$eh8$1@smc.vnet.net>

Nasser Abbasi wrote:
> Hello;
> 
> I have a function which I want to call repeatedly for all rows of a matrix 
> to find non-zero elements in each row.
> This function takes as input the row number and the matrix itself and 
> returns a list that contain the non-zero elements in the that row.
> 
> i.e. function is   f[ list , matrix]:=Module[{},.....]
> 
> I want to use Thread to call this function 'f' over all the rows of the 
> matrix. Something like
> 
> Thread[  f[{1,2,3}, matrix] ]
> 
> But it is not working. I guess becuase matrix is a list of lists and it is 
> of different dimension than the list of the row numbers?
 >
> I can use MapThread, but then I have to write
> 
> MapThread[  f  {{1,2,3}, {matrix,matrix,matrix}} ]
> 
> and the above works but I have to duplicate 'matrix' to make it work, which 
> I do not like.
> 
> Here is the code that does not work
> 
> ------------------- Thread not working, why? -----------------
> 
> findNonZeroElements[row_, p_] := Module[{}, Select[p[[row,All]], #1 != 0 
> & ]]
> 
> mchain[p_] := Module[{lhs, rhs},
>    {nRow, nCol} = Dimensions[p];
>    lhs = Range[nRow];
>    Thread[findNonZeroElements[lhs, p]]      (* NOT WORKING *)
> ]
> 
> p = {{1, 0, 0, 0, 0}, {0, 0.2, 0.8, 0, 0}, {0, 0.7, 0.3, 0, 0},
>     {0.1, 0, 0.1, 0.4, 0.4}, {0, 0.1, 0.3, 0.2, 0.4}};
> 
> mchain[p]

I think your problem is that Thread only sees the evaluated expression, 
which does not even contain the call to findNoneZeroElements anymore. 
This can be seen by checking that Thread has no hold attributes:

Attributes[Thread]

or by printing e.g. row and p in findNonZeroElements. This will reveal 
that findNonZeroElements will only be called once, with all rownumbers 
and the complete matrix.

This can be corrected by using a definition for findNoneZeroElements 
which only evaluates when given the expected arguments, e.g.:

findNonZeroElements[row_Integer, p_?VectorQ]:= ...

but you will then find that Thread still works differently than what you 
expected, since findNonZeroElements will now see one row only, and can 
be changed to:

findNonZeroElements[row_Integer, p_?VectorQ] := Select[p, #1 != 0 &])

which also shows that you actually wouldn't even need to pass the row 
number along and that the following does the same thing in just a 
oneliner and without even using Thread:

Function[{row}, Select[row, #1 != 0 &]] /@ p

reading my post, I am questioning myself whether I have understood your 
problem correctly, but maybe it is still of some value...

cheers,

albert




  • Prev by Date: Re: Create pdf document from graphics
  • Next by Date: Re: Re: Assignment problem
  • Previous by thread: Re: How to use Thread when second argument to function is a list
  • Next by thread: Re: How to use Thread when second argument to function is a list