Topic: Proposals for small vectors?


Author: wlandry@ucsd.edu (Walter Landry)
Date: Fri, 6 Sep 2002 15:35:07 +0000 (UTC)
Raw View
John Nagle <nagle@animats.com> writes:
>     Yes.  My point was not that I wanted to change the meaning of
> operations.  It's that I wanted the ability to change the
> underlying representation easily to match lower-level APIs.
> Users of these objects don't see the underlying representation
> unless they explicitly ask for it.

Well, I've updated my tensor library so that Tensor2's (matrices, for
those who don't think in terms of tensors) can have the storage order
optionally specified.  It was a lot easier than I initially feared.

>     I'm also trying not to get sucked into the "POD" morass.
> My general position is that these small matrix/vector objects
> need not be PODs, but should, on request, return a pointer to
> a POD.  Think of how STL "string" offers a ".data()" member
> function, which returns a C string.

Agreed.  To get the pointer to the data, you just do &v(0) for
Tensor1's (vectors), and &m(0,0) for Tensor2's (matrices).

>     (For example, I have an application which has a graphics
> API, an interface to an animation system, a collision detection
> system, a convex hull system, and a physics system, all of which
> have incompatible representations for small vectors and matrices.
> This is all too common in game, animation, and simulation work.)

Would the tensor library be useful for you, or does the extra
complication seem like too much overhead?  I'm still trying to get a
feel for whether it is useful to pursue it as a standard.  I haven't
gotten a lot of good feedback.  No bad feedback, just no "This is
great and solves all of my problems" kind of feedback.  If the
graphics people are not happy with it, then it probably doesn't have a
chance of getting standardized.

By the way, does anyone know whether this sort of thing is
standardized for Java or C#?

Thanks,
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                       ]





Author: Walter Landry <wlandry@ucsd.edu>
Date: Sun, 1 Sep 2002 13:43:08 CST
Raw View
Noah Stein wrote:
>"Walter Landry" <wlandry@ucsd.edu> wrote in message
>> Another thing that I should mention is that this tensor notation
>> solves the problem of what happens when you multiply two vectors
>> together.  Does U*V give an inner product, an outer product, or a
>> cross product?  Tensor notation makes it clear which one is happening.
>
>Yes, tensor notation succinctly states what is going on in the vector
>operation; however, it doesn't solve the poster's original problem.  The
>original poster's problem wasn't that he couldn't remember the operation
>being performed, his problem is that he couldn't know at the code-time which
>variation of vectors he was using: row-major or column-major.  Different
>graphics APIs use different layouts.  He wouldn't know until
>compilation-time which format was used, thus, he suggested that V*M would
>transparently become M*V for those environments that were of the opposite
>orientation.  It's nice for graphics, but as I already said, I think it's a
>very dangerous construct as presented.

Ah, I see what is going on.  This is why John Nagle's valmatrix code
allows column-major or row-major storage, depending on a template
parameter.  Certainly that could be added to the tensor code, it just
isn't there now.  Patches always welcome.

>> The sort of thing that you're talking about is already implemented in
>> the TinyVector class in Blitz.  It doesn't know about homogeneous
>> transforms, but it does handle vector and matrix multiplication in a
>> non-tensorial way.  And no, it doesn't work with MS VC 6.0.  I don't
>> think that expression templates really work in MS VC 6.0.  I'm open to
>> existence proofs of the contrary though...
>
>Not true about VC6.  I've done it (under sp3 and later).

You've gotten Blitz to work under VC6, or you've gotten some kind of
expression templates to work?  I suspect it is the latter.  In any
case, you da man.  However, making a *general purpose*, high
performance matrix library without partial specialization sounds
painful, if not outright impossible.

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                       ]





Author: "Noah Stein" <noah@a-c-m.org>
Date: Mon, 2 Sep 2002 03:12:51 CST
Raw View
"Walter Landry" <wlandry@ucsd.edu> wrote in message
news:87d6rxwoti.fsf@grue.ucsd.edu...

> You've gotten Blitz to work under VC6, or you've gotten some kind of
> expression templates to work?  I suspect it is the latter.  In any
> case, you da man.  However, making a *general purpose*, high
> performance matrix library without partial specialization sounds
> painful, if not outright impossible.

Noooo.... I haven't even considered trying to port Blitz to VC6.  I've
written a working expression template engine for vectors and matrices.  You
need to plan around the fact that there's no PTS or you're going to have a
nightmare.  Non-PTS implementations have many more support classes to
function properly.  Most constructs can be implmented without PTS.  Some
port very poorly, but they are just not extensible.  Supporting new classes
requires modifying the library code because some workarounds for PTS require
compile-time switch statements.  A new class to consider is a new case for
the switch deep in the bowels of the machinery.

I'd say it's quite possible to have an efficient library without PTS.  I've
examined the assembly output of the fully optimized version under VC6.  The
compiler can make some very tight code.  I assume that GCC should also put
out some fast code, too.

What do you think PTS is necessary for?  I'm wondering if maybe I'm just
looking at the needs I've always had and that I might be overlooking
everybody else's needs.  The only part of the code base that really suffers
so far as I've seen is type promotion.  PTS might be necessary to
effectively deal with specializations for supporting math hardware such as
MMX and SSE on Pentiums or Altivec on the MIPS architecture.  I'm not
convinced that this last statement is true, though.

This is all probably for naught anyhow since by the time any sort of small
vector would become standardized, non-PTS compilers will be few and far
between.  Hopefully that's more than a dream.  :)


-- Noah


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





Author: John Nagle <nagle@animats.com>
Date: Mon, 2 Sep 2002 03:12:59 CST
Raw View
Walter Landry wrote:

> Noah Stein wrote:
>
>>"Walter Landry" <wlandry@ucsd.edu> wrote in message
>>
>>>Another thing that I should mention is that this tensor notation
>>>solves the problem of what happens when you multiply two vectors
>>>together.  Does U*V give an inner product, an outer product, or a
>>>cross product?  Tensor notation makes it clear which one is happening.
>>>
>>Yes, tensor notation succinctly states what is going on in the vector
>>operation; however, it doesn't solve the poster's original problem.  The
>>original poster's problem wasn't that he couldn't remember the operation
>>being performed, his problem is that he couldn't know at the code-time which
>>variation of vectors he was using: row-major or column-major.  Different
>>graphics APIs use different layouts.  He wouldn't know until
>>compilation-time which format was used, thus, he suggested that V*M would
>>transparently become M*V for those environments that were of the opposite
>>orientation.  It's nice for graphics, but as I already said, I think it's a
>>very dangerous construct as presented.
>>
>
> Ah, I see what is going on.  This is why John Nagle's valmatrix code
> allows column-major or row-major storage, depending on a template
> parameter.  Certainly that could be added to the tensor code, it just
> isn't there now.  Patches always welcome.


    Yes.  My point was not that I wanted to change the meaning of
operations.  It's that I wanted the ability to change the
underlying representation easily to match lower-level APIs.
Users of these objects don't see the underlying representation
unless they explicitly ask for it.

    I'm also trying not to get sucked into the "POD" morass.
My general position is that these small matrix/vector objects
need not be PODs, but should, on request, return a pointer to
a POD.  Think of how STL "string" offers a ".data()" member
function, which returns a C string.

    This is all very practical; it's about making up the
matrices that graphics and game APIs need.  The motivation
behind all this is that there are many libraries that use
order 2, 3, and 4 vectors and matrices, many applications
use more than one of these libraries, and lack of standarization
prevents these libraries from interoperating cleanly.

    (For example, I have an application which has a graphics
API, an interface to an animation system, a collision detection
system, a convex hull system, and a physics system, all of which
have incompatible representations for small vectors and matrices.
This is all too common in game, animation, and simulation work.)

     John Nagle
     Animats

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





