Re: [script] Comparing two transforms

Date : Mon, 15 Jan 2007 15:42:31 -0500
To : XSI(at)Softimage.COM
From : "Bernard Lebel" <3dbernard(at)gmail.com>
Subject : Re: [script] Comparing two transforms
That depends. If you test for translation first and translations are
not the same, your suggestion is the fastest.

#INFO : compare1 : 0.091
#INFO : compare2 : 0.404
#INFO : compare3 : 0.087
#INFO : compare4 : 0.058
#INFO : compare5 : 0.053
#INFO : compare6 : 1.553

However if translations are the same, then the function runs longer
and then is outperformed by compare4, which tests in the other values
first.

#INFO : compare1 : 0.364
#INFO : compare2 : 0.486
#INFO : compare3 : 0.343
#INFO : compare4 : 0.058
#INFO : compare5 : 0.134
#INFO : compare6 : 1.451

Now in a scenario where all the transforms are the same and, thus, the
full tests have to be made, compare5 wins:

#INFO : compare1 : 0.824
#INFO : compare2 : 0.481
#INFO : compare3 : 0.785
#INFO : compare4 : 0.452
#INFO : compare5 : 0.33
#INFO : compare6 : 1.459

So conclusion, I assume there is no best way to find out which one is
the fastest, as it is very contextual.

Also, no matter what, the Get2() method seems to be the slowest.



Thanks everyone for the help, that was a great discussion!

Bernard


Final script:




import time import win32com

xsi = Application
xsimath = win32com.client.Dispatch( 'XSI.Math' )




def timer( oT1, oT2, functionName, oMatrixA, oMatrixB ): time1 = time.clock()

	for i in range(1000):
		functionName( oT1, oT2, oMatrixA, oMatrixB )

	time2 = time.clock()
	xsi.logmessage( '%s : %s' % ( functionName.__name__, round(time2 -
time1, 3) ) )



def compare1( oT1, oT2, oMatrixA, oMatrixB ):

	if round( oT1.PosX, 4 ) != round( oT2.PosX, 4 ):
		return False
	elif round( oT1.PosY, 4 ) != round( oT2.PosY, 4 ):
		return False
	elif round( oT1.PosZ, 4 ) != round( oT2.PosZ, 4 ):
		return False
	elif round( oT1.RotX, 4 ) != round( oT2.RotX, 4 ):
		return False
	elif round( oT1.RotY, 4 ) != round( oT2.RotY, 4 ):
		return False
	elif round( oT1.RotZ, 4 ) != round( oT2.RotZ, 4 ):
		return False
	elif round( oT1.SclX, 4 ) != round( oT2.SclX, 4 ):
		return False
	elif round( oT1.SclY, 4 ) != round( oT2.SclY, 4 ):
		return False
	elif round( oT1.SclZ, 4 ) != round( oT2.SclZ, 4 ):
		return False
	else:
		return True



def compare2( oT1, oT2, oMatrixA, oMatrixB ):
	
	oT1.GetMatrix4( oMatrixA )
	oT2.GetMatrix4( oMatrixB )

	for i in range(0, 4):
		for j in range(0, 4):
			if round( oMatrixA.Value(i, j) ) != round( oMatrixB.Value(i,j) ):
				return False

	return True





def compare3( oT1, oT2, oMatrixA, oMatrixB ):

	if abs( oT1.PosX - oT2.PosX ) > 0.0001:
		return False
	elif abs( oT1.PosY - oT2.PosY ) > 0.0001:
		return False
	elif abs( oT1.PosZ - oT2.PosZ ) > 0.0001:
		return False
	elif abs( oT1.RotX - oT2.RotX ) > 0.0001:
		return False
	elif abs( oT1.RotY - oT2.RotY ) > 0.0001:
		return False
	elif abs( oT1.RotZ - oT2.RotZ ) > 0.0001:
		return False
	elif abs( oT1.SclX - oT2.SclX ) > 0.0001:
		return False
	elif abs( oT1.SclY - oT2.SclY ) > 0.0001:
		return False
	elif abs( oT1.SclZ - oT2.SclZ ) > 0.0001:
		return False
	else:
		return True





def compare4( oT1, oT2, oMatrixA, oMatrixB ):
	
	oT1.GetMatrix4( oMatrixA )
	oT2.GetMatrix4( oMatrixB )
	
	for i in range(0, 4):
		for j in range(0, 4):
			if abs( oMatrixA.Value(i, j) - oMatrixB.Value(i,j) ) > 0.0001:
				return False

	return True





