[Bf-committers] Patches Submitted

wim van hoydonck wim.van.hoydonck at gmail.com
Fri Jul 22 13:32:02 CEST 2011


Hi,

On Fri, Jul 22, 2011 at 11:09 AM, Benoit Bolsee <benoit.bolsee at online.be> wrote:

> While playing around I found something else that still doesn't work: in
> the scientific literature, vectors are single column matrix, this means
> that the only correct way to multiply a vector with a matrix is to put
> it on the right side of the matrix:
> v2 = m1 * v1

This is not true.

For a matrix multiplication to work, the inner dimensions of the
matrices/vectors
must match. The size of the result is then a combination of the first
dimension of the first
matrix or vector and the second dimension of the second matrix or vector.

So, assuming m1 is a 4x4 matrix and v1 is a vector with four elements,
the following operations
are defined:

v2 = m1 * v1   gives a (4x4)x(4x1) = (4x1) vector
v3 = v1 * m1   gives a (1x4)x(4x4) = (1x4) vector
v4 = v1*transpose(m1) gives a (1x4)x(4x4) = (1x4) vector

The resulting vector v3 differs from v2.
v4 equals v2.


The following test program shows what fortran does.


$ gfortran -o mul mul.f90
$ cat mul.f90
program mul
  implicit none
  integer , parameter :: dp = selected_real_kind(p=15,r=300)
  integer :: i
  real(dp) , dimension(4,4) :: m1
  real(dp) , dimension(4) :: v1

  m1(1,:) = [ 0._dp , 0._dp ,   1._dp  , 0._dp]
  m1(2,:) = [-1._dp , 0._dp ,   0._dp  , 0._dp]
  m1(3,:) = [ 0._dp ,-1._dp ,   0._dp  , 0._dp]
  m1(4,:) = [ 0.6_dp , 0._dp , -0.05_dp , 1._dp]

  v1 = [1._dp , 2._dp , 3._dp , -4._dp]

  print *, 'matrix m1:'
  do i = 1,4
    write(*,'(4f16.10)') m1(i,:)
  end do
  print *, 'vector v1:'
  write(*,'(4f16.10)') v1

  print *, 'm1 * v1:'
  print *, matmul( m1, v1 )
  print *, 'v1 * m1:'
  print *, matmul( v1, m1 )
  print *, 'v1 x transpose(m1):'
  print *, matmul( v1 , transpose(m1) )

end program mul
$ ./mul
 matrix m1:
    0.0000000000    0.0000000000    1.0000000000    0.0000000000
   -1.0000000000    0.0000000000    0.0000000000    0.0000000000
    0.0000000000   -1.0000000000    0.0000000000    0.0000000000
    0.6000000000    0.0000000000   -0.0500000000    1.0000000000
 vector v1:
    1.0000000000    2.0000000000    3.0000000000   -4.0000000000
 m1 * v1:
   3.0000000000000000      -1.00000000000000000
-2.0000000000000000       -3.5499999999999998
 v1 * m1:
  -4.4000000000000004       -3.0000000000000000
1.2000000000000000       -4.0000000000000000
 v1 x transpose(m1):
   3.0000000000000000      -1.00000000000000000
-2.0000000000000000       -3.5499999999999998

Regards,

Wim

