MathGroup Archive 2009

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

Search the Archive

Re: Re: Two questions about modification of a

  • To: mathgroup at smc.vnet.net
  • Subject: [mg101105] Re: [mg101057] Re: [mg101041] Two questions about modification of a
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Wed, 24 Jun 2009 06:32:19 -0400 (EDT)
  • References: <200906220822.EAA09140@smc.vnet.net>

Carl, Andrzej,

 You are totally right. This one didn't occur to me. Thanks for the hint!

Best,
Leonid


On Tue, Jun 23, 2009 at 6:04 AM, Carl Woll <carlw at wolfram.com> wrote:

> Leonid Shifrin wrote:
>
>> Hi,
>>
>> Assuming that you store your matrix in a variable <matr>, here is the
>> code:
>>
>> 1.
>>
>> MapIndexed[If[Times @@ #2 > Length[matr], 0, #1] &, matr, {2}]
>>
>> 2.
>>
>> matr /. _?Negative :> 0
>>
>> As usual in Mathematica, in both cases above the original matrix has not
>> been changed.  Rather a new copy of the matrix is created as a result.
>>
>> If your matrix is large, you can implement the 1. much more efficiently.
>> Here is the previous implementation:
>>
>> In[1] =
>> nullify[matr_?MatrixQ] :=
>>  MapIndexed[If[Times @@ #2 > Length[matr], 0, #1] &, matr, {2}]
>>
>>
>> Here is an alternative one using SparseArrays:
>>
>> In[2] =
>> nullifyFast[matr_?MatrixQ] :=
>>  Normal[SparseArray[Thread[# -> Extract[matr, #]]]] &[
>>   Flatten[Thread[{#, Range[IntegerPart[Length[matr]/#]]}] & /@
>>     Range[Length[matr]], 1]];
>>
>> Here is a test matrix:
>>
>> In[3] =
>> largeTestMatr =  RandomInteger[{-20, 20}, {400, 400}];
>>
>> Compare performance:
>>
>> In[4] =
>> (res1 = nullifyFast[largeTestMatr]); // Timing
>>
>> Out[4] =
>> {0.03, Null}
>>
>> In[5] =
>> (res2 = nullify[largeTestMatr]); // Timing
>>
>> Out[5] =
>> {2.073, Null}
>>
>> In[6] =
>> res1 == res2
>>
>> Out[6] =
>> true
>>
>> The solutions have such a dramatic difference in performance (for large
>> matrices), since the condition i*j>N is very strong and we only need to
>> keep
>> a very small (comparing to a total number of matrix elements) subset of
>> elements non - zero, and thus in the second solution we can utilize
>> efficient built-in Mathematica facilities such as SparseArrays, while the
>> first solution is very general and does not utilize the resulting matrix
>> structure.
>>
>> For the second problem, probably the easiest way to speed up code in case
>> of large matrices is to use Compile:
>>
>> nullifyNegativeCompiled =
>>   Compile[{{matr, _Real, 2}},
>>   Module[{i = 1, j = 1, new = matr},
>>    For[i = 1, i <= Length[matr], i++,
>>     For[j = 1, j <= Length[matr], j++,
>>      If[matr[[i, j]] < 0, new[[i, j]] = 0]]];
>>    new]];
>>
>> My benchmarks indicate 3-fold speed - up on <largeTestMatr>, with respect
>> to
>> a rule-based solution.
>>
>>
> A much simpler (and faster) solution is to use Clip:
>
> Clip[matrix, {0, Infinity}]
>
> Carl Woll
> Wolfram Research
>
>  Regards,
>> Leonid
>>
>>
>> On Mon, Jun 22, 2009 at 1:22 AM, Mayasky <alix.zhang at gmail.com> wrote:
>>
>>
>>
>>> Suppose there is a N*N matrix.
>>>
>>> 1. How can I change all elements that satisfy i*j>N to 0 ? (Here i, j
>>> is position of this element, as in mat[[i,j]])
>>>
>>> 2. How can I change all negative elements in that matrix to 0 ?
>>>
>>> I know a "for loop" can be used, I just wonder if there is any more
>>> concise and beautiful ways. (I doubt Mathematica doesn't have a 'find'
>>> function as in another system which conveniently returns indice of
>>> elements
>>> that satisfy a certain condition)
>>>


  • Prev by Date: Re: Re: Two questions about modification of
  • Next by Date: Almost finished - my first calculator!
  • Previous by thread: Re: Re: Two questions about modification of
  • Next by thread: Re: Two questions about modification of a matrix.