Author: kuyper@wizard.net ("James Russell Kuyper Jr.")
Date: Tue, 3 Sep 2002 00:13:34 +0000 (UTC)
Raw View
Noah Stein wrote:
....
> port very poorly, but they are just not extensible.  Supporting new classes
> requires modifying the library code because some workarounds for PTS require
> compile-time switch statements.  A new class to consider is a new case for
> the switch deep in the bowels of the machinery.
....
> What do you think PTS is necessary for?

To avoid those problems, among other reasons. To work properly, it
should handle arbitrary classes.

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





Author: "Noah Stein" <noah@a-c-m.org>
Date: 31 Aug 2002 12:25:04 GMT
Raw View
"Walter Landry" <wlandry@ucsd.edu> wrote in message
news:87lm6ttfik.fsf@grue.ucsd.edu...

> This sounds like you want to change the meaning of V*M depending on
> something that is not visible in the code itself (i.e. what library
> you are using).  I don't think that is a good idea.

I agree that changing the dynamics of V*M is very dangerous from a
mathematical stand-point.  Please see my response to the next paragraph.
Even in the specific context given in the original post (games), there's a
giant potential for problems.  A physics programmer will be easily
frustrated if his vector-matrix multiplication is defined differently on two
platforms, with one of them not being the mathematically-correct definition.

> Another thing that I should mention is that this tensor notation
> solves the problem of what happens when you multiply two vectors
> together.  Does U*V give an inner product, an outer product, or a
> cross product?  Tensor notation makes it clear which one is happening.

Yes, tensor notation succinctly states what is going on in the vector
operation; however, it doesn't solve the poster's original problem.  The
original poster's problem wasn't that he couldn't remember the operation
being performed, his problem is that he couldn't know at the code-time which
variation of vectors he was using: row-major or column-major.  Different
graphics APIs use different layouts.  He wouldn't know until
compilation-time which format was used, thus, he suggested that V*M would
transparently become M*V for those environments that were of the opposite
orientation.  It's nice for graphics, but as I already said, I think it's a
very dangerous construct as presented.


> The sort of thing that you're talking about is already implemented in
> the TinyVector class in Blitz.  It doesn't know about homogeneous
> transforms, but it does handle vector and matrix multiplication in a
> non-tensorial way.  And no, it doesn't work with MS VC 6.0.  I don't
> think that expression templates really work in MS VC 6.0.  I'm open to
> existence proofs of the contrary though...

Not true about VC6.  I've done it (under sp3 and later).


-- Noah


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





Author: Walter Landry <wlandry@ucsd.edu>
Date: Tue, 27 Aug 2002 00:08:11 GMT
Raw View
>Natale Fietta wrote:

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

This sounds like you want to change the meaning of V*M depending on
something that is not visible in the code itself (i.e. what library
you are using).  I don't think that is a good idea.

Another thing that I should mention is that this tensor notation
solves the problem of what happens when you multiply two vectors
together.  Does U*V give an inner product, an outer product, or a
cross product?  Tensor notation makes it clear which one is happening.

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

Yes.  Sorry.  In my code, I generally use a,b,c,d... for four
dimensional indices and i,j,k,l... for three dimensional indices.

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

C should be a 3x4 matrix, so it wouldn't be able to hold a 4x4 matrix.
If you accidently tried to do what you wrote above, then a build
compiled with FTENSOR_DEBUG defined would throw an out of bounds
error during runtime.

However, if you decided to use a 4x4 matrix for a homogeneous
transform, everything I've written before will still work.  It will
just be carrying around 4 extra numbers.  Also, you won't get an out
of bounds error.  Only if you wanted a simple expression (like the one
just below) would you need to explicitly set the fourth row.

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

Yes, you're right.  If you want the absolute minimum number of
multiplies, you have to manually create the temporaries with something
like

  tmp1(i,a)=B(i,k)*C(k,a);
  tmp1(i,3)+=B(i,3);
  tmp2(i,a)=tmp1(i,l)*D(l,a);
  tmp2(i,3)+=tmp1(i,3);
  A(i,a)=tmp2(i,m)*E(m,a);
  A(i,3)+=tmp2(i,3);

Readability does suffer, and the ordering of operations of operations
is different from what a special purpose library would use.  That
could make it faster or slower.  It would probably depend on the
compiler.

Hmm.  It seems like tensor notation can handle some of your needs, but
full support for homogeneous transforms is not something that can be
really accomodated in a standard.  However, it still seems that a
useful subset can be standardized.

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

You should be aware that optimization really varies among compilers,
and I don't think any compiler will optimize all cases.  The paper on
my website looks at this in some detail (see page 32 for the summary
graph).  One of the nice things about the library is that, if the
compiler does fail to optimize a particular expression, you can still
go in and write out the particular expression by hand.

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

The sort of thing that you're talking about is already implemented in
the TinyVector class in Blitz.  It doesn't know about homogeneous
transforms, but it does handle vector and matrix multiplication in a
non-tensorial way.  And no, it doesn't work with MS VC 6.0.  I don't
think that expression templates really work in MS VC 6.0.  I'm open to
existence proofs of the contrary though...

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

Nope.  It only calculates C.w==(A(3,j)*B(j) + A(3,3)) once.  That is
just a benefit of using classes, instead of enclosing everything in
for() loops.

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

Well, Tensor<> is a class, so you can't really make an array of
Tensor's and treat them as an array of pointers.  However, it has
trivial copy and destruction operators.  Its non-trivial constructors
are for convenience only.  Also, sizeof(Tensor1<T,N>)=sizeof(T)*N, at
least here on my linux laptop.  I'm not sure if that answers your
question, though.

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                       ]





Author: John Nagle <nagle@animats.com>
Date: Tue, 27 Aug 2002 12:17:27 CST
Raw View
    For a more concrete discussion on this subject, see
my previous message under "I am writing vector/matrix
classes".  Thanks.

    John Nagle
    Animats

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





Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: 23 Aug 2002 10:25:18 GMT
Raw View
On Tue, 20 Aug 2002 18:47:50 GMT, "Noah Stein" <noah@a-c-m.org> wrote:

>I'm in the same field as you: video games, but I've noticed that my needs,
>as well as those of others I know, varies from yours.

The world is beautiful because it is so varied :-)

Anyhow i was only pointing out my most unusual needs, it is not
necessary to bother the C++ communitiy with all little details of my
application domain...

>I've also used a number of 2x2 and 3x2 matrices.  There are a number of
>computations that occur in the plane, and I much prefer not to "just ignore
>z".  A 3x3 matrix now has two roles: a homogeneous 2d transform as well as a
>3d transform.

I've never used 3x2 matrixes, interesting to know that someone find
these useful. i was unsing 2x2 and 3x3 homo 2D in the past, i dont use
them anymore, when i do make computations on a plane the plane can be
inclinated so i dont want to ignore any coordinate.

>however, in a general
>n-dimensional setting, writing a version that works with VC6 will definitely
>be a chore.

Sorry, my english dictionary do not list the word "chore" what is the
meaning of the term ?

> And I do have use for dense matrices beyond 4x4, so it seems
>quite a shame to give up n-dimensionality for just 2d, 3d, and 4d.

I dont want to gave up n-dimensionality, i do want a different and
more optimized version for some widely used little dimensions.
If the optimized version can be made compatible with the more general
version this is an added bonus, but i can live without it.

>> It is also worth noting that for us 4x4 matrixes represent homogeneous
>> coordinates transformations, so they always have the last row (or
>> column) as 0,0,0,1;

>I know a few people, in the same industry as you, who have found this
>assumption to have thrown a giant monkey wrench in their plans.  There are a
>number of developers who use the perspective row (column).  I think as a
>general rule, this assumption would be a huge mistake to include.

