Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

sparsearray bug?

43 views
Skip to first unread message

wpb

unread,
Jul 8, 2009, 7:10:06 AM7/8/09
to
In[494]:= SparseArray[{1}]/SparseArray[{1}]

During evaluation of In[494]:= Power::infy: Infinite expression 1/0 encountered. >>
During evaluation of In[494]:= \[Infinity]::indet: Indeterminate expression 0 ComplexInfinity encountered. >>

Out[494]= SparseArray[<1>,{1},Indeterminate]

Leonid Shifrin

unread,
Jul 9, 2009, 1:50:36 AM7/9/09
to
Hi,

This seems indeed to be a bug. Here is what I think is the reason.

In[1] = SparseArray[{1}] // FullForm


Out[1] =
SparseArray[Automatic,List[1],0,List[1,List[List[0,1],List[List[1]]],List[1]]]

Look at the third element (zero). This is a default element, which is filled
for any position missed in explicit rules (when SparseArray is defined from
a set of rules position->value).

Now, in that latter case (when at least one default element is present),
it makes sense to apply whatever Listable operation is applied to an entire
array (Power[x,-1] in this case) also to the default element - but this
should
not be done in cases when all elements are indicated explicitly (and so the
default element substitution does not actually take place). Let us change a
default element to 1 in the FullForm:


In[2] =
SparseArray[Automatic,List[1],1,List[1,List[List[0,1],List[List[1]]],List[1]]]

Out[2] = SparseArray[<1>,{1},1]

In this case, no error message:

In[3] =
1/SparseArray[Automatic,List[1],1,List[1,List[List[0,1],List[List[1]]],List[1]]]

Out[3] = SparseArray[<1>,{1},1]

In[4] = Normal[%]

Out[4] ={1}

Now, we can convince ourselves that the bug is indeed related to applying
an inverse (in this case, but this may be a more general problem) to the
default element:

In[5]:= Normal[1/SparseArray[{1->1,2->2,4->5}]]

During evaluation of In[5]:= Power::infy: Infinite expression 1/0
encountered. >>

Out[5]= {1,1/2,ComplexInfinity,1/5}

Here the behavior was correct, since the default is present. However, I
would bet that the actual place where this message was generated isn't
correct - I am almost certain that it was generated before default element
substitution actually took place (but this only WRI could confirm). Now:

In[6]:= Normal[1/SparseArray[{1->1,2->2,3->4,4->5}]]

During evaluation of In[6]:= Power::infy: Infinite expression 1/0
encountered. >>

Out[6]= {1,1/2,1/4,1/5}

Here it was incorrect (in terms of error message generation at least), since
the default wasn't ever used.

Now we change the default to 1:

In[7]:= Normal[1/SparseArray[{1->1,2->2,3->4,4->5,{_}->1}]]

Out[7]= {1,1/2,1/4,1/5}

and get no error message. Here also the default wasn't actually used.
This seems to support my conjecture.


Hope this helps.

Regards,
Leonid

Bill Rowe

unread,
Jul 10, 2009, 6:41:24 AM7/10/09
to
On 7/8/09 at 7:11 AM, w.p.b...@lse.ac.uk (wpb) wrote:

>In[494]:= SparseArray[{1}]/SparseArray[{1}]

>During evaluation of In[494]:= Power::infy: Infinite expression 1/0
>encountered. >> During evaluation of In[494]:= \[Infinity]::indet:
>Indeterminate expression 0 ComplexInfinity encountered. >>

>Out[494]= SparseArray[<1>,{1},Indeterminate]

What were you expecting and why would you ever divide one sparse
array by another?

Consider for normal arrays the following:

In[3]:= x = RandomReal[1, {2, 2}]

Out[3]= {{0.980046, 0.324877}, {0.587326, 0.387608}}

In[4]:= y = RandomReal[1, {2, 2}]

Out[4]= {{0.554456, 0.960964}, {0.162428, 0.976886}}

In[5]:= x/y

Out[5]= {{1.76758, 0.338074}, {3.61592, 0.396779}}

Since the divide operation does an element by element divide you
should expect the same behavior when dividing a sparse array by
another sparse array. But by definition a sparse array has a
great many elements with value 0. So, an element by element
divide will inevitably mean dividing by 0.

Admittedly, this explanation doesn't totally explain your result
above since SparseArray[{1}] is the one element array {1}.
Possibly the code that does the element by element divide does
not look to see that SparseArray[{1}] isn't really a sparse
array in the since there are no zero elements.

But even if this is a bug (meaning the results are different
than intended) it still leaves the question of why would you be
doing this kind of division?


W.P.B...@lse.ac.uk

unread,
Jul 12, 2009, 5:46:20 AM7/12/09
to

Thanks,thisindeedseemstoexplainit.AworkaroundI=
foundis:

Withxandyvectors,use

SparseArray[x]*SparseArray[1/y]

insteadof

SparseArray[x]/SparseArray[y]

Regards,Wicher


-----OriginalMessage-----
From:LeonidShifrin[mailto:lsh...@gmail.com]
Sent:Wed8-7-200914:35
To:Bergsma,WP;math...@smc.vnet.net
Subject:Re:sparsearraybug?

Hi,

Thisseemsindeedtobeabug.HereiswhatIthink=
isthereason.

In[1]=SparseArray[{1}]//FullForm