>
>>>> m
> Matrix((1.0, 0.0, 0.0, 0.0),
>       (0.0, 1.0, 0.0, 0.0),
>       (1.0, 0.0, -1.0, 0.0),
>       (0.0, 0.0, 0.0, 1.0))
>
>>>> v
> Vector((0.5, 0.0, 0.5, 1.0))
>
>>>> m*v
> Traceback (most recent call last):
>  File "<blender_console>", line 1, in <module>
> TypeError: Matrix multiplication: not supported between
> 'mathutils.Matrix' and 'mathutils.Vector' types
>
> But the reverse expression gives the correct result (i.e the result of m
> * v)
>
>>>> v*m
> Vector((1.0, 0.0, -0.5, 1.0))
>
> which is illogical and should be fixed. Note that this incorrect form
> has one benefit: it allows the use the shortcut expression "v*=m" to
> apply a transformation matrix on a vector.
>
> I pretty certain that I set the matrix*vector multiplication order
> correct at the same time I fixed the matrix*matrix multiplication order,
> so I don't know where this new error is coming from. Note that v*m is an
> acceptable expression if one considers that it turns v into a row
> vector, but then the result of the multiplication is different of
> course.
> In 2.49 it was possible to use both expressions m*v and v*m and they
> were producing different results, except that there were the exact
> opposite of what you should be by conventional matrix math.
>
> Campbell, can you trace back what happened with vector multiplication in
> Mathutils?
>
> /Benoit
>
> On Wed, 20 Jul 2011 20:12:50 -0500, "Scott Giese"
> <scott.giese at comcast.net> wrote:
>>
>> My reasoning for assuming this was a bug:
>>
>> 1. Previously working scripts (2.49) broke.
>>
>> 2. m1 *= m2 is equivalent to m1 = m1 * m2, where m1
>> represents the Base matrix and m2 represents the Influencing
>> matrix.  This is more intuitive to me.
>>       There is no equivalent shorthand for m1 = m2 * m1.
>>
>>       e.g. Apply a series of transforms to produce a single
>> transformation matrix
>>               contextMatrix = mathutils.Matrix()
>>               for part in parts:
>>                       contextMatrix *=
>> data.tran.matrix[part.matrix_index]
>>                       contextMatrix *=
>> data.tran.matrix[part.parent.matrix_index]
>>               ...
>>                       newObject.matrix_basis = contextMatrix
>>
>> 3. Treating leftMatrix as the Base and rightMatrix as the
>> Influencing facilitates a hypothetical method of varying
>> argument counts.
>>       e.g.  resultMatrix = Matrix.Combine(baseMatrix,
>> translateMatrix, rotationMatrix, scaleMatrix, ...)
>>
>> The above outlines my thought process.  I was not aware that
>> the change was intentional.  In light of the "... stop
>> breaking APIs?" discussion, we may be better served by
>> leaving it as-is.
>>
>> Scott
>>
>> -----Original Message-----
>> From: Campbell Barton [mailto:ideasman42 at gmail.com]
>> Sent: Wednesday, July 20, 2011 2:16 AM
>> To: bf-blender developers
>> Subject: Re: [Bf-committers] Patches Submitted
>>
>> On Wed, Jul 20, 2011 at 3:37 PM, Scott Giese <scott.giese at comcast.net>
>> wrote:
>> > Hi Gang,
>> >
>> >
>> >
>> > FYI. I submitted 3 patches for your review. ?I'm new to the
>> list and I
>> > wanted to give back to the Blender community.
>> >
>> >
>> >
>> > 28030 ?SCONS Build: Build Date reflects
>> >
>> <http://projects.blender.org/tracker/index.php?func=detail&aid
>> =28030&group_i
>> > d=9&atid=127> "1" instead of actual date of build
>> >
>> > 28031 ?Minor typo in Blenlib
>> >
>> <http://projects.blender.org/tracker/index.php?func=detail&aid
>> =28031&group_i
>> > d=9&atid=127>
>> >
>> > 28032 ?Python Mathutils: Matrix Multiplication Error
>> >
>> <http://projects.blender.org/tracker/index.php?func=detail&aid
>> =28032&group_i
>> > d=9&atid=127>
>> >
>> >
>> >
>> > Great work guys! ?Appreciate the great product.
>> >
>> >
>> >
>> > Scott
>>
>> Thanks for the fixes, committed all patches however you're
>> changes to mathutils effectively only change the order of
>> multiplication,
>>
>> http://projects.blender.org/tracker/index.php?func=detail&aid=
>> 28032&group_id
>> =9&atid=127
>>
>> In you're example
>> >>> print (m1 * m2)
>>
>> Change to...
>> >>> print (m2 * m1)
>>
>> This is a bit confusing because in C we have
>> mul_m4_m4m4(m1, m2);
>>  which is the equivalent to "m2 * m1" in python.
>>
>> A while back Benoit Bolsee was concerned our matrix
>> multiplication order was wrong so we switched it (between
>> 2.4x and 2.5x)
>>
>> What makes you think the order in blender is wrong? what's
>> you're reference?
>>
>> Just checked and we're currently doing matrix multiplication
>> differently to numpy which doesn't bode well :S - test:
>>
>> # --- snip
>> m1 = ((0.0, 0.0, 1.0, 0.0), (-1.0, 0.0, 0.0, 0.0), (0.0,
>> -1.0, 0.0, 0.0), (0.6, 0.0, -0.05, 1.0)) m2 = ((1.0, 0.0,
>> 0.0, 0.0), (0.0, 1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0,
>> -0.02, -0.1, 1.0))
>>
>> from numpy import matrix
>> n_m1 = matrix(m1)
>> n_m2 = matrix(m2)
>> print("\nnumpy\n%r" % (n_m1 * n_m2))
>>
>> from mathutils import Matrix
>> b_m1 = Matrix(m1)
>> b_m2 = Matrix(m2)
>> print("\nmathutils\n%r" % (b_m1 * b_m2))
>>
>> # --- output
>>
>> numpy
>> matrix([[ 0.  ,  0.  ,  1.  ,  0.  ],
>>         [-1.  ,  0.  ,  0.  ,  0.  ],
>>         [ 0.  , -1.  ,  0.  ,  0.  ],
>>         [ 0.6 , -0.02, -0.15,  1.  ]])
>>
>> mathutils
>> Matrix((0.0, 0.0, 1.0, 0.0),
>>        (-1.0, 0.0, 0.0, 0.0),
>>        (0.0, -1.0, 0.0, 0.0),
>>        (0.62, 0.1, -0.05, 1.0))
>>
>>
>> # --- switch m1/m2 order for both mathutils and numpy. re-run
>>
>> numpy
>> matrix([[ 0.  ,  0.  ,  1.  ,  0.  ],
>>         [-1.  ,  0.  ,  0.  ,  0.  ],
>>         [ 0.  , -1.  ,  0.  ,  0.  ],
>>         [ 0.62,  0.1 , -0.05,  1.  ]])
>>
>> mathutils
>> Matrix((0.0, 0.0, 1.0, 0.0),
>>        (-1.0, 0.0, 0.0, 0.0),
>>        (0.0, -1.0, 0.0, 0.0),
>>        (0.6, -0.0, -0.15, 1.0))
>
>
> _______________________________________________
> Bf-committers mailing list
> Bf-committers at blender.org
> http://lists.blender.org/mailman/listinfo/bf-committers
>



-- 
Avoid hangovers - stay drunk!


More information about the Bf-committers mailing list