Yes, i was over-simplifiying for the sake of the general discussion,
obviously i do also use the perspective row, so i use different
multiplication implementation for perspective and non-perspective
transformations.
This has never caused bugs to me, i do use different matrix classes
for perspective and non-perspective transformation, so i do have for
example: PerspMatrix operator*(AnimMatrix, PerspMatrix);
and the compiler will trigger an error if i erroneously assign the
result to an AnimMatrix (i dont have implicit conversions from
PerspMatrix to AnimMatrix).

>> Also we often use 3-vector to represent normalized 4-vector in
>> homogeneous coordinates, so we can multiply a 3-vector by a 4x4 matrix
>> and obtain another 3-vector as result. (i suppose this sound very odd
>> to mathematicians).
>
>This is another dangerous idea IMHO.  Whether a vector represents a vector
>or a point makes a big difference in its handling with a homogeneous matrix.
>I would like to avoid jumping through hoops to deal with the issues of "is
>this vector actually a point?".  That would be a giant source of bugs.

Yes, i do know, i use different "vector" classes for points and
normals and versors. as for the previous issue i dont have mentioned
it because to me it seem not significative in the general discussion.

>> Probably my (ours ?) needs are too specific to be adressed by the
>> standard C++ library...
>
>I don't think your (our) needs are too specific.  I think, though, that to
>have those needs met requires a significant amount of thoughtful design, not
>an insurmountable amount.

What do you think of tensorial formalism ?
I am learning it, and i am only half-convinced that it can be useful
to implement the library i dream of.

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                       ]





Author: "Stephen Howe" <SPAMstephen.howeGUARD@tnsofres.com>
Date: Fri, 23 Aug 2002 22:26:39 GMT
Raw View
> Sorry, my english dictionary do not list the word "chore" what is the
> meaning of the term ?

An unpleasant task, something you woudl rather not do (particularly if it
can be automated)

Stephen Howe


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





Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Sun, 25 Aug 2002 19:09:10 CST
Raw View
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                       ]





Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Sun, 18 Aug 2002 17:47:18 GMT
Raw View
On Fri, 16 Aug 2002 12:42:33 GMT, John Nagle <nagle@animats.com>
wrote:

>     I never insisted that such objects necessarily be
>POD (plain old data.)  I only insisted that they contain
>and return upon request plain old data in a recognized
>order. for use with interfaces which need it.  Think of
>the facility provided for type "string" now:
>
> string s;   // is not a POD
> ...
> const char* p = s.data(); // returns a POD
>
>That compromise works well for strings.

I also think it can work well on matrixes.

The problem is with array of vectors, it is both inconvenient and
inefficient to copy them in a temporary array of PODs each time we
need to pass them to a C-API.

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                       ]





Author: Walter Landry <wlandry@ucsd.edu>
Date: Mon, 19 Aug 2002 19:37:58 GMT
Raw View
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                       ]





Author: "Noah Stein" <noah@a-c-m.org>
Date: Tue, 20 Aug 2002 18:47:50 GMT
Raw View
I'm in the same field as you: video games, but I've noticed that my needs,
as well as those of others I know, varies from yours.  I've outlined the
differences:

> Also we use very few matrix sizes: in modern days pratically only 4x4
> and occasionally 3x3 (also 3x4 or 4x3 as a space-optimized form of
> 4x4).

I've also used a number of 2x2 and 3x2 matrices.  There are a number of
computations that occur in the plane, and I much prefer not to "just ignore
z".  A 3x3 matrix now has two roles: a homogeneous 2d transform as well as a
3d transform.  Per se, it's not an issue since the vector types are
different when writing the mutliplications; however, in a general
n-dimensional setting, writing a version that works with VC6 will definitely
be a chore.  And I do have use for dense matrices beyond 4x4, so it seems
quite a shame to give up n-dimensionality for just 2d, 3d, and 4d.

> It is also worth noting that for us 4x4 matrixes represent homogeneous
> coordinates transformations, so they always have the last row (or
> column) as 0,0,0,1; this is very important because we use optimized
> matrix*matrix and vector*matrix multiplications to take advantage of
> these constant values.

I know a few people, in the same industry as you, who have found this
assumption to have thrown a giant monkey wrench in their plans.  There are a
number of developers who use the perspective row (column).  I think as a
general rule, this assumption would be a huge mistake to include.

> Also we often use 3-vector to represent normalized 4-vector in
> homogeneous coordinates, so we can multiply a 3-vector by a 4x4 matrix
> and obtain another 3-vector as result. (i suppose this sound very odd
> to mathematicians).

This is another dangerous idea IMHO.  Whether a vector represents a vector
or a point makes a big difference in its handling with a homogeneous matrix.
I would like to avoid jumping through hoops to deal with the issues of "is
this vector actually a point?".  That would be a giant source of bugs.


> Probably my (ours ?) needs are too specific to be adressed by the
> standard C++ library...

I don't think your (our) needs are too specific.  I think, though, that to
have those needs met requires a significant amount of thoughtful design, not
an insurmountable amount.


-- Noah


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





Author: Walter Landry <wlandry@ucsd.edu>
Date: Sat, 10 Aug 2002 11:46:39 GMT
Raw View
Natale Fietta wrote:
>> Do you usually have a lot of small, simple equations?

> Please, define "simple equation".

What I meant is do your equations tend to look like

  A=B*C;
  D=A+E*F;

or is it more like

  A=(B*C + D*F)/(B*E - D*B) + B*B - F*C;

That is, do the operations tend to separate out between statements, or
are there a lot of operations clustered together.  Optimizing the
first kind is simple, and almost any approach will work.  For the
second kind, only expression templates will really help.  Even then,
results can vary.

>> Do you always know the size of the vectors and matrices at compile time?

> Absolutely YES !

> Also we use very few matrix sizes: in modern days pratically only
> 4x4 and occasionally 3x3 (also 3x4 or 4x3 as a space-optimized form
> of 4x4).

> It is also worth noting that for us 4x4 matrixes represent
> homogeneous coordinates transformations, so they always have the
> last row (or column) as 0,0,0,1; this is very important because we
> use optimized matrix*matrix and vector*matrix multiplications to
> take advantage of these constant values.

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.  Hmm.  That I can not do.  What I could do is something
like

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

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

Where the template parameter '3' for Index 'i' is so that only the
first three elements of C are computed.

For matrix*matrix operations, if you're using 3x4 matrices, you could
do something like

  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.

> Also we often use 3-vector to represent normalized 4-vector in
> homogeneous coordinates, so we can multiply a 3-vector by a 4x4
> matrix and obtain another 3-vector as result. (i suppose this sound
> very odd to mathematicians).

I think you want to be able to multiply

  A00 A01 A02 A03   B0
  A10 A11 A12 A13 * B1
  A20 A21 A22 A23   B2
    0   0   0   1    1

without storing that last B3=1.  Instead of simply

  C=A*B

you would have to do something like

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

> I am unsure a general matrix-vector library can be useful for me, i
> use only 3-vectors and 4x4 homogeneous matrixes, and i want a lot of
> specific optimizations, so a very specialized library can be far
> more useful.

Well, it seems like you can do most of what you need with a general
tool.  I will admit that it is not quite as simple as a specialized
library.  In cases where this matters, though, it shouldn't be
difficult to define your own inline functions.  It will at least free
you from having to construct the basic operations.

If, as John Nagle says, the algebra3 library is considered useful,
then a more powerful and flexible interface with equivalent
optimizations should work fine for most people.

I've also rooted around the Quake II source code a little, and it
seems like that code in particular could benefit greatly from a
standard vector and matrix toolkit.

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                       ]





