Re: style question
- To: mathgroup at smc.vnet.net
- Subject: [mg79347] Re: style question
- From: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>
- Date: Wed, 25 Jul 2007 02:08:31 -0400 (EDT)
- Organization: The Open University, Milton Keynes, UK
- References: <f84jp8$qmp$1@smc.vnet.net>
Yaroslav Bulatov wrote: > What is the recommended way of counting the number of matches in two > lists? > > The natural way would be to thread over Equal, but Equal will evaluate > before Thread gets to it. The method below works, but somehow feels > wrong > > m1 = RandomInteger[{1}, {10^5, 2, 2}]; > m2 = RandomInteger[{1}, {10^5, 2, 2}]; > matches = Thread[temporary[m1, m2]] /. temporary -> Equal; > Count[matches, True] Hi, If your question is about the general case, it is a tricky question indeed for there is no satisfactory answer that can fit all cases. Mathematica lists are highly flexible objects that can contain an arbitrary number of arbitrary expressions, expressions being lists, functions, numbers in different bases and different arithmetic models, symbol with or without values, strings, graphics, just to name a few. Moreover, lists (or expressions) within lists do not have to be of the same length and their content as well as their structure can be altered dynamically. All of this to say that the best approach in comparing list elements will depend on the structure and content of the lists to be compared. Back to your original case, where you want to compare two lists of square matrices and count by how many elements they differ, you could improve your test by using *MapThread* rather than *Tread*, which will yield a slight improvement in speed. Another strategy, faster by roughly a factor 3.5, is to compute the difference of the matrices and to count the how many null matrices there are. In[1]:= $HistoryLength = 0; m1 = RandomInteger[{1}, {10^5, 2, 2}]; m2 = RandomInteger[{1}, {10^5, 2, 2}]; Timing[matches = Thread[temporary[m1, m2]] /. temporary -> Equal; Count[matches, True]] Timing[matches = MapThread[Equal, {m1, m2}]; Count[matches, True]] Timing[matches = m1 - m2; Count[matches, {{0, 0}, {0, 0}}]] Out[4]= {0.75, 6206} Out[5]= {0.765, 6206} Out[6]= {0.25, 6206} Hope this answers your question, Jean-Marc