From 8905331427725871757
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,94e9c2bbb0060b48
X-Google-Attributes: gidf78e5,public
X-Google-ArrivalTime: 2002-08-25 17:10:04 PST
Return-Path: <devnull@stump.algebra.com>
X-Authentication-Warning: mulga.cs.mu.OZ.AU: fjh set sender to devnull@stump.algebra.com using -f
Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!comp-std-cpp-robomod!not-for-mail
X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov)
Delivered-To: std-c++@ncar.ucar.edu
From: ros0230@iperbole.bologna.it (Natale Fietta)
Newsgroups: comp.std.c++
Subject: Re: Proposals for small vectors?
Organization: NETTuno
Message-ID: <3d6752fb.4893595@news.iperbole.bologna.it>
References: <87bs7yps0l.fsf_-_@grue.ucsd.edu>
Reply-To: ros0230@iperbole.bologna.it
X-Trace: panco.nettuno.it 1030181947 9368 193.207.3.36 (24 Aug 2002 09:39:07 GMT)
X-Complaints-To: news@nettuno.it
NNTP-Posting-Date: 24 Aug 2002 09:39:07 GMT
X-Newsreader: Forte Free Agent 1.21/32.243
Approved: Fergus Henderson <fjh@cs.mu.oz.au>, moderator of comp.std.c++
Date: Sun, 25 Aug 2002 19:09:10 CST
Lines: 160
Xref: archiver1.google.com comp.std.c++:13374

On Mon, 19 Aug 2002 19:37:58 GMT, Walter Landry <wlandry@ucsd.edu>
wrote:

>Natale Fietta wrote:
>> 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.

>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.

Maybe i have poorly described my situation: the fact that sometime i
miswrite U=V*M instead of U=M*V is a lesser problem, the main problem
is that when i write U=V*M i want it to mean U(j)=V(i)*M(i,j) if i
select some API, but instead to mean U(j)=V(i)*M(j,i) if i select a
different API. so i think the tensorial formalism do not solve the
situation.

>> 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;

if i understand it correctly this must be Index<'k',4> k; 

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

maybe is also need C(3,k)=A(3,k); if the previous value of C is not an
homogeneous transformation.

My question: but this do not make all advantages of expression
templates not appliables ?
I do mean, if i want to do A=B*C*D*E using normal matrix
multiplication i can write (i hope tensor syntax is correct, i am
still learning this formalism) A(i,j)=B(i,k)*C(k,l)*D(l,m)*E(m,j); and
have the wonderful template optimization.
but if i use the special optimized form of multiplication implemented
with two (or three) line of code for each single multiplication it is
not possible to combine them all in a single optimizable expression,
am i wrong ?

>> 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.

Yes, it was a very poor objection, forget of it.

Sometime i also use this trick:

class MyVector
{
    float data[3];
public:
    float& x;
    float& y;
    float& z;

    MyVector() : x(data[0]), y(data[1]), z(data[2]) {}
}

Alas, this is not feasible with vectors if i want a memory layout
compatile with C API's...

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

It is only syntactic sugar, but i do prefer v.GetX() instead of
GetX(v).

>> 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'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.

This is very unfortunate, because the main reason i can convince
myself (and my coworkers) to learn and use tensors can be to take
advantage of this optimization. as far as i can actually see they do
not give other significative advantages in my application domain.

Probably a non-tensorial small-matrix library implemented to take full
advantage of expression template can be more useful for me (maybe, if
i found sufficient spare time, i can attempt to write one).

>> 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

I am starting to understand it, but it is difficult for me to get used
to this formalism, the loss of abstraction is unwanted, i usually
think of matrix multiplications as "black boxes", i bother to
understand they only when i implement the operator*, instead this
formalism force me to remember how they work each time i write an
expression, i suppose this is very unusual for people out of the
numeric community (it is surely very unusual for me).

>> 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!).  

To me it seem that this do calculate C.w three times, so it is not the
minimal number of operations ;-)

>Tensor notation is really a powerful tool.

Yes, i am fully convinced tensor are a powerful tool.
indeed i am only half-convinced they are worthwhile in my application
domain.

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

What about arrays of vectors ? as i said to Uwe Schnitker i often pass
arrays of vectors to C API's.

Regards,
Natale Fietta

---
[ 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                       ]