Author: schnitker@sigma-c.com (Uwe Schnitker)
Date: Mon, 12 Aug 2002 16:43:44 GMT
Raw View
ros0230@iperbole.bologna.it (Natale Fietta) wrote in message news:<3d538392.2753209@news.iperbole.bologna.it>...
> On Wed,  7 Aug 2002 23:07:53 GMT, schnitker@sigma-c.com (Uwe
> Schnitker) wrote:
>
> >My question: Is it also important to you to be able to pass a lot of those
> >small matrices or vectors to a C-API which requires array-like storage?
>
> Often It is necessarty to be able to pass an array of valvectors to a
> C-API and often it is necessary to use array of structs containing one
> or more valvectors plus other datas (for example colors and/or texture
> informations),

Ok, you confirmed my suspicion and provided further evidence. With regard
to the rank 1 - vector - case, at least.

> in both cases i think valvectors must be POD.

Well, "must" is a strong word. If you don't care about what the C++
standard guarantees, you could use a class which is only "almost" a
POD. It is, e.g., hard to imagine why and how a C++ compiler would
change the data layout of a POD if you just add a simple constructor.
But I'd care enough not to rely on such undefined, or at best
implementation-defined, behavior.

> Instead it is not so common to pass arrays of matrixes, so i think
> matrixes can be non-POD (if this buy some advantage)
> with a fast member function to access the underlying representation.

Of course it does. You can use contructors. You may even design them as
base classes, or derive them from other classes. You can use "canonic"
policies ... ...

So this would be one reason not to regard the vector case as just the 1xn
or mx1 case of the matrix.

> >I could imagine that you might have hardware specific functions, e.g. to
> >multiply one transformation matrix with a lot of vectors.
>
> Yes, there is a wide variety of specific hardware functions, but
> sometimes (often) they work only on specific memory, and in this case
> it is very slow to retrive results, so when results are need for
> further software processing (instead of further hardware processing)
> it is usual to transform them in software.
>
> >Please read my other posting in this thread were I consider whether to make
> >the small matrix / vector class a POD. There I describe a usage example.
> >
> >I'd really like to know if my example is based on a realistic scenario.
>
> Well, as i explained in previous paragraphs your example is not the
> more frequent situation i see...

OK, now I understand. I was trying to imagine whether such hardware issues
would make the C-array compatibillity even more important. But, as you
explained above, it is important anyway. (For valvectors, not valmatrices.)

> [cut&paste from your other message]
> > Also note that I mentioned writing things like
> >   valmatrix<double,1,3> vm = {2.0,3.0,4.0};
> > which requires valmatrix<double,1,3> to be an aggregate.
>
> I've never had the need to inizialize matrixes this way (instead it is
> important to be able to do this for vectors),

Here we have again the difference between the matrix and the vector case.
It's quite interesting. More than I'd imagined.

> in my apps tipically
> matrixes are inizialized reading from data files or using some
> function to construct the representation of a specific basic
> transformation, for example very often i do
> m.SetRotationMatrix(axis,angle) or something similar.
>
> Regards,
> Natale Fietta
>

Thank you. I consider using small (not val-) vectors/matrices as part of a
case study. It wouldn't really cover the topic we discussed (, it's more
about using STl with such small vectors,) but I wanted to know a bit more
about the implications of certain simple design decisions.

Hmm, the valmatrix, -vector topic would also make for a nice case study, on
a very different level. Someday ...

Thanks again,

Uwe

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





Author: John Nagle <nagle@animats.com>
Date: Mon, 5 Aug 2002 21:05:47 GMT
Raw View
James Russell Kuyper Jr. wrote:

> John Nagle wrote:
> ....
>
>>     Actually, no.  "valmatrix" does not have to be
>>a POD.  It just has to have an access function that
>>returns a POD with the underlying numerical data
>>as a dense, built-in array.
>>
>>     I'd thought that "valarray" had such a function.
>>But it doesn't.  So maybe "valmatrix" is a bad idea.
>>
>
> &varr[0] is a pointer to a POD object: the array containing the contents
> of the
> valarray.


     OK, thanks.

     John Nagle

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





Author: Allan_W@my-dejanews.com (Allan W)
Date: Mon, 5 Aug 2002 22:21:06 GMT
Raw View
> > > John Nagle <nagle@animats.com> wrote
> > >>    "valmatrix" would support N x M matrices, with
> > >>the size defined at template instantiation.  The
> > >>underlying representation would be guaranteed to
> > >>be a built-in array of the specified element type,
> > >>and the underlying representation data would be
> > >>accessable from the outside if needed.
> > >>(There are many APIs in existence that use such
> > >>a representation; this allows efficient C++
> > >>use or encapsulation of them.)
> > >>
> > >>     Both row-major and column-major representations
> > >>would be supported, again, determined at template
> > >>instantiation time.  (OpenGL and Direct-X use 4x4
> > >>matrices of different direction, so we must
> > >>support both.)

> > Allan W wrote:
> > > I'm worried that a less-than-careful implementation could cause
> > > major code bloat.

schnitker@sigma-c.com (Uwe Schnitker) wrote
> Define code bloat. IMHO the important point isn't how much binary code
> is produced from how little source code - one might argue that to keep
> the ratio high is the whole purpose of templates.

Well, of course.

If you could type #pragma customer_billing_system and somehow magically
turn this into a customer billing system that satisfies all of your
needs, nobody would complain that it was a few thousand (or even a few
million) bytes!

> The important point
> is how much binary code is produced from templates compared to equally
> efficient alternative solutions, in C++ or C.

Which is exactly my point. If we hand-coded a bunch of matrix classes,
we would go to great lengths to factor out common code. Within
reasonable performance constraints, our goal would be to move as much
code as possible out of the individual classes and into some common
code, most likely a base class. For instance, suppose we had a member
function that would sum every element of the matrix. We would probably
NOT code it this way:
    int Matrix_4_by_4_int_RowMajor::sum_all_elements() {
        int result=0;
        for (int row=0; row<4; ++row)
            for (int col=0; col<4; ++col)
                result += data[row*4+col];
        return result;
    }
    int Matrix_5_by_5_int_RowMajor::sum_all_elements() {
        int result=0;
        for (int row=0; row<5; ++row)
            for (int col=0; col<5; ++col)
                result += data[row*5+col];
        return result;
    }

Instead, we would probably code it this way:
    int Matrix_4_by_4_int_RowMajor::sum_all_elements()
        { return MatrixPrivate::sum(all_elements(data,16); }
    int Matrix_5_by_5_int_RowMajor::sum_all_elements()
        { return MatrixPrivate::sum(all_elements(data,25); }

This same technique could be used inside a template, but a naive
implementation would not do it this way.

> I suppose that a lot of the small functions, e.g. the math operators,
> will be inline anyway. -> no template related code bloat.

Perhaps this is true for memberwise math, but certainly not for
Matrix Multiplication, or Matrix Inversion, or...

> Other functions might have to be coded separately for different dimensions.
> I cannot imagine that you always can afford to check for the dimension and
> run a loop through the indices. -> no template related code bloat.

"I cannot imagine that you always can afford to check for the
dimension and run a loop through the indices." -- what does this mean?

If non-trivial (non-inline) code is contained directly in the template,
there will be code bloat. Perhaps an optimizing compiler can reduce this
a lot, but you cergainly can't assume this.

> [E.g. the profiler-between-my-ears tells me that eigenvalue calculation
> will be faster if you know at compile time whether the dimension is 3x3
> or 4x4 . Yes, I know that there are much better profilers available. ;-)]
>
> Where functions can indeed be independend of the dimension, there are ways
> to reduce template related code bloat, e.g call a free function.

Where functions are not entirely independant of the dimensions, there
are almost always ways to reduce code size there as well. Sometimes
these are free, but more often they will have a very minor performance
difference.

This goes back to the heart of my question. Suppose we decide that
ValMatrix<float,M,N>::foo(float x) needs to call
FreeFunction::foo(float*data,int M,int N,float x). This does have some
degree of overhead! The overhead will be entirely acceptable in most
business applications, but might be totally unacceptable in some
graphics applications.

That's why I want to know if the documentation for ValMatrix would
indicate that this was specifically intended for high-performance
graphics applications. I'm afraid that a business programmer might
use it by mistake, and never notice how huge his code has grown.
(Have you looked at the size of most business apps today? It seems
like nobody ever gives any consideration to code size!)

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





Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Wed, 14 Aug 2002 16:48:13 GMT
Raw View
On Mon, 12 Aug 2002 16:43:44 GMT, schnitker@sigma-c.com (Uwe
Schnitker) wrote:

>> in both cases i think valvectors must be POD.
>
>Well, "must" is a strong word. If you don't care about what the C++
>standard guarantees, you could use a class which is only "almost" a
>POD. It is, e.g., hard to imagine why and how a C++ compiler would
>change the data layout of a POD if you just add a simple constructor.
>But I'd care enough not to rely on such undefined, or at best
>implementation-defined, behavior.

I'm not a language lawyer, probably i am not using the term POD in the
correct way, for me a POD is a class with a memory layout compatible
with a C struct. to obtain this it is necessary (and as far as i know
also sufficient) to have no virtual function, to have all datas in the
same section and to evitate multiple inheritance and virtual bases; is
this incorrect ?

My vectors classes often have non trivial constructor, do this make
them non-POD ?

Regard,
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                       ]