Out[1]=SparseArray[Automatic,List[1],0,List[1,List[List[0,1],List[=
List[1]]],List[1]]]

Lookatthethirdelement(zero).Thisisadefaultel=
ement,whichisfilledforanypositionmissedinexplic=
itrules(whenSparseArrayisdefinedfrom
asetofrulesposition->value).

Now,inthatlattercase(whenatleastonedefaultel=
ementispresent),
itmakessensetoapplywhateverListableoperationisa=
ppliedtoanentirearray(Power[x,-1]inthiscase)als=
otothedefaultelement-butthisshould
notbedoneincaseswhenallelementsareindicatede=
xplicitly(andsothedefaultelementsubstitutiondoes=
notactuallytakeplace).Letuschangeadefaultelemen=
tto1intheFullForm:


In[2]=SparseArray[Automatic,List[1],1,List[1,List[List[0,1],List[L=
ist[1]]],List[1]]]

Out[2]=SparseArray[<1>,{1},1]

Inthiscase,noerrormessage:

In[3]=1/SparseArray[Automatic,List[1],1,List[1,List[List[0,1],List=
[List[1]]],List[1]]]

Out[3]=SparseArray[<1>,{1},1]

In[4]=Normal[%]

Out[4]={1}

Now,wecanconvinceourselvesthatthebugisindeed=
relatedtoapplying
aninverse(inthiscase,butthismaybeamoregen=
eralproblem)tothedefaultelement:

In[5]:=Normal[1/SparseArray[{1->1,2->2,4->5}]]

DuringevaluationofIn[5]:=Power::infy:Infiniteexpressio=
n1/0encountered.>>

Out[5]={1,1/2,ComplexInfinity,1/5}

Herethebehaviorwascorrect,sincethedefaultispres=
ent.However,Iwouldbetthattheactualplacewhere=
thismessagewasgeneratedisn'tcorrect-Iamalmost=
certainthatitwasgeneratedbeforedefaultelementsubst=
itutionactuallytookplace(butthisonlyWRIcouldcon=
firm).Now:

In[6]:=Normal[1/SparseArray[{1->1,2->2,3->4,4->5}]]

DuringevaluationofIn[6]:=Power::infy:Infiniteexpressio=
n1/0encountered.>>

Out[6]={1,1/2,1/4,1/5}

Hereitwasincorrect(intermsoferrormessagegenerat=
ionatleast),sincethedefaultwasn'teverused.

Nowwechangethedefaultto1:

In[7]:=Normal[1/SparseArray[{1->1,2->2,3->4,4->5,{_}->1}]]

Out[7]={1,1/2,1/4,1/5}

andgetnoerrormessage.Herealsothedefaultwasn't=
actuallyused.
Thisseemstosupportmyconjecture.


Hopethishelps.

Regards,
Leonid


OnWed,Jul8,2009at4:11AM,wpb<w.p.b...@lse.ac.=
uk>wrote:


=09In[494]:=SparseArray[{1}]/SparseArray[{1}]
=09
=09DuringevaluationofIn[494]:=Power::infy:Infiniteexpr=
ession1/0encountered.>>
=09DuringevaluationofIn[494]:=\[Infinity]::indet:Indeterm=
inateexpression0ComplexInfinityencountered.>>
=09
=09Out[494]=SparseArray[<1>,{1},Indeterminate]
=09
=09


Pleaseaccesstheattachedhyperlinkforanimportantelec=
troniccommunicationsdisclaimer:http://www.lse.ac.uk/collections/s=
ecretariat/legal/disclaimer.htm

wpb

unread,
Jul 12, 2009, 5:46:31 AM7/12/09
to

Dividing a SparseArray by another can be needed eg in the following
situation: A is a sparse matrix, b and c nonsparse vectors and we want
to compute A.(b/c). Seems to be best to numerically to put everything
in SparseArray form I think...


> On Jul 10, 11:41 am, Bill Rowe <readn...@sbcglobal.net> wrote:

Bill Rowe

unread,
Jul 14, 2009, 5:32:18 AM7/14/09
to
On 7/12/09 at 5:48 AM, wicher....@googlemail.com (wpb) wrote:

>Dividing a SparseArray by another can be needed eg in the following
>situation: A is a sparse matrix, b and c nonsparse vectors and we
>want to compute A.(b/c). Seems to be best to numerically to put
>everything in SparseArray form I think...

Why? I very much doubt computing b/c for two non-sparse vectors
will execute faster when b and c are made into SparseArray
objects than the obvious solution.

The advantage of a SparseArray over a normal implementation
comes from not needing to specifically store the zero elements.
If all of the elements of an array are non-zero, the storage
requirements for a the SparseArray form will be higher than the
simple list form. And whether b and c are SparseArray objects or
not, each element of b and c needs to be accessed to compute
b/c. It is hard to see how having b and c as SparseArray objects
could reduce the execution time.

The only reason I can see for not mixing SparseArray objects
with normal lists would be if Mathematica did not allow this. But

In[22]:= s =
SparseArray[Thread[Table[{n, n}, {n, 5}] -> RandomReal[1, {5}]]];
s.RandomInteger[100, {5}]

Out[23]= {24.3707,25.5166,5.77052,23.7288,15.5728}

clearly demonstrates it is acceptable to mix SparseArray objects
with normal lists.

0 new messages