Page 1 of 2

Comparing arrays of the same size

Posted: 25 Mar 2012 08:40
by bxsj
I want to compare two arrays of the same length if all items contain the same value (checking a subarray of an incoming sysex string). When comparing two arrays, the result is another array containing zeroes or ones for each entry in the compared arrays, depending if they are equal or not. If all items are unequal the result of the comparison will be set to the length of the arrays (not mentioned in the manual btw :cry: ).
So far so good, but this does not tell me if all of the items in the two arrays contain the same value. I came up with the following script/routine (parameters are a and b):

Code: Select all

// compare two arrays of the same length
decl result;
decl i;

if(!sizeof(a)==sizeof(b)) return 0;  // return false when not the same length

result=(a==b);
if(firstof(result)==sizeof(result)) return 0;  // return false when all items are unequal

for(i=0;i<sizeof(result);i++) {
  if(result[i]==0) return 0;  // entry not equal return false
}

return 1;  // all equal return true
Is there a better or more elegant way to compare two arrays?

Thanks in advance,
B.

Re: Comparing arrays of the same size

Posted: 25 Mar 2012 10:56
by Macciza
Hi
You could try something like

nonnull(array1-array2)==sizeof(array1)?1:0

Based on the fact that subtracting an identical array yields an array of 0's
so nonnull of that returns the size of the array because they are all 0's
if that equals your array size it returns 1 else 0, if there is a nonnull . . .
Would also work as if then else structure, something like -

if(nonnull(array1-array2)==sizeof(array1)) return 1;
else return 0;

Left out bounds checking etc
Also the '==' comparison always returns a vector, even when all are different, never the sizeof the array
nonnull does however return the sizeof array if are all non null
Cheers
MM

Re: Comparing arrays of the same size

Posted: 25 Mar 2012 13:03
by bxsj
Thanks a lot for the info. I'm going to try it right a away.
Cheers,
B.
Edit: This script/function works like a charm :) ... arraycompare(array1,array2)

Code: Select all

// compare two arrays of the same length
if(!(sizeof(array1)==sizeof(array2))) return 0; // different length -> return false
if(nonnull(array1-array2)==sizeof(array1)) return 1;
else return 0;
Final Edit: An expression arraycompare(array1,array2):

Code: Select all

(nonnull(array1-array2)==sizeof(array1))&&(sizeof(array1)==sizeof(array2))
Lession learned - there is more than one way to skin a lemur 8-)

Re: Comparing arrays of the same size

Posted: 25 Mar 2012 16:34
by kraftf
Had the same problem when I started wit lemur and tried to script multisliders to only send the touched sliders. The nonnull function is the key to comparing arrays. Should have been mentioned in the manual with examples.
Manual needs a lot of updating in order that Lemur becomes attractive to newcomers.

Re: Comparing arrays of the same size

Posted: 29 Mar 2012 12:36
by analog604
Guys thanks for the insight. At one point I had struggled with the array comparison and did not know how to apply the nonull function. I ended up subtracting one from the other and checking the result of their sum.

if (! sumof(ARRAY1-ARRAY2) ) //TRUE if equal

Is the nonull method more efficient?

Re: Comparing arrays of the same size

Posted: 29 Mar 2012 18:00
by kraftf
analog604 wrote:Guys thanks for the insight. At one point I had struggled with the array comparison and did not know how to apply the nonull function. I ended up subtracting one from the other and checking the result of their sum.

if (! sumof(ARRAY1-ARRAY2) ) //TRUE if equal

Is the nonull method more efficient?
Nonnull actually does the same job with your approach but it certainly is more elegant.
Also the sumof(ARRAY1-ARRAY2) expression would give you an array equal in size to the arrays being compared. Nonnul(ARRAY1-ARRAY2) would give you an array sized according to the nonnull items of the comparison.

Re: Comparing arrays of the same size

Posted: 29 Mar 2012 21:58
by analog604
Both of these methods are a bit confusing to me, but having Lemur calculate using its built in function should be faster than
scripting a for() structure. Which is what my fingers initially want to type for this operation. ;)

btw- I specifically began using this to look at chunks of sysex data with a little help from subarray
basically something like the below called as function passed MIDI_ARGS by a sysex listener :

Code: Select all

//m=MIDI_ARGS as argument  targdev={0x01, 0x25} as global for DSI Mopho series
if( !sumof(subarray(m,1,3)-{0x7F,0x06,0x02}) ) {//sys non-realtime msg
 if( !sumof(subarray(m,4,2)-{targdev})) {//attempt to match device family
   mstatmsg='Inquiry response OK';
 } else { mstatmsg='SysEx Inquiry response not from DSI Mopho!';}
}
kraftf wrote: Nonnull actually does the same job with your approach but it certainly is more elegant.
Also the sumof(ARRAY1-ARRAY2) expression would give you an array equal in size to the arrays being compared. Nonnul(ARRAY1-ARRAY2) would give you an array sized according to the nonnull items of the comparison.

Re: Comparing arrays of the same size

Posted: 30 Mar 2012 07:01
by bxsj
Personally I do not like to use the sumof function to do array comparisons. Per se it returns wrong results if the same array values are compared in a different order (I know that's probably my anal approach as I make my living developing commercial software). Comparing sysex strings is the reason why I asked for an array comparison technique. The method given by Macizza works great and uses inbuilt functions. Thanks MM :mrgreen:

I've attached an unfinished template that communicates w/ my Roland V-Synth XT via sysex. It's not nearly complete, just something I am tinkering around with when I have some rare spare time. Any input on the template is highly appreciated!

Cheers,
B.

Re: Comparing arrays of the same size

Posted: 30 Mar 2012 11:52
by Macciza
Hi
Thanks bx - Quite correct about sumof being able to return 'wrong' results(compared to what you intended) due to ordering.
I tried a few other approaches but also ran into ! (not) problem where it just looks wrong and hard to read nicely.

For the sysex matching I have just used the direct approach - something like
decl VG_SYX_ID = {0x41,0,0,0,0x1C,0x12}; // but probably declared globally actually
if (subarray(MIDI_ARGS,1,6) ==VG_SYX_ID) // Roland VG99 Sysex.
Did not actually check it in Lemur but thats the basic idea. . .

Will have a bit of look at your XT project - I run a Roland VG 99 and have been testing possibilities - and putting it off . . .
Unfortunately the Sysex documentation I have is a pdf translated from Japanese . . .
That has lost it's column formatting so I need to also re-edit the doc to make it easier to read . . .
Oh and it is something like 150 pages long without any of unnecessary info or fill
And the sysex file for one patch is 5.5k, containing over 200 various size sysex messages within it
Cheers
MM

Re: Comparing arrays of the same size

Posted: 30 Mar 2012 12:53
by analog604
Ah interesting.
I had initially tried the direct '==' comparison (array == {}) and it failed to work for arrays where I had applied it.
Now it seems that I have some code to review. :oops:

Thanks guys, cheers.