Author: ros0230@iperbole.bologna.it (Natale Fietta)
Date: Wed, 14 Aug 2002 21:28:36 GMT
Raw View
On Sat, 10 Aug 2002 11:46:39 GMT, Walter Landry <wlandry@ucsd.edu>
wrote:

>Natale Fietta wrote:
>> Please, define "simple equation".
>
>What I meant is do your equations tend to look like
>
>  A=B*C;
>  D=A+E*F;
>
>or is it more like
>
>  A=(B*C + D*F)/(B*E - D*B) + B*B - F*C;

With matrixes i usually write long expression breaked in little token
to get rid of unnecessary temporaries, so i can be happy if the
library can automagically eliminate temporary for me :-)

My expressions often are not a simple sequence of arithmetic
operators, but are intermixed with various function calls, this way:

A=Normalize( CrossProduct((A - B), (C - B)) );
a=DotProduct( Vector(A.z, A.y, -A.x), Normalize(B - A) );

It is very infrequent for me to mix matrixes and vectors in the same
expression, i usually have strong separation betwen them, instead i do
often mix float in the same expression, this way:

//in this example lower-case are floats, upper-case are vectors or
matrixes
A=(u*B + v*C) / t;

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

>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

>  B=(B0 B1 B2 B3)

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

> What I could do is something
>like
>
>  Index<'i',3> i;
>  Index<'j',4> j;
>
>  C(i)=A(i,j)*B(j);
>  C(3)=B(3);
>
>Where the template parameter '3' for Index 'i' is so that only the
>first three elements of C are computed.

I've had a quick look at FTensor library, tensor concept is very
interesting (it is new to me) but for my work it is an unneeded
complexity; i am very happy with unrelated vector and matrix classes,
i do use them in very different modes and do not have any need to
generalize them in a tensorial way...

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

>For matrix*matrix operations, if you're using 3x4 matrices, you could
>do something like

The strange thing is that being 3x4 (widely used in past, but less
often now) a space optimized form of 4x4, i do want to be able to
multiply them, i mean multiply a 3x4 matrix for a 3x4 matrix obtaining
as result another 3x4 matrix (another cry from mathematicians ;-)

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

>> Also we often use 3-vector to represent normalized 4-vector in
>> homogeneous coordinates, so we can multiply a 3-vector by a 4x4
>> matrix and obtain another 3-vector as result. (i suppose this sound
>> very odd to mathematicians).
>
>I think you want to be able to multiply
>
>  A00 A01 A02 A03   B0
>  A10 A11 A12 A13 * B1
>  A20 A21 A22 A23   B2
>    0   0   0   1    1
>
>without storing that last B3=1.  Instead of simply
>  C=A*B

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

>Well, it seems like you can do most of what you need with a general
>tool.  I will admit that it is not quite as simple as a specialized
>library.  In cases where this matters, though, it shouldn't be
>difficult to define your own inline functions.  It will at least free
>you from having to construct the basic operations.

For me it is *far* more easy to construct all the basic operations
than to understand and use a tensor library...

>If, as John Nagle says, the algebra3 library is considered useful,
>then a more powerful and flexible interface with equivalent
>optimizations should work fine for most people.

As i said in my first post in this thread, i am talking only about my
personal experience and needs; i am not surprised John Neagle has
slightly (or also not so slightly) different needs than me; we do work
in differents niche of the geometric community.

I dislike some of algebra3 design, in particular the missing x y z
names for vector components, and various missing optimizations.

>I've also rooted around the Quake II source code a little, and it
>seems like that code in particular could benefit greatly from a
>standard vector and matrix toolkit.

Well, first of all this particular code is not a good example of C++
programming, because it is written in C...

In any case i must make my position more clear: i think a good quality
standard vector/matrix library can be a great benefit for the graphic
community, but i do think the needs are too peculiar and specific to
include a similar library in the C++ standard or boost libraries.

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

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                       ]





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Thu, 15 Aug 2002 23:59:10 GMT
Raw View
Natale Fietta wrote:
....
> I'm not a language lawyer, probably i am not using the term POD in the
> correct way, for me a POD is a class with a memory layout compatible
> with a C struct. to obtain this it is necessary (and as far as i know
> also sufficient) to have no virtual function, to have all datas in the
> same section and to evitate multiple inheritance and virtual bases; is
> this incorrect ?

Those are all necessary. They're not quite sufficient. Among other
things, all of the non-static data members must also have POD types.

> My vectors classes often have non trivial constructor, do this make
> them non-POD ?

Yes.

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





Author: John Nagle <nagle@animats.com>
Date: Fri, 16 Aug 2002 12:42:33 GMT
Raw View
     I never insisted that such objects necessarily be
POD (plain old data.)  I only insisted that they contain
and return upon request plain old data in a recognized
order. for use with interfaces which need it.  Think of
the facility provided for type "string" now:

 string s;   // is not a POD
 ...
 const char* p = s.data(); // returns a POD

That compromise works well for strings.

    John Nagle
    Animats

Natale Fietta wrote:

> On Mon, 12 Aug 2002 16:43:44 GMT, schnitker@sigma-c.com (Uwe
> Schnitker) wrote:
>
>
>>>in both cases i think valvectors must be POD.
>>>
>>Well, "must" is a strong word. If you don't care about what the C++
>>standard guarantees, you could use a class which is only "almost" a
>>POD. It is, e.g., hard to imagine why and how a C++ compiler would
>>change the data layout of a POD if you just add a simple constructor.
>>But I'd care enough not to rely on such undefined, or at best
>>implementation-defined, behavior.

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





Author: schnitker@sigma-c.com (Uwe Schnitker)
Date: Fri, 2 Aug 2002 15:50:02 GMT
Raw View
John Nagle <nagle@animats.com> wrote in message news:<3D4966AD.9080709@animats.com>...
> Uwe Schnitker wrote:
>
> > John Nagle <nagle@animats.com> wrote in message news:<3D475BF7.1060602@animats.com>...
>
> > To achieve this a "valmatrix" must be a POD.
>
>
>      Actually, no.  "valmatrix" does not have to be
> a POD.  It just has to have an access function that
> returns a POD with the underlying numerical data
> as a dense, built-in array.

Depends on what you want to do with it. I'd like to be able to write:

  vector<valmatrix> vec(100);

// label
  cvm* cvmp = (cvm*) &vec[0];

  manipulate(cvmp, cvmp + vec.size());