def compare5( oT1, oT2, oMatrixA, oMatrixB ):
	
	oT1.GetMatrix4( oMatrixA )
	oT2.GetMatrix4( oMatrixB )
	
	# Test translation
	if abs( oMatrixA.Value(3, 0) - oMatrixB.Value(3, 0) ) > 0.0001:
		return False
	elif abs( oMatrixA.Value(3, 1) - oMatrixB.Value(3, 1) ) > 0.0001:
		return False
	elif abs( oMatrixA.Value(3, 2) - oMatrixB.Value(3, 2) ) > 0.0001:
		return False
	
	# Test other transforms
	elif abs( oMatrixA.Value(0, 0) - oMatrixB.Value(0, 0) ) > 0.0001:
		return False
	elif abs( oMatrixA.Value(0, 1) - oMatrixB.Value(0, 1) ) > 0.0001:
		return False
	elif abs( oMatrixA.Value(0, 2) - oMatrixB.Value(0, 2) ) > 0.0001:
		return False
	elif abs( oMatrixA.Value(1, 0) - oMatrixB.Value(1, 0) ) > 0.0001:
		return False
	elif abs( oMatrixA.Value(1, 1) - oMatrixB.Value(1, 1) ) > 0.0001:
		return False
	elif abs( oMatrixA.Value(1, 2) - oMatrixB.Value(1, 2) ) > 0.0001:
		return False
	elif abs( oMatrixA.Value(2, 0) - oMatrixB.Value(2, 0) ) > 0.0001:
		return False
	elif abs( oMatrixA.Value(2, 1) - oMatrixB.Value(2, 1) ) > 0.0001:
		return False
	elif abs( oMatrixA.Value(2, 2) - oMatrixB.Value(2, 2) ) > 0.0001:
		return False
	else:
		return True





def compare6( oT1, oT2, oMatrixA, oMatrixB ):
	
	"""
	Translation values:
	12, 13, 14
	"""
	
	aMatrix1 = oT1.Matrix4.Get2()
	aMatrix2 = oT2.Matrix4.Get2()
	
	# Test translation
	if abs( aMatrix1[12] - aMatrix2[12] ) > 0.0001:
		return False
	elif abs( aMatrix1[13] - aMatrix2[13] ) > 0.0001:
		return False
	elif abs( aMatrix1[14] - aMatrix2[14] ) > 0.0001:
		return False
	
	# Test other transforms
	elif abs( aMatrix1[0] - aMatrix2[0] ) > 0.0001:
		return False
	elif abs( aMatrix1[1] - aMatrix2[1] ) > 0.0001:
		return False
	elif abs( aMatrix1[2] - aMatrix2[2] ) > 0.0001:
		return False
	elif abs( aMatrix1[4] - aMatrix2[4] ) > 0.0001:
		return False
	elif abs( aMatrix1[5] - aMatrix2[5] ) > 0.0001:
		return False
	elif abs( aMatrix1[6] - aMatrix2[6] ) > 0.0001:
		return False
	elif abs( aMatrix1[8] - aMatrix2[8] ) > 0.0001:
		return False
	elif abs( aMatrix1[9] - aMatrix2[9] ) > 0.0001:
		return False
	elif abs( aMatrix1[10] - aMatrix2[10] ) > 0.0001:
		return False
	else:
		return True









oSel1 = xsi.selection(0)
oT1 = oSel1.Kinematics.Global.Transform

oSel2 = xsi.selection(1)
oT2 = oSel2.Kinematics.Global.Transform


oMatrixA = xsimath.CreateMatrix4() oMatrixB = xsimath.CreateMatrix4()




aFunctionNames = [ compare1, compare2, compare3, compare4, compare5, compare6 ]

for oFunctionName in aFunctionNames:
	
	timer( oT1, oT2, oFunctionName, oMatrixA, oMatrixB )








On 1/12/07, François Painchaud <francois.painchaud(at)sympatico.ca> wrote:

Le 2007-01-12 18:26, Joe Laffey a écrit : On Fri, 12 Jan 2007, Bernard Lebel wrote:

def compare4( oT1, oT2, oMatrixA, oMatrixB ):
         for i in range(0, 4):
         for j in range(0, 4):
             if abs( oMatrixA.Value(i, j) - oMatrixB.Value(i,j) ) < 0.0001:
                 return False
     return True
 Now if your are REALLY trying to make things fast, for something so short
as 16 elements you could easily unroll the loops into a series of if
statements like in the other functions. This avoids the (very slight)
overhead of setting up the loop, and reading from / writing to the iterator
variables...
 Excellent suggestion! This way, you can order the "if" statements to first
test the values that will most likely change in your homogeneous matrix: the
3 (or 4) translation values, then the 6 rotation/scaling values, then the
rest.

 François


--- Unsubscribe? Mail Majordomo(at)Softimage.COM with the following text in body: unsubscribe xsi


Search the XSI List archives here or use the advanced search form to search across mailing lists. Searching help is available.
This site supposedly brought to you by Benjamin Grosser and the Imaging Technology Group.