From -3171245195890368311
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,94e9c2bbb0060b48
X-Google-Attributes: gidf78e5,public
X-Google-ArrivalTime: 2002-08-19 12:39:04 PST
Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!kibo.news.demon.net!news.demon.co.uk!demon!mail2news.demon.co.uk!not-for-mail
From: Walter Landry <wlandry@ucsd.edu>
Newsgroups: comp.std.c++
Subject: Proposals for small vectors?
Date: Mon, 19 Aug 2002 19:37:58 GMT
Organization: Univ of Calif San Diego
Approved: Fergus Henderson <fjh@cs.mu.oz.au>, moderator of comp.std.c++
Message-ID: <87bs7yps0l.fsf_-_@grue.ucsd.edu>
X-Trace: mail2news.demon.co.uk 1029785883 mail2news:13147 mail2news mail2news.demon.co.uk
X-Complaints-To: abuse@demon.net
X-Mail2News-Path: news.demon.net!mulga.cs.mu.oz.au
X-Authentication-Warning: mulga.cs.mu.OZ.AU: fjh set sender to devnull@stump.algebra.com using -f
X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov)
Delivered-To: std-c++@ncar.ucar.edu
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
NNTP-Posting-Date: Mon, 19 Aug 2002 19:28:42 +0000 (UTC)
User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2
Lines: 149
Xref: archiver1.google.com comp.std.c++:13308

Natale Fietta wrote:
> The only very frequent case i mix vector and matrixes is
> vector*matrix multiplications, usually they are in the simplest
> form: U=V*M; or also V*=M;
> Note: for some API matrixes are transposed, so i must use M*V
> instead of V*M. because using the wrong multiplication order can be
> a difficult bug to find (and also a pain to write if the same
> program must be compiled for both conventions) i usually define both
> V*M and M*V to be equivalent to the only geometrically correct
> multiplication for the currently selected API.
> (i can hear mathematicians cry out with horror ;-)
> This is very different form what a general purpose library can
> reasonably do...

Well, this is where I think the tensor notation will help you.  V*M
would be something like V(i)*M(i,j), or equivalently as M(i,j)*V(i).
Similarly, M*V -> M(j,i)*V(i) or V(i)*M(j,i).  The indices keep things
in order.

> >Let me get this straight.  You have matrices of the form
> >
> >    A00 A01 A02 A03
> >A=  A10 A11 A12 A13
> >    A20 A21 A22 A23
> >      0   0   0   1
> >
> >and you want to be able to multiply it by a vector
> >
> >  B=(B0 B1 B2 B3)
> >to get C=A*B without actually doing any multiplies for the last
> >element of C.

> Not only, i also want to multiply two matrixes of this form using the
> minimal needed number of operations, like as
> C00 = A00*B00 + A01*B10 + A02*B20  instead of 
> C00 = A00*B00 + A01*B10 + A02*B20 + A03*B30

Well, you could do 

Index<'i',3> i;
Index<'j',3> j;
Index<'k',3> k;

C(i,k)=A(i,j)*B(j,k);
C(i,3)+=A(i,3);

> It is worth noting that i prefer traditional names (with a
> geometrical meaning) for vectors components, i do not access them
> using B[0] B[1] B[2] but instead i use B.x, B.y B.z; this is far
> more readable for me because i do think in terms of xyz, i am not
> interested in a vector class without the ability to access
> components with a .x or .x() or GetX() syntax or similar (the .x is
> my favourite).

I'm sure that you can add a non-member function of your own named
GetX() that does the right thing.  This would be, for the const and
non-const cases

template<class T>
double GetX(const T &t)
  {
    return t(0);
  }

template<class T>
double & GetX(T &t)
  {
    return t(0);
  }

The member functions are probably not amenable to standardization,
though.  Some people use x,y,z, some use x,y,z,t, some use t,x,y,z,
some use r,theta,phi, and still others use U,V, etc.

> Also note that often videogames console do not have very standard
> conforming C++ compilers, so a library that do not work even on
> MSVC++6 in out of my range of usefulness.  i strongly hope in a near
> future all C++ compilers can be standard conforming, but i must work
> with current compilers :-(

I'm sure that the library could be made to have the same interface and
still work with broken compilers.  It just wouldn't use expression
templates, removing some of its nice aspects.

> >  Index<'i',3> i;
> >  Index<'j',4> j;
> >  Index<'k',3> k;
> >
> >  D(i,j)=A(i,k)*B(k,j);
> >
> >and it would do the minimum number of multiplies.  In addition, this
> >D(i,j) would still work with the vector*matrix example above.

> Sorry, this tensorial formalism only confuse me... :-(

Wherever you see an index (i.e. i, j, or k), substitute a loop.  So
the previous example would be equivavlent to

for(int i=0;i<3;++i)
  for(int j=0;j<4;++j)
    {
      D(i,j)=0;
      for(int k=0;k<3;++k)
        D(i,j)=A(i,k)*B(k,j);
    }

On my website, I have a paper that talks about the library.  You only
have to read the introduction (about 2 pages) to understand tensor
notation.

> Yes, but i do also use (less often) this:
> 
>  A00 A01 A02 A03   B0
>  A10 A11 A12 A13 * B1
>  A20 A21 A22 A23   B2
>  A30 A31 A32 A33    1
> 
> performing the full multiplication and returning as result:
> Vector(C.x/C.w, C.y/C.w, C.z/C.w) //C.w is C3

In that case, you can write

Index<'i',3> i;
Index<'j',3> j;

C(i)=(A(i,j)*B(j) + A(i,3)) / (A(3,j)*B(j) + A(3,3));

And it will use the minimum number of operations (Really!).  Tensor
notation is really a powerful tool.

> The library i do dream of has some peculiarity (for example the
> mentioned V*M==M*V) that can be only cause of unexpected bugs for
> more general purpose applications...

Well, this is one thing that Tensor notation clears up.

Also, relating to POD's, for a non-constant vector C, &(C(0)) would
give you a pointer to the beginning of the vector.

Regards,
Walter Landry
wlandry@ucsd.edu

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]