if cvm is a struct layout-compatible with valmatrix<double,1,3>
and manipulate is a C function taking two pointers which have
to delimit an array of cvm's.

If valmatrix is not a POD, but allows you to get at the data in
POD form, e.g. by declaring a friend function/functor makePOD,
you would need a copy operation to achieve the above:

// label
  vector<cvm> cvmVec(vec.size());

  transform(vec.begin(),vec.end(),cvmVec.begin(),makePOD);

  cvm* cvmp = &cvmVec[0];

  manipulate(cvmp, cvmp + cvmVec.size());

Also note that I mentioned writing things like

  valmatrix<double,1,3> vm = {2.0,3.0,4.0};

which requires valmatrix<double,1,3> to be an aggregate.

I do not claim that this usages are necessary for an effective
"valmatrix" design. But if you want to support them, you need
to make valmatrix a POD.

To give an example: On PowerPC systems with an Altivec unit you
could define a small vector to consist not of three or four doubles,
but of just one xxx (I don't remember the exact name of the
hardware-specific data type). Then manipulate could call one of
the intrinsic functions which works on an array of xxx with fast
vector processing.

If this valmatrix/valvector were a POD, then you could operate
directly on an array or std::vector of them both with C++ standard
library algorithms and with hardware-specific intrinsic functions.

Maybe it would be worth the trouble of making them POD's.

Regards,
Uwe

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





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Sat, 3 Aug 2002 19:03:56 GMT
Raw View
John Nagle wrote:
....
>      Actually, no.  "valmatrix" does not have to be
> a POD.  It just has to have an access function that
> returns a POD with the underlying numerical data
> as a dense, built-in array.
>
>      I'd thought that "valarray" had such a function.
> But it doesn't.  So maybe "valmatrix" is a bad idea.

&varr[0] is a pointer to a POD object: the array containing the contents
of the
valarray.

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





Author: Allan_W@my-dejanews.com (Allan W)
Date: Tue, 30 Jul 2002 23:56:50 GMT
Raw View
John Nagle <nagle@animats.com> wrote
>     "valmatrix" would support N x M matrices, with
> the size defined at template instantiation.  The
> underlying representation would be guaranteed to
> be a built-in array of the specified element type,
> and the underlying representation data would be
> accessable from the outside if needed.
> (There are many APIs in existence that use such
> a representation; this allows efficient C++
> use or encapsulation of them.)
>
>      Both row-major and column-major representations
> would be supported, again, determined at template
> instantiation time.  (OpenGL and Direct-X use 4x4
> matrices of different direction, so we must
> support both.)

I'm worried that a less-than-careful implementation could cause
major code bloat. If my program a 4x4, 4x8, 8x4, and 8x8 valmatrixes,
would a lot of code be instanciated four times? If I have both
row-major and column-major representations, would this grow to 8
times?

Judicious use of inheritance can drastically reduce the amount of
code generated from a template instanciation -- but in some
circumstances this can provide a (very modest) performance penalty.
Most code wouldn't even notice the performance difference, but I
suppose that video updates very well could -- and that could make
this type of code factoring inappropriate for graphics.

>      Like "valarray", the implementation would be
> optimized for performance, not generality.  If
> generality is needed, Boost's "Matrix" class
> is probably more appropriate.

I'm not a graphics programmer. Maybe it's reasonable to say, "this
is only appropriate for a graphics app where 'optimize' means
'optimize for speed, burn as much memory as you need'." But I'd
want that to be VERY explicit -- maybe in the class name (i.e.
GraphicsQuickValMatrix).

Among C++ novices, templates already have an (undeserved) reputation
for code bloat. If valmatrix ends up using a lot of code space, this
will be the first place that people point to "prove" this allegation.

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





Author: John Nagle <nagle@animats.com>
Date: 31 Jul 2002 11:35:18 GMT
Raw View
Allan W wrote:

> John Nagle <nagle@animats.com> wrote
>
>>    "valmatrix" would support N x M matrices, with
>>the size defined at template instantiation.  The
>>underlying representation would be guaranteed to
>>be a built-in array of the specified element type,
>>and the underlying representation data would be
>>accessable from the outside if needed.
>>(There are many APIs in existence that use such
>>a representation; this allows efficient C++
>>use or encapsulation of them.)
>>
>>     Both row-major and column-major representations
>>would be supported, again, determined at template
>>instantiation time.  (OpenGL and Direct-X use 4x4
>>matrices of different direction, so we must
>>support both.)
>>
>
> I'm worried that a less-than-careful implementation could cause
> major code bloat.


     It might, but if there's a speed gain, that's
considered a win in the graphics world.

     The real point here is that "valmatrix" would
guarantee the underlying representation as a dense
array of floats or doubles.  That's the representation
needed for OpenGL or Direct-X (although they're transposed
from each other) and by mainstream graphics hardware.

     Lately, I've been raising various issues relevant
to number-crunching in C++.  Is there a special-interest
group that's working on number-crunching issues for C++0x?
The C community seems to be addressing number-crunching
more aggressively than the C++ standards community (see
C99 variable-length arrays), but there's no fundamental
reason that C++ couldn't be as fast as C, if not faster.
(It's certainly cleaner.)  But it takes some work.
Right now, a multitude of encapsulations of common
number-crunching data objects tends to result in
much copying and reformatting when multiple numeric
libraries from different sources are brought together.
That can and should be fixed.

    John Nagle
    Animats

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





Author: Gabriel Dos Reis <gdr@integrable-solutions.net>
Date: Wed, 31 Jul 2002 15:02:56 GMT
Raw View
Allan_W@my-dejanews.com (Allan W) writes:

[...]

| Judicious use of inheritance can drastically reduce the amount of
| code generated from a template instanciation -- but in some
| circumstances this can provide a (very modest) performance penalty.
| Most code wouldn't even notice the performance difference, but I
| suppose that video updates very well could -- and that could make
| this type of code factoring inappropriate for graphics.

I guess that depends on your compiler.  If it understands type alias
analysis (properly), then it could use it to optimize away the
abstraction penalty.

--
Gabriel Dos Reis, gdr@integrable-solutions.net

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





Author: Computer User <tehdas@optushome.com.au>
Date: Thu, 1 Aug 2002 08:51:19 GMT
Raw View
In article <877kjnpg3p.fsf@grue.ucsd.edu>, wlandry@ucsd.edu says...
> >     My main concern is that 2D, 3D, and 4D vectors and matrices be
> > efficiently
> > supported in C++ in a standard way.  All 3D graphics programs pass
> > such objects around with great enthusiasm, and several different
> > formats are in use.  Interconversion of these objects is an
> > ongoing hassle.  C arrays are usually used because they're
> > standard, but of course you don't get any operators on them.
> >
> >     Does anybody in the graphics community want to push
> > this forward?
>
> What kind of thing does the graphics community want?  Do you usually
> have a lot of small, simple equations?  How would you ideally like
> them to appear as code?  Is making the vectors and matrices as small
> as possible important?  Do you always know the size of the vectors and
> matrices at compile time?  Is it important to be able to dynamically
> resize them?  How much of a performance penalty are you willing to
> pay?  Does your tolerance of a penalty go up if there is still a way
> to get around it (i.e. you can use C-style notation, and it is just as
> fast as C arrays)?
>
> It would be useful if you could post some representative code.  Then
> we could see how the various projects (algebra3, uBlas, Blitz, and
> FTensor) handle it.

  From what I have seen, in a majority of freely available 3d engine
sources, most will have a Vector3, a Vector4 and a Matrix4x4 class. And
possibly a Quaternion class as well. They tend to have overloaded
arithmatic operators, and some operations provided as well (Dot product,
cross product, etc).
  Common varients include assuming that the last row of the matrix is
(0,0,0,1) (which is somewhat less common now than in the old software
rendering days), varying the amount of function members that are
inlined, adding in a Plane class (and intersections thereof), etc..
  You can easily check out a wide variety of them from the 3d engines
list, or any site cateering to the hobbiest game/graphics programming
erm, segment. (www.flipcode.com, gamedev.net, etc)

  - Factory

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





Author: schnitker@sigma-c.com (Uwe Schnitker)
Date: Thu, 1 Aug 2002 08:53:07 GMT
Raw View
John Nagle <nagle@animats.com> wrote in message news:<3D475BF7.1060602@animats.com>...
> Allan W wrote:
>
> > John Nagle <nagle@animats.com> wrote
> >
> >>    "valmatrix" would support N x M matrices, with
> >>the size defined at template instantiation.  The
> >>underlying representation would be guaranteed to
> >>be a built-in array of the specified element type,
> >>and the underlying representation data would be
> >>accessable from the outside if needed.
> >>(There are many APIs in existence that use such
> >>a representation; this allows efficient C++
> >>use or encapsulation of them.)
> >>
> >>     Both row-major and column-major representations
> >>would be supported, again, determined at template
> >>instantiation time.  (OpenGL and Direct-X use 4x4
> >>matrices of different direction, so we must
> >>support both.)
> >>
> >
> > I'm worried that a less-than-careful implementation could cause
> > major code bloat.

Define code bloat. IMHO the important point isn't how much binary code
is produced from how little source code - one might argue that to keep
the ratio high is the whole purpose of templates. The important point
is how much binary code is produced from templates compared to equally
efficient alternative solutions, in C++ or C.

I suppose that a lot of the small functions, e.g. the math operators,
will be inline anyway. -> no template related code bloat.

Other functions might have to be coded separately for different dimensions.
I cannot imagine that you always can afford to check for the dimension and
run a loop through the indices. -> no template related code bloat.

[E.g. the profiler-between-my-ears tells me that eigenvalue calculation
will be faster if you know at compile time whether the dimension is 3x3
or 4x4 . Yes, I know that there are much better profilers available. ;-)]

