[Insight-developers] RE: FunctionBase

Miller, James V (CRD) millerjv@crd.ge.com
Wed, 19 Sep 2001 07:54:10 -0400


Luis,

Should the vector classes have another "inner product" method wrt to a specified metric tensor?
Somewhere deep in the recesses of math knowledge I seem to recall using a form like

	<Mv, w> = v * M * w'
 
Should we have methods in vector and covariant vector that perform the above calculation?

Jim

-----Original Message-----
From: Luis Ibanez [mailto:ibanez@cs.unc.edu]
Sent: Tuesday, September 18, 2001 6:09 PM
To: Miller, James V (CRD); 'Damion Shelton'
Subject: Re: FunctionBase



Jim wrote
>  Luis are dot products defined on Covariant vectors?

------

Well, that's a problem...

In principle they shouldn't have a dot product, 
and the vectors either...but that's maybe too 
much of a restricion to impose on the toolkit.

The scalar product should be defined in terms of 
the metric tensor M (a matrix) of the space, 
something like:

       <v,w>  =  v * M * w'    (1)

  M = metric tensor
  v = vector
  w' = vector transposed

In cartesian coordinates M is an identiy matrix
and the scalar product is reduced to:   v * w'

and that's the same reason why vectors and 
covariant vectors are the same in cartesian 
coordinates.

but... as soon as we apply an affine transform
having non-isotropic scaling or having shearing, 
M is no longer an identiy and the product has to 
be computed as in (1). 

This definition of scalar product in (1) is the 
one that is invariant to affine transforms.

The fun thing about this is that,
if w is a contra-variant vector (a normal vector), 
(M * w') will be its covariant version.  So sometimes
the scalar product is only defined as a product
between a covariant vector and a contravariant one.

As a consequence, for example the squared Norm of 
a vector is supposed to be :  

         |w|^2    =  <w,w>  =  w * M * w'

--------

Now, to be reasonable we can just add a scalar 
product on the CovariantVector, and add a Doxygen
warning explaining that mathematically this may
not be what people expect.

It is important to double check what you
mean when you compute the scalar product on a
covariant vector, in Damion's case, he seems to
be looking for the length of the vector, and 
use the scalar product as a way of obtaining
the length .... is that right ?

In a cartesian space, that's just fine, but
it doesn't have much sense if you do it after
an affine transform...because if the coordinate
axis are not orthogonal, (x^2 + y^2) will not
give you the value of the squared diagonal,
you need to use the cosinus theorem:

      x^2 + y^2 - 2 x y cos(axis_angle)

This third term is what the matrix M is adding
to the product.

I think it is worth to double check what the 
Function classes should be doing because you 
may want to use them through affine transforms. 
If this is the case, it is important to be careful 
with the way in which covariantvectors and vectors 
are managed.


--------

I'll add the scalar operator to CovariantVector,
anyways and put a warning in Doxygen.


Luis


--------------


"Miller, James V (CRD)" wrote:
> 
> itk::Vector does have a inner product, operator*().  But apparently, the CovariantVector does not
> have an operator*().  Luis are dot products defined on Covariant vectors?
> 
> The problem that you are hitting upon is that Get_vnl_vector() returns a reference to a vnl_vector
> and hence could modify that reference.
> 
> Two options:
> 
> 1) Add a method to itk::CovariantVector
> 
>    const vnl_vector_ref<T> Get_vnl_vector( void ) const;
> 
>    that has the same implementation as Get_vnl_vector().
> 
> 2) use a const_cast before calling the dot product.
> 
>    double dotprod =
> dot_product(const_cast<vnl_vector_ref<What_ever_type>>(m_OriginGradient).Get_vnl_vector(),
> 
> const_cast<vnl_vector_ref<What_ever_type>>(vecOriginToTest).Get_vnl_vector());
> 
> -----Original Message-----
> From: Damion Shelton [mailto:dmshelto@andrew.cmu.edu]
> Sent: Tuesday, September 18, 2001 2:15 PM
> To: Miller, James V (CRD)
> Subject: RE: FunctionBase
> 
> Ok... makes sense. Actually, the ellipsoid class was written by Robert
> Tamburo, and I haven't really looked at it much - I'll let him know.
> 
> I moved the normalization into the set function, and ran into an additional
> problem.
> 
> One of the lines in ConicShell is:
> 
> double dotprod = dot_product(m_OriginGradient.Get_vnl_vector(),
> vecOriginToTest.Get_vnl_vector());
> 
> This produces the error:
> 
> Get_vnl_vector' : cannot convert 'this' pointer from 'const class
> itk::CovariantVector<double,3>' to 'class itk::CovariantVector<double,3> &'
> 
> in reference to:
> 
> m_OriginGradient.Get_vnl_vector()
> 
> So, apparently extracting a VNL vector from an ITK vector involves some
> sort of modification (or perceived modification) of the vector. Since there
> isn't yet a dot product function for itk::Vector (that I know of), I've
> been relying on VNL's functions. Any ideas?
> 
> -Damion-
> 
> --On Tuesday, September 18, 2001 2:00 PM -0400 "Miller, James V (CRD)"
> <millerjv@crd.ge.com> wrote:
> 
> > For efficiency, I would normalize on the Set call.  The trouble with this
> > is that if someone calls Set and then Get, they will get a different
> > value than they set.  So the Set method will need to be documented
> > properly and perhaps named appropriately to indicate it will normalize
> > the vector.
> >
> > The specific case I was looking at this morning was in the Ellipse code.
> > Your Evaluate() method was keeping an ivar that kept track of where a
> > point projected onto one of the axes.  This shouldn't be stored in an
> > ivar but computed by the Get method.

-- 
Luis Ibanez                                      CB#:   7060
Research Assistan Professor                      phone: (919) 843 5436
Division of Neurosurgery                         fax:   (919) 966 6627
University of North Carolina at Chapel Hill      email:
ibanez@cs.unc.edu
Chapel Hill, NC 27599-7060                      
http://www.cs.unc.edu/~ibanez