Re: A fast way to compare two vectors
- To: mathgroup at smc.vnet.net
- Subject: [mg121681] Re: A fast way to compare two vectors
- From: Ray Koopman <koopman at sfu.ca>
- Date: Sun, 25 Sep 2011 05:43:10 -0400 (EDT)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- References: <j5m44t$ple$1@smc.vnet.net>
On Sep 24, 7:37 pm, Yasha Gindikin <gindi... at gmail.com> wrote: > I'm looking for a hyper-fast way to compare two vectors using > Mathematica built-in functions. The problem arises in the > calculation of the Hamiltonian matrix elements of a many-particle > quantum system. > > Consider two rows of equal length n, a[[p1] and a[[p2]]. Their > elements are integers from 1 to M, put in an increasing order, > without repeats. E.g., a[[p1]] = {1,2,3,6,7,9} and a[[p2]] = > {1,2,4,7,8,9}. I need to find the number of different elements > (4 in the example) and, if this number is less or equal to 4, > their positions ((3,4) and (3,5) in the example). > The simplest way looks like this: > > diff = Intersection[a[[p1]], a[[p2]]]; > R = Dimensions[diff][[1]]; > If[R < 5, d1 = Complement[a[[p1]], diff]; > d2 = Complement[a[[p2]], diff]; > k1 = Position[a[[p1]], d1[[1]]]; k2 = Position[a[[p1]], d1[[2]]]; > k3 = Position[a[[p2]], d2[[1]]]; k4 = Position[a[[p2]], d2[[2]]]]; > > This is slow, since four search operations are used (and because > the ordering of the elements is not taken advantage of). Is there > a built-in function that quickly finds the differences between the > two vectors? > > Thank you. > Regards, > Yasha. I'm confused about what you want. The verbal description refers to "the number of different elements", which I would ordinaryily take to mean Length@Union[a1,a2], and specifies that it be <= 4. But the code checks Length@Intersection[a1,a2], the number of different values that occur in both lists, and wants it to be <= 4. The two criteria are not equivalent. poscom[a,b] assumes that a and b are sorted lists of positive integers, with no within-list duplicates. It returns the positions in a of those values that are not also in b. It is equivalent to Flatten[Position[a,#]&/@Complement[a,b]]. poscom[a_,b_] := Block[{r = ConstantArray[0,Max[a[[-1]],b[[-1]]]]}, r[[a]] = Range@Length@a; r[[b]] = ConstantArray[0,Length@b]; SparseArray[r] /. SparseArray[_,_,_,d_] :> d[[3]] ] poscom[a1,a2] poscom[a2,a1] {3,4} {3,5}