Where functions can indeed be independend of the dimension, there are ways
to reduce template related code bloat, e.g call a free function.

>      It might, but if there's a speed gain, that's
> considered a win in the graphics world.

You know that too much memory use will degrade speed because of cache size
related effects, don't you?

>      The real point here is that "valmatrix" would
> guarantee the underlying representation as a dense
> array of floats or doubles.  That's the representation
> needed for OpenGL or Direct-X (although they're transposed
> from each other) and by mainstream graphics hardware.

I'm not sure that it is enough to "guarantee the underlying
representation". I can imagine that one may want to trade
not only "valmatrix"es, but also arrays of "valmatrix"es
with C API's.

To achieve this a "valmatrix" must be a POD. I don't know
whether template instantiations can be POD's - I've asked
that questions on this NG - but derived classes are never
POD's. This would make "valmatrix" a very low-level concept
- no constructors, no bases, no nothing - which may be wrapped
in a more convenient layer for safer use.

If "valmatrix" were a POD - and hence an aggregate, too - you
could stuff "valmatrix"es into a std::vector, pass that
std::vector data to a C API, memcpy it, call hardware specific
intrinsics on it, etc.

You could also initialize arrays of "valmatrix"es with
{}- initializer lists. This would allow creating static
arrays at compile-time, with no initializing cost at runtime.
(Const static arrays could even be put in ROM.)

Of course, the "canonic, alexandrescu" way to use policies breaks
down if you cannot use inheritance because of the POD issue, but
here we have a very special case, where we can find different ways
to make "policies" work.

[OTOH, there is no fundamental reason that inheritance always has
to break POD-ness. If the base class is a POD, it should be possible
to guarantee that the derived class is a POD, too. However, I don't
think it would be easy to get this into the next revision of the
standard.]

Regards,
Uwe

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





Author: John Nagle <nagle@animats.com>
Date: Thu, 1 Aug 2002 17:59:49 GMT
Raw View
Uwe Schnitker wrote:

> John Nagle <nagle@animats.com> wrote in message news:<3D475BF7.1060602@animats.com>...

> To achieve this a "valmatrix" must be a POD.


     Actually, no.  "valmatrix" does not have to be
a POD.  It just has to have an access function that
returns a POD with the underlying numerical data
as a dense, built-in array.

     I'd thought that "valarray" had such a function.
But it doesn't.  So maybe "valmatrix" is a bad idea.

     John Nagle
     Animats

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





Author: Walter Landry <wlandry@ucsd.edu>
Date: Sat, 20 Jul 2002 01:27:10 GMT
Raw View
Greetings,

I'm wondering if anyone has given any thought to adding support for
small vectors and matrices to the C++ standard.  I know that last
December John Nagle proposed the algebra3 library, but he hasn't
responded to my email.  I'm also aware of the Blitz library.  I've got
my own implementation [1], so I'm curious to know if anyone is working
on it.

Thanks,
Walter Landry
wlandry@ucsd.edu

[1] http://superbeast.ucsd.edu/~landry/FTensor

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





Author: John Nagle <nagle@animats.com>
Date: Sat, 20 Jul 2002 23:24:29 CST
Raw View
    Someone suggested I propose it to Boost, and someone else
suggested a more complicated template-based approach.
But I haven't followed up.  All I was proposing was the library
from Graphics Gems, cleaned up a bit.

    My main concern is that 2D, 3D, and 4D vectors and matrices be
efficiently
supported in C++ in a standard way.  All 3D graphics programs pass
such objects around with great enthusiasm, and several different
formats are in use.  Interconversion of these objects is an
ongoing hassle.  C arrays are usually used because they're
standard, but of course you don't get any operators on them.

    Does anybody in the graphics community want to push
this forward?

    John Nagle
    Animats

Walter Landry wrote:

> Greetings,
>
> I'm wondering if anyone has given any thought to adding support for
> small vectors and matrices to the C++ standard.  I know that last
> December John Nagle proposed the algebra3 library, but he hasn't
> responded to my email.  I'm also aware of the Blitz library.  I've got
> my own implementation [1], so I'm curious to know if anyone is working
> on it.
>
> Thanks,
> Walter Landry
> wlandry@ucsd.edu
>
> [1] http://superbeast.ucsd.edu/~landry/FTensor

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





Author: "David Abrahams" <david.abrahams@rcn.com>
Date: Sun, 21 Jul 2002 04:25:06 GMT
Raw View
"Walter Landry" <wlandry@ucsd.edu> wrote in message
news:87wurryywb.fsf@grue.ucsd.edu...
> Greetings,
>
> I'm wondering if anyone has given any thought to adding support for
> small vectors and matrices to the C++ standard.  I know that last
> December John Nagle proposed the algebra3 library, but he hasn't
> responded to my email.  I'm also aware of the Blitz library.  I've got
> my own implementation [1], so I'm curious to know if anyone is working
> on it.

Boost.uBlas is a numerics library that has recently been accepted into
Boost, and will be in the next release.

-Dave



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





Author: Frank Compagner <frank@compagner.com>
Date: Sun, 21 Jul 2002 04:26:33 GMT
Raw View
Walter Landry <wlandry@ucsd.edu> wrote in
news:87wurryywb.fsf@grue.ucsd.edu:
> I'm wondering if anyone has given any thought to adding support for
> small vectors and matrices to the C++ standard.  I know that last
> December John Nagle proposed the algebra3 library, but he hasn't
> responded to my email.  I'm also aware of the Blitz library.  I've got
> my own implementation [1], so I'm curious to know if anyone is working
> on it.

Although i agree that the C++ community could very well use a small (2,3
and 4 dimensions) vector/matrix library, i don't think it a likely
candidate for the next version of the standard library. Implementing a
good quality lib that is both fast, flexible and robust and can be
applied to a broad range of problem domains is going to be very hard to
do. It might not be impossible, but it certainly is going to take some
time and effort.

The boost library (www.boost.org) would seem a more logical first step.
I'm not aware of anybody working on a vector/matrix library for addition
to boost, but it wouldn't hurt to discuss this on the boost mailing list
first. But even making a first implementation that would be good enough
to submit to boost is going to be quite a bit of work. Your own work
looks interesting and promising, and the algebra3 lib (the source can be
found at http://www.animats.com/source/graphics/algebra3.h) is a good
example of a basic vector/matrix library, but a high quality
implementation needs to offer at least these:
- high performance (matrix size as template argument, expression
  templates might be going a bit too far for small matrices).
- flexibility (at least make the value type a template parameter)
- Compatible across a broad range of compilers (vc6 sucks, but it still
  is the nr.1 compiler in use today).
- Robustness (provide good, and preferably flexible error handling, maybe
  through policies?)
- Clean and clear interface.
There are an awful lot of vector/matrix library's floating around, but
none of them score very well against these criteria. All the more reason
to add one to boost, i say. It would be a very welcome addition i think,
and maybe reduce the number of wheels that get reinvented somewhat.
I would be very willing to help in this matter, i've got my own
experimental implentation (of course ;-) laying around somewhere.

Frank Compagner.

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





Author: John Nagle <nagle@animats.com>
Date: Sun, 21 Jul 2002 18:25:48 CST
Raw View
Frank Compagner wrote:

> Walter Landry <wlandry@ucsd.edu> wrote in
> news:87wurryywb.fsf@grue.ucsd.edu:
>
>>I'm wondering if anyone has given any thought to adding support for
>>small vectors and matrices to the C++ standard.  I know that last
>>December John Nagle proposed the algebra3 library, but he hasn't
>>responded to my email.  I'm also aware of the Blitz library.  I've got
>>my own implementation [1], so I'm curious to know if anyone is working
>>on it.
>>
>
> Although i agree that the C++ community could very well use a small (2,3
> and 4 dimensions) vector/matrix library, i don't think it a likely
> candidate for the next version of the standard library. Implementing a
> good quality lib that is both fast, flexible and robust and can be
> applied to a broad range of problem domains is going to be very hard to
> do. It might not be impossible, but it certainly is going to take some
> time and effort.
>
> The boost library (www.boost.org) would seem a more logical first step.
> I'm not aware of anybody working on a vector/matrix library for addition
> to boost, but it wouldn't hurt to discuss this on the boost mailing list
> first.


    Boost's "Matrix" template class is impressive, but so complicated
that few graphics programmers would accept it.  It does dense matrices,
sparse matrices, variable size, fixed size, etc.  Whether the simpler
cases reliably grind down to trivial code under all major compilers
is a big issue.

    There's a tradeoff between genericity and simplicity here.

    However, if there was a standard "general matrix" library, and a
standard "small matrix and vector" library, and conversions
between the two that worked, that wouldn't be too bad.

     John Nagle
     Animats

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





Author: "Noah Stein" <n-o-a-h@a_c_m.org>
Date: Mon, 22 Jul 2002 06:40:52 GMT
Raw View
"John Nagle" <nagle@animats.com> wrote in message
news:3D38FB4F.1020909@animats.com...
>     My main concern is that 2D, 3D, and 4D vectors and matrices be
> efficiently
> supported in C++ in a standard way.  All 3D graphics programs pass
> such objects around with great enthusiasm, and several different
> formats are in use.  Interconversion of these objects is an
> ongoing hassle.  C arrays are usually used because they're
> standard, but of course you don't get any operators on them.
>
>     Does anybody in the graphics community want to push
> this forward?
>

I've reinvented this wheel a few times (at least 10), so I'm rather
supportive of the effort.  I also don't mind putting in some of the effort
to implement the library.  It's a tough system to design and implement.  My
target platforms are video game consoles just as frequently as PCs.  The
consoles frequently have specialized math hardware.  A good design would
allow me to merely implement one or two classes to represent their specific
types and implement supporting inline assembly code.  A bad design would
require me to merely re-implement the wheel one more time.


-- Noah


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





Author: Walter Landry <wlandry@ucsd.edu>
Date: Tue, 23 Jul 2002 01:32:23 GMT
Raw View
John Nagle <nagle@animats.com> writes:

>     Someone suggested I propose it to Boost, and someone else
> suggested a more complicated template-based approach.
> But I haven't followed up.  All I was proposing was the library
> from Graphics Gems, cleaned up a bit.

Well, I've implemented a template-based approach.  I'm trying to find
out if it has applicability beyond what I wrote it for.  I think it
covers what you want, but I could be wrong.

>     My main concern is that 2D, 3D, and 4D vectors and matrices be
> efficiently
> supported in C++ in a standard way.  All 3D graphics programs pass
> such objects around with great enthusiasm, and several different
> formats are in use.  Interconversion of these objects is an
> ongoing hassle.  C arrays are usually used because they're
> standard, but of course you don't get any operators on them.
>
>     Does anybody in the graphics community want to push
> this forward?

What kind of thing does the graphics community want?  Do you usually
have a lot of small, simple equations?  How would you ideally like
them to appear as code?  Is making the vectors and matrices as small
as possible important?  Do you always know the size of the vectors and
matrices at compile time?  Is it important to be able to dynamically
resize them?  How much of a performance penalty are you willing to
pay?  Does your tolerance of a penalty go up if there is still a way
to get around it (i.e. you can use C-style notation, and it is just as
fast as C arrays)?

It would be useful if you could post some representative code.  Then
we could see how the various projects (algebra3, uBlas, Blitz, and
FTensor) handle it.

Thanks,
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                       ]





Author: John Nagle <nagle@animats.com>
Date: Tue, 23 Jul 2002 17:52:29 GMT
Raw View
    I was just thinking along the lines Noah mentioned.
What we may need is an efficient representation of 2D
arrays of numbers, like "valarray" but for 2D matrices.
The name "valmatrix" suggests itself.

    "valmatrix" would support N x M matrices, with
the size defined at template instantiation.  The
underlying representation would be guaranteed to
be a built-in array of the specified element type,
and the underlying representation data would be
accessable from the outside if needed.
(There are many APIs in existence that use such
a representation; this allows efficient C++
use or encapsulation of them.)

     Both row-major and column-major representations
would be supported, again, determined at template
instantiation time.  (OpenGL and Direct-X use 4x4
matrices of different direction, so we must
support both.)

     Like "valarray", the implementation would be
optimized for performance, not generality.  If
generality is needed, Boost's "Matrix" class
is probably more appropriate.

     Comments?

    John Nagle
    Animats

Noah Stein wrote:

> "John Nagle" <nagle@animats.com> wrote in message
> news:3D38FB4F.1020909@animats.com...
>
>>    My main concern is that 2D, 3D, and 4D vectors and matrices be
>>efficiently
>>supported in C++ in a standard way.  All 3D graphics programs pass
>>such objects around with great enthusiasm, and several different
>>formats are in use.  Interconversion of these objects is an
>>ongoing hassle.  C arrays are usually used because they're
>>standard, but of course you don't get any operators on them.
>>
>>    Does anybody in the graphics community want to push
>>this forward?
>>
>>
>
> I've reinvented this wheel a few times (at least 10), so I'm rather
> supportive of the effort.  I also don't mind putting in some of the effort
> to implement the library.  It's a tough system to design and implement.  My
> target platforms are video game consoles just as frequently as PCs.  The
> consoles frequently have specialized math hardware.  A good design would
> allow me to merely implement one or two classes to represent their specific
> types and implement supporting inline assembly code.  A bad design would
> require me to merely re-implement the wheel one more time.
>
>
> -- Noah
>
>
> ---
> [ 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                       ]
>
>

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