www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Low dimensional matrices, vectors, quaternions and a cubic equation

reply "Gareth Charnock" <gareth.charnock gmail.com> writes:
As a side effect of my PhD project I've got a collection of mathematical  
classes. I'd be happy to collect them together, tidy them up and donate  
them to phobos the authors are interested in including them. Matrices and  
vectors in particular get reinvented all the time so I'm sure users of D  
will appreciate them being there. Quaternions are probably somewhat more  
specialised; they are most often used for representing rotations (they  
have different advantages and disadvantages to rotation matrices). I've  
also written a solver for cubic equations.

The matrix and vector classes are of the sort where the dimension is known  
at compile time and will probably be most useful for modelling geometry.  
High dimensional matrices and vectors are probably better left to a  
scientific library (I remember there was talk that one might be being  
proposed).

Would this sort of functionality be useful for phobos? At the moment, I  
can't promise anything, I'm just trying to judge the interest should I  
find time to look into it.

Gareth Charnock
Apr 15 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Gareth Charnock:

 Matrices and  
 vectors in particular get reinvented all the time so I'm sure users of D  
 will appreciate them being there.
I've seen so many times people re-write a 2D-3D vector struct that I hope it will be added to Phobos once and for all. Bye, bearophile
Apr 15 2010
parent Johan Granberg <lijat.meREM OVEgmail.com> writes:
bearophile wrote:

 Gareth Charnock:
 
 Matrices and
 vectors in particular get reinvented all the time so I'm sure users of D
 will appreciate them being there.
I've seen so many times people re-write a 2D-3D vector struct that I hope it will be added to Phobos once and for all. Bye, bearophile
I would be imensly gratefull for the same reason. This goes foor the Quaternions to by the way.
Apr 15 2010
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 04/15/2010 01:49 PM, Gareth Charnock wrote:
 As a side effect of my PhD project I've got a collection of mathematical
 classes. I'd be happy to collect them together, tidy them up and donate
 them to phobos the authors are interested in including them. Matrices
 and vectors in particular get reinvented all the time so I'm sure users
 of D will appreciate them being there. Quaternions are probably somewhat
 more specialised; they are most often used for representing rotations
 (they have different advantages and disadvantages to rotation matrices).
 I've also written a solver for cubic equations.

 The matrix and vector classes are of the sort where the dimension is
 known at compile time and will probably be most useful for modelling
 geometry. High dimensional matrices and vectors are probably better left
 to a scientific library (I remember there was talk that one might be
 being proposed).

 Would this sort of functionality be useful for phobos? At the moment, I
 can't promise anything, I'm just trying to judge the interest should I
 find time to look into it.

 Gareth Charnock
I think it would. Could you please post a brief list of features so people can take a look? Andrei
Apr 15 2010
parent reply Gareth Charnock <gareth.tpc gmail.com> writes:
Okay, here goes. I've collected together the basic functionality that 
would probably make a good starting point. As I've mentioned my code is 
very messy and has bits missing (e.g. I never had a use for the cross 
product but it's pretty important in general). I guess a good way to 
begin would be to write the pubic interfaces then start on the 
implementation.

Cubic Solvers:
General complex cubic solver with two algorithms (one requiring a 
complex cosine and and arcosine one using only +-*/ and roots). A 
special case cubic solver for the reduced cubic x^^3 + px - q = 0.

Quaternions:
opAdd, opSub, opMult(quaternion), opMult(vector), opDiv, Normalise, 
Normalized, conjugate, conjugated, toEulerAngles*, fromEulerAngles, 
this(real,i,j,k), this(angle,axis), getAngle(), getAxis()

*Currently I've only got a quaternion->euler angles routine that works 
in the ZYZ convention but I have read a paper that generalises my method 
to all valid axis conventions. Will probably impliment as something like:
toEulerAngles(string convention="XYZ")()

Vectors:
opAdd, opSub, opMult(scalar), opMult(vector)*, cross**, Normalise, 
Normalized, Length

* dot product. Would this be better named as dot()?
** 3D vectors only. Perhaps defining a cross product on the

Matrices:
opAdd, opSub, opMult(scalar), opMult(vector), opMult(matrix)**, Invert, 
Inverted, Orthogonalize, Orthogonalized, Reorthogonalize***, 
Reorthogonalized***, Det, Transpose, Transposed, Dagger*, Daggered*, 
Eigenvalues****, Eigenvectors****

*The hermitian conjugate/conjugate transpose. Reduces to the transpose 
for a real matrix
** Matrix-matrix multiplication doesn't commute. Could this be a problem 
when using operator notation?
*** Othogonalize assuming the matrix is nearly orthogonal already 
(possibly using some quick, approximate method such as a Taylor series)
**** I have a eigenvalue/vector solver for 3x3 matrices which seems 
reasonably stable but needs more testing.

Free functions:
MatrixToQuaternion
QuaternionToMatrix
+ code to allow easy printing to stdout/streams and such.

Andrei Alexandrescu wrote:
 On 04/15/2010 01:49 PM, Gareth Charnock wrote:
 As a side effect of my PhD project I've got a collection of mathematical
 classes. I'd be happy to collect them together, tidy them up and donate
 them to phobos the authors are interested in including them. Matrices
 and vectors in particular get reinvented all the time so I'm sure users
 of D will appreciate them being there. Quaternions are probably somewhat
 more specialised; they are most often used for representing rotations
 (they have different advantages and disadvantages to rotation matrices).
 I've also written a solver for cubic equations.

 The matrix and vector classes are of the sort where the dimension is
 known at compile time and will probably be most useful for modelling
 geometry. High dimensional matrices and vectors are probably better left
 to a scientific library (I remember there was talk that one might be
 being proposed).

 Would this sort of functionality be useful for phobos? At the moment, I
 can't promise anything, I'm just trying to judge the interest should I
 find time to look into it.

 Gareth Charnock
I think it would. Could you please post a brief list of features so people can take a look? Andrei
Apr 16 2010
next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Gareth Charnock <gareth.tpc gmail.com> wrote:

 Quaternions:
 opAdd, opSub, opMult(quaternion), opMult(vector), opDiv, Normalise,  
 Normalized, conjugate, conjugated, toEulerAngles*, fromEulerAngles,  
 this(real,i,j,k), this(angle,axis), getAngle(), getAxis()
[...]
 Vectors:
 opAdd, opSub, opMult(scalar), opMult(vector)*, cross**, Normalise,  
 Normalized, Length
Normalise and normalized seem to be inconsistent in their naming. Please use only z or only s.
 * dot product. Would this be better named as dot()?
Yes please.
 ** 3D vectors only. Perhaps defining a cross product on the
Cross products are useful. Please add.
 Matrices:
 opAdd, opSub, opMult(scalar), opMult(vector), opMult(matrix)**, Invert,  
 Inverted, Orthogonalize, Orthogonalized, Reorthogonalize***,  
 Reorthogonalized***, Det, Transpose, Transposed, Dagger*, Daggered*,  
 Eigenvalues****, Eigenvectors****

 *The hermitian conjugate/conjugate transpose. Reduces to the transpose  
 for a real matrix
 ** Matrix-matrix multiplication doesn't commute. Could this be a problem  
 when using operator notation?
There should be no associated problems. -- Simen
Apr 16 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Gareth Charnock <gareth.tpc gmail.com> wrote:
 Vectors:
 opAdd, opSub, opMult(scalar), opMult(vector)*, cross**, Normalise,  
 Normalized, Length
Oh, and perhaps add swizzling? Probably using opDispatch. -- Simen
Apr 16 2010
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 04/16/2010 04:25 PM, Gareth Charnock wrote:
 Okay, here goes. I've collected together the basic functionality that
 would probably make a good starting point. As I've mentioned my code is
 very messy and has bits missing (e.g. I never had a use for the cross
 product but it's pretty important in general). I guess a good way to
 begin would be to write the pubic interfaces then start on the
 implementation.

 Cubic Solvers:
 General complex cubic solver with two algorithms (one requiring a
 complex cosine and and arcosine one using only +-*/ and roots). A
 special case cubic solver for the reduced cubic x^^3 + px - q = 0.
This sounds a candidate for std.numeric. How popular/needed are cubic solvers?
 Quaternions:
 opAdd, opSub, opMult(quaternion), opMult(vector), opDiv, Normalise,
 Normalized, conjugate, conjugated, toEulerAngles*, fromEulerAngles,
 this(real,i,j,k), this(angle,axis), getAngle(), getAxis()
Sounds good, but you'd need to convert the code to the new overloaded operators approach.
 *Currently I've only got a quaternion->euler angles routine that works
 in the ZYZ convention but I have read a paper that generalises my method
 to all valid axis conventions. Will probably impliment as something like:
 toEulerAngles(string convention="XYZ")()

 Vectors:
 opAdd, opSub, opMult(scalar), opMult(vector)*, cross**, Normalise,
 Normalized, Length
What is the representation of vectors? I'm afraid the design above would be too limited for what we need.
 * dot product. Would this be better named as dot()?
We already have dot product and normalization routines that work with general ranges. http://www.digitalmars.com/d/2.0/phobos/std_numeric.html#dotProduct http://www.digitalmars.com/d/2.0/phobos/std_numeric.html#normalize Generally I'd strongly suggest making operations free generic functions instead of members.
 ** 3D vectors only. Perhaps defining a cross product on the

 Matrices:
 opAdd, opSub, opMult(scalar), opMult(vector), opMult(matrix)**, Invert,
 Inverted, Orthogonalize, Orthogonalized, Reorthogonalize***,
 Reorthogonalized***, Det, Transpose, Transposed, Dagger*, Daggered*,
 Eigenvalues****, Eigenvectors****
What is the representation of matrices?
 *The hermitian conjugate/conjugate transpose. Reduces to the transpose
 for a real matrix
Transposition should also be handled in a static manner, e.g. define a transposed view of a matrix that doesn't actually move elements.
 ** Matrix-matrix multiplication doesn't commute. Could this be a problem
 when using operator notation?
Should be fine.
 *** Othogonalize assuming the matrix is nearly orthogonal already
 (possibly using some quick, approximate method such as a Taylor series)
 **** I have a eigenvalue/vector solver for 3x3 matrices which seems
 reasonably stable but needs more testing.

 Free functions:
 MatrixToQuaternion
 QuaternionToMatrix
 + code to allow easy printing to stdout/streams and such.
Sounds encouraging. I think a good next step is to go through a community scrutiny process by dropping the code somewhere on the Web so people can review it. Andrei
Apr 16 2010
next sibling parent reply Gareth Charnock <gareth.tpc gmail.com> writes:
Andrei Alexandrescu wrote:
 On 04/16/2010 04:25 PM, Gareth Charnock wrote:
 Okay, here goes. I've collected together the basic functionality that
 would probably make a good starting point. As I've mentioned my code is
 very messy and has bits missing (e.g. I never had a use for the cross
 product but it's pretty important in general). I guess a good way to
 begin would be to write the pubic interfaces then start on the
 implementation.

 Cubic Solvers:
 General complex cubic solver with two algorithms (one requiring a
 complex cosine and and arcosine one using only +-*/ and roots). A
 special case cubic solver for the reduced cubic x^^3 + px - q = 0.
This sounds a candidate for std.numeric. How popular/needed are cubic solvers?
They're probably don't come up that frequently but they do they're rather fiddly. Lots of operations to get right. But the solution doesn't depend on anything but basic math operators so once it's written, it's written. I guess the question is whether Phobos is meant to be a small library or a kitchen sink library.
 Quaternions:
 opAdd, opSub, opMult(quaternion), opMult(vector), opDiv, Normalise,
 Normalized, conjugate, conjugated, toEulerAngles*, fromEulerAngles,
 this(real,i,j,k), this(angle,axis), getAngle(), getAxis()
Sounds good, but you'd need to convert the code to the new overloaded operators approach.
Fair enough, and this will be a good opportunity to show off why the new overloading scheme is more powerful (e.g. opAdd and opSub can be combined).
 *Currently I've only got a quaternion->euler angles routine that works
 in the ZYZ convention but I have read a paper that generalises my method
 to all valid axis conventions. Will probably impliment as something like:
 toEulerAngles(string convention="XYZ")()

 Vectors:
 opAdd, opSub, opMult(scalar), opMult(vector)*, cross**, Normalise,
 Normalized, Length
What is the representation of vectors? I'm afraid the design above would be too limited for what we need.
A fixed sized array where V[0] ~ x, V[1] ~ y and V[2] ~ z. The field the vector is defined over is templated. What other operators are needed? I'd defiantly want to add swizzling. http://www.ogre3d.org/docs/api/html/classOgre_1_1Vector3.html looks like it could be a good source of ideas.
 * dot product. Would this be better named as dot()?
 We already have dot product and normalization routines that work with 
 general ranges.
 
 http://www.digitalmars.com/d/2.0/phobos/std_numeric.html#dotProduct
 http://www.digitalmars.com/d/2.0/phobos/std_numeric.html#normalize
 
 Generally I'd strongly suggest making operations free generic functions 
 instead of members.
I've not really thought about operators as members vs operators as free functions. I just tend to put them as members because it feels more organised. But looking at other implementations, I seem to be in the minority.
 ** 3D vectors only. Perhaps defining a cross product on the

 Matrices:
 opAdd, opSub, opMult(scalar), opMult(vector), opMult(matrix)**, Invert,
 Inverted, Orthogonalize, Orthogonalized, Reorthogonalize***,
 Reorthogonalized***, Det, Transpose, Transposed, Dagger*, Daggered*,
 Eigenvalues****, Eigenvectors****
What is the representation of matrices?
private: F[n*n] mat; where F is the type of the field and n is the dimension of the matrix.
 *The hermitian conjugate/conjugate transpose. Reduces to the transpose
 for a real matrix
Transposition should also be handled in a static manner, e.g. define a transposed view of a matrix that doesn't actually move elements.
Do you mean that a bool should be stored to count the number of transpositions or that there is a type that behaves like a matrix but actually just presents a view of another matrix e.g. Matrix A; ... Matrix B = A.Transposed(); //Changes to B now affect A
 ** Matrix-matrix multiplication doesn't commute. Could this be a problem
 when using operator notation?
Should be fine.
 *** Othogonalize assuming the matrix is nearly orthogonal already
 (possibly using some quick, approximate method such as a Taylor series)
 **** I have a eigenvalue/vector solver for 3x3 matrices which seems
 reasonably stable but needs more testing.

 Free functions:
 MatrixToQuaternion
 QuaternionToMatrix
 + code to allow easy printing to stdout/streams and such.
Sounds encouraging. I think a good next step is to go through a community scrutiny process by dropping the code somewhere on the Web so people can review it.
Couldn't agree more because I'm sure I'll miss tricks and conventions. I would have never thought of that funky swizzling idea. I've also got another question: should matrices, vectors and quaternions be classes or structs? My gut reaction is that they should be structs and thus act like value types. But matrices might be too big and should be passed by reference which would imply they should be a class. Anyone know any rules of thumb that might apply? Gareth Charnock
Apr 18 2010
next sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Mon, Apr 19, 2010 at 01:11, Gareth Charnock <gareth.tpc gmail.com> wrote:

 Couldn't agree more because I'm sure I'll miss tricks and conventions. I
 would have never thought of that funky swizzling idea.
Here is a first try with the new operator syntax: http://lists.puremagic.com/pipermail/digitalmars-d/2010-April/074864.html Maybe it can help you... Cheers, Philippe
Apr 18 2010
parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Philippe Sigaud wrote:
 
 
 On Mon, Apr 19, 2010 at 01:11, Gareth Charnock <gareth.tpc gmail.com 
 <mailto:gareth.tpc gmail.com>> wrote:
 
     Couldn't agree more because I'm sure I'll miss tricks and
     conventions. I would have never thought of that funky swizzling idea.
 
 
 Here is a first try with the new operator syntax:
 
 http://lists.puremagic.com/pipermail/digitalmars-d/2010-April/074864.html
 
 Maybe it can help you...
Yeah, opDispatch is really cool. :) Here's an even earlier suggestion by Don, using inline assembler: http://www.digitalmars.com/d/archives/digitalmars/D/Re_dynamic_classes_and_duck_typing_102407.html#N102410 (Note: "opDynamic" was an early proposal. It should be replaced with "opDispatch", which is what we have now.) -Lars
Apr 19 2010
prev sibling next sibling parent #ponce <spam spam.spam> writes:
Gareth Charnock Wrote:

 Andrei Alexandrescu wrote:
 On 04/16/2010 04:25 PM, Gareth Charnock wrote:
 Okay, here goes. I've collected together the basic functionality that
 would probably make a good starting point. As I've mentioned my code is
 very messy and has bits missing (e.g. I never had a use for the cross
 product but it's pretty important in general). I guess a good way to
 begin would be to write the pubic interfaces then start on the
 implementation.

 Cubic Solvers:
 General complex cubic solver with two algorithms (one requiring a
 complex cosine and and arcosine one using only +-*/ and roots). A
 special case cubic solver for the reduced cubic x^^3 + px - q = 0.
This sounds a candidate for std.numeric. How popular/needed are cubic solvers?
They're probably don't come up that frequently but they do they're rather fiddly. Lots of operations to get right. But the solution doesn't depend on anything but basic math operators so once it's written, it's written. I guess the question is whether Phobos is meant to be a small library or a kitchen sink library.
 Quaternions:
 opAdd, opSub, opMult(quaternion), opMult(vector), opDiv, Normalise,
 Normalized, conjugate, conjugated, toEulerAngles*, fromEulerAngles,
 this(real,i,j,k), this(angle,axis), getAngle(), getAxis()
Sounds good, but you'd need to convert the code to the new overloaded operators approach.
Fair enough, and this will be a good opportunity to show off why the new overloading scheme is more powerful (e.g. opAdd and opSub can be combined).
 *Currently I've only got a quaternion->euler angles routine that works
 in the ZYZ convention but I have read a paper that generalises my method
 to all valid axis conventions. Will probably impliment as something like:
 toEulerAngles(string convention="XYZ")()

 Vectors:
 opAdd, opSub, opMult(scalar), opMult(vector)*, cross**, Normalise,
 Normalized, Length
What is the representation of vectors? I'm afraid the design above would be too limited for what we need.
A fixed sized array where V[0] ~ x, V[1] ~ y and V[2] ~ z. The field the vector is defined over is templated. What other operators are needed? I'd defiantly want to add swizzling. http://www.ogre3d.org/docs/api/html/classOgre_1_1Vector3.html looks like it could be a good source of ideas.
 * dot product. Would this be better named as dot()?
 We already have dot product and normalization routines that work with 
 general ranges.
 
 http://www.digitalmars.com/d/2.0/phobos/std_numeric.html#dotProduct
 http://www.digitalmars.com/d/2.0/phobos/std_numeric.html#normalize
 
 Generally I'd strongly suggest making operations free generic functions 
 instead of members.
I've not really thought about operators as members vs operators as free functions. I just tend to put them as members because it feels more organised. But looking at other implementations, I seem to be in the minority.
 ** 3D vectors only. Perhaps defining a cross product on the

 Matrices:
 opAdd, opSub, opMult(scalar), opMult(vector), opMult(matrix)**, Invert,
 Inverted, Orthogonalize, Orthogonalized, Reorthogonalize***,
 Reorthogonalized***, Det, Transpose, Transposed, Dagger*, Daggered*,
 Eigenvalues****, Eigenvectors****
What is the representation of matrices?
private: F[n*n] mat; where F is the type of the field and n is the dimension of the matrix.
 *The hermitian conjugate/conjugate transpose. Reduces to the transpose
 for a real matrix
Transposition should also be handled in a static manner, e.g. define a transposed view of a matrix that doesn't actually move elements.
Do you mean that a bool should be stored to count the number of transpositions or that there is a type that behaves like a matrix but actually just presents a view of another matrix e.g. Matrix A; ... Matrix B = A.Transposed(); //Changes to B now affect A
 ** Matrix-matrix multiplication doesn't commute. Could this be a problem
 when using operator notation?
Should be fine.
 *** Othogonalize assuming the matrix is nearly orthogonal already
 (possibly using some quick, approximate method such as a Taylor series)
 **** I have a eigenvalue/vector solver for 3x3 matrices which seems
 reasonably stable but needs more testing.

 Free functions:
 MatrixToQuaternion
 QuaternionToMatrix
 + code to allow easy printing to stdout/streams and such.
Sounds encouraging. I think a good next step is to go through a community scrutiny process by dropping the code somewhere on the Web so people can review it.
Couldn't agree more because I'm sure I'll miss tricks and conventions. I would have never thought of that funky swizzling idea. I've also got another question: should matrices, vectors and quaternions be classes or structs? My gut reaction is that they should be structs and thus act like value types. But matrices might be too big and should be passed by reference which would imply they should be a class. Anyone know any rules of thumb that might apply?
I definately think low-dimensional vectors/matrices must be structs. The cost of writing/reading some float/double/real values sitting next in memory is nowhere near the cost of allocating such a new area for each opAdd. Structs can be pooled too, and referred by pointers.
Apr 19 2010
prev sibling next sibling parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Gareth Charnock wrote:
 Andrei Alexandrescu wrote:
 On 04/16/2010 04:25 PM, Gareth Charnock wrote:
 Okay, here goes. I've collected together the basic functionality that
 would probably make a good starting point. As I've mentioned my code is
 very messy and has bits missing (e.g. I never had a use for the cross
 product but it's pretty important in general). I guess a good way to
 begin would be to write the pubic interfaces then start on the
 implementation.

 Cubic Solvers:
 General complex cubic solver with two algorithms (one requiring a
 complex cosine and and arcosine one using only +-*/ and roots). A
 special case cubic solver for the reduced cubic x^^3 + px - q = 0.
This sounds a candidate for std.numeric. How popular/needed are cubic solvers?
They're probably don't come up that frequently but they do they're rather fiddly. Lots of operations to get right. But the solution doesn't depend on anything but basic math operators so once it's written, it's written. I guess the question is whether Phobos is meant to be a small library or a kitchen sink library.
 Quaternions:
 opAdd, opSub, opMult(quaternion), opMult(vector), opDiv, Normalise,
 Normalized, conjugate, conjugated, toEulerAngles*, fromEulerAngles,
 this(real,i,j,k), this(angle,axis), getAngle(), getAxis()
Sounds good, but you'd need to convert the code to the new overloaded operators approach.
Fair enough, and this will be a good opportunity to show off why the new overloading scheme is more powerful (e.g. opAdd and opSub can be combined).
 *Currently I've only got a quaternion->euler angles routine that works
 in the ZYZ convention but I have read a paper that generalises my method
 to all valid axis conventions. Will probably impliment as something 
 like:
 toEulerAngles(string convention="XYZ")()

 Vectors:
 opAdd, opSub, opMult(scalar), opMult(vector)*, cross**, Normalise,
 Normalized, Length
What is the representation of vectors? I'm afraid the design above would be too limited for what we need.
A fixed sized array where V[0] ~ x, V[1] ~ y and V[2] ~ z. The field the vector is defined over is templated. What other operators are needed? I'd defiantly want to add swizzling. http://www.ogre3d.org/docs/api/html/classOgre_1_1Vector3.html looks like it could be a good source of ideas.
 * dot product. Would this be better named as dot()?
 We already have dot product and normalization routines that work with 
 general ranges.

 http://www.digitalmars.com/d/2.0/phobos/std_numeric.html#dotProduct
 http://www.digitalmars.com/d/2.0/phobos/std_numeric.html#normalize

 Generally I'd strongly suggest making operations free generic 
 functions instead of members.
I've not really thought about operators as members vs operators as free functions. I just tend to put them as members because it feels more organised. But looking at other implementations, I seem to be in the minority.
 ** 3D vectors only. Perhaps defining a cross product on the

 Matrices:
 opAdd, opSub, opMult(scalar), opMult(vector), opMult(matrix)**, Invert,
 Inverted, Orthogonalize, Orthogonalized, Reorthogonalize***,
 Reorthogonalized***, Det, Transpose, Transposed, Dagger*, Daggered*,
 Eigenvalues****, Eigenvectors****
What is the representation of matrices?
private: F[n*n] mat; where F is the type of the field and n is the dimension of the matrix.
 *The hermitian conjugate/conjugate transpose. Reduces to the transpose
 for a real matrix
Transposition should also be handled in a static manner, e.g. define a transposed view of a matrix that doesn't actually move elements.
Do you mean that a bool should be stored to count the number of transpositions or that there is a type that behaves like a matrix but actually just presents a view of another matrix e.g. Matrix A; ... Matrix B = A.Transposed(); //Changes to B now affect A
 ** Matrix-matrix multiplication doesn't commute. Could this be a problem
 when using operator notation?
Should be fine.
 *** Othogonalize assuming the matrix is nearly orthogonal already
 (possibly using some quick, approximate method such as a Taylor series)
 **** I have a eigenvalue/vector solver for 3x3 matrices which seems
 reasonably stable but needs more testing.

 Free functions:
 MatrixToQuaternion
 QuaternionToMatrix
 + code to allow easy printing to stdout/streams and such.
Sounds encouraging. I think a good next step is to go through a community scrutiny process by dropping the code somewhere on the Web so people can review it.
Couldn't agree more because I'm sure I'll miss tricks and conventions. I would have never thought of that funky swizzling idea. I've also got another question: should matrices, vectors and quaternions be classes or structs? My gut reaction is that they should be structs and thus act like value types. But matrices might be too big and should be passed by reference which would imply they should be a class. Anyone know any rules of thumb that might apply?
IMO, general vectors/matrices should be structs wrapping a pointer to the data: struct Vector(T) { T* ptr; size_t length; size_t stride; } Low-dimensional fixed-size vectors should probably be value types. -Lars
Apr 19 2010
parent reply Eric Poggel <dnewsgroup yage3d.net> writes:
On 4/19/2010 6:43 AM, Lars T. Kyllingstad wrote:
 IMO, general vectors/matrices should be structs wrapping a pointer to
 the data:

    struct Vector(T)
    {
       T* ptr;
       size_t length;
       size_t stride;
    }

 Low-dimensional fixed-size vectors should probably be value types.
I think it would be confusing to have some vectors as value and others as reference types, unless they were different types in the library itself. I've always used two template parameters, one for type and another for size, but almost all my vectors are only 2-4 components. struct Vector(T, S) { T[S] values; } You can union things out from there so you can still have your .x/y/z properties without the overhead of a function call.
Apr 19 2010
parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
Eric Poggel wrote:
 On 4/19/2010 6:43 AM, Lars T. Kyllingstad wrote:
 IMO, general vectors/matrices should be structs wrapping a pointer to
 the data:

    struct Vector(T)
    {
       T* ptr;
       size_t length;
       size_t stride;
    }

 Low-dimensional fixed-size vectors should probably be value types.
I think it would be confusing to have some vectors as value and others as reference types, unless they were different types in the library itself.
That was the idea, to have *both* a generic Vector(T) type and specialised Vector2D(T) and Vector3D(T) types. -Lars
Apr 19 2010
prev sibling parent Fawzi Mohamed <fawzi gmx.ch> writes:
On 19-apr-10, at 01:11, Gareth Charnock wrote:

 Andrei Alexandrescu wrote:
 On 04/16/2010 04:25 PM, Gareth Charnock wrote:
 Okay, here goes. I've collected together the basic functionality  
 that
 Quaternions:
 opAdd, opSub, opMult(quaternion), opMult(vector), opDiv, Normalise,
 Normalized, conjugate, conjugated, toEulerAngles*, fromEulerAngles,
 this(real,i,j,k), this(angle,axis), getAngle(), getAxis()
Sounds good, but you'd need to convert the code to the new overloaded operators approach.
Fair enough, and this will be a good opportunity to show off why the new overloading scheme is more powerful (e.g. opAdd and opSub can be combined).
About the overloading of opIndex still think that having just an opIndexLhs might have been a little bit cleaner (you basically pick up all overloading of the underlying type without any extra code), but as overloading has become extremely easy it is not a big issue.
Apr 19 2010
prev sibling parent reply Eric Poggel <dnewsgroup yage3d.net> writes:
On 4/16/2010 10:41 PM, Andrei Alexandrescu wrote:
 Generally I'd strongly suggest making operations free generic functions
 instead of members.
I disagree on this one. It unnecessarily adds more names to an outer namespace and makes code less readable: vec1.cross(vec2).project(vec3).length(); vs: length(project(cross(vec1, vec2), vec3); The first reads naturally while the second is more like polish notation and is easier to forget parentheses, as I did.
Apr 19 2010
next sibling parent Eric Poggel <dnewsgroup yage3d.net> writes:
Also, the first syntax will give you intellisense in many IDE's.
Apr 19 2010
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 04/19/2010 02:41 PM, Eric Poggel wrote:
 On 4/16/2010 10:41 PM, Andrei Alexandrescu wrote:
 Generally I'd strongly suggest making operations free generic functions
 instead of members.
I disagree on this one. It unnecessarily adds more names to an outer namespace and makes code less readable: vec1.cross(vec2).project(vec3).length(); vs: length(project(cross(vec1, vec2), vec3); The first reads naturally while the second is more like polish notation and is easier to forget parentheses, as I did.
Notationally I agree - but you are (or at least should be) able to invoke a nonmember as if it were a member. Andrei
Apr 19 2010
prev sibling parent reply Clemens <eriatarka84 gmail.com> writes:
Eric Poggel Wrote:

 On 4/16/2010 10:41 PM, Andrei Alexandrescu wrote:
 Generally I'd strongly suggest making operations free generic functions
 instead of members.
I disagree on this one. It unnecessarily adds more names to an outer namespace and makes code less readable: vec1.cross(vec2).project(vec3).length(); vs: length(project(cross(vec1, vec2), vec3); The first reads naturally while the second is more like polish notation and is easier to forget parentheses, as I did.
For the record: at least for cross(), I prefer the latter version. It always seemed awkward to me to make a symmetric (ok, anti-symmetric in this case) operation like this a member, because vec1.cross(vec2) doesn't look symmetric at all anymore. Furthermore, in the absence of an actual operator for the cross product (which we can't have, unless we resort to overloading abuse), the latter is closer to mathematical notation. -- Clemens
Apr 20 2010
next sibling parent #ponce <spam spam.spam> writes:
 For the record: at least for cross(), I prefer the latter version. It always
seemed awkward to me to make a symmetric (ok, anti-symmetric in this case)
operation like this a member, because vec1.cross(vec2) doesn't look symmetric
at all anymore. Furthermore, in the absence of an actual operator for the cross
product (which we can't have, unless we resort to overloading abuse), the
latter is closer to mathematical notation.
 
 -- Clemens
I also prefer the second version. Don't we like to write max(a, b) and not a.max(b) ? Ideally I'd like to be able to write operation(x) or operation(x, y) indifferently with x and y being a scalar or a small vector type, like in shader languages. I tried with min/max but failed due to ambiguous overloading: T min(T)(T a, T b) vs vec2!(T) min(T)(vec2!(T) a, vec2!(T) b) and finally changed names (min, min2, min3...) to overcome this. D has modules, overload sets, specialization etc... so maybe someone more skilled can figure how to sort it out.
Apr 20 2010
prev sibling parent Gareth Charnock <gareth.tpc gmail.com> writes:
Clemens wrote:
 Eric Poggel Wrote:
 
 On 4/16/2010 10:41 PM, Andrei Alexandrescu wrote:
 Generally I'd strongly suggest making operations free generic functions
 instead of members.
I disagree on this one. It unnecessarily adds more names to an outer namespace and makes code less readable: vec1.cross(vec2).project(vec3).length(); vs: length(project(cross(vec1, vec2), vec3); The first reads naturally while the second is more like polish notation and is easier to forget parentheses, as I did.
For the record: at least for cross(), I prefer the latter version. It always seemed awkward to me to make a symmetric (ok, anti-symmetric in this case) operation like this a member, because vec1.cross(vec2) doesn't look symmetric at all anymore. Furthermore, in the absence of an actual operator for the cross product (which we can't have, unless we resort to overloading abuse), the latter is closer to mathematical notation. -- Clemens
Oddly I tend to like v1.cross(v2) because for me that feels closer to the the mathematical notation with the cross sitting between the two vectors. But for D at least it's a none issue because both will work.
Apr 20 2010
prev sibling next sibling parent reply BLS <windevguy hotmail.de> writes:
Like so many hopeful enthusiasts you are trying to bring in something. I 
regret that I have to tell you that Phobos is a one man show.

ATM we have a situation where the compiler tries to support ideas 
written in book not yet available for a library which exist in outer space.
See concurrence (news group) ,container (D)

I think we can say that Phobos is a ridiculous tiny library. but in case 
that you have a look on what is  happening outside .. a lot. This is 
where your library will/can survive.

Bjoern. 10000 A  (B)en(H)inckle



On 15/04/2010 20:49, Gareth Charnock wrote:
 As a side effect of my PhD project I've got a collection of mathematical
 classes. I'd be happy to collect them together, tidy them up and donate
 them to phobos the authors are interested in including them. Matrices
 and vectors in particular get reinvented all the time so I'm sure users
 of D will appreciate them being there. Quaternions are probably somewhat
 more specialised; they are most often used for representing rotations
 (they have different advantages and disadvantages to rotation matrices).
 I've also written a solver for cubic equations.

 The matrix and vector classes are of the sort where the dimension is
 known at compile time and will probably be most useful for modelling
 geometry. High dimensional matrices and vectors are probably better left
 to a scientific library (I remember there was talk that one might be
 being proposed).

 Would this sort of functionality be useful for phobos? At the moment, I
 can't promise anything, I'm just trying to judge the interest should I
 find time to look into it.

 Gareth Charnock
Apr 15 2010
parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
BLS wrote:
 Like so many hopeful enthusiasts you are trying to bring in something. I 
 regret that I have to tell you that Phobos is a one man show.
Actually, it is more like a six- or seven-man show, and the number of developers is growing.
 ATM we have a situation where the compiler tries to support ideas 
 written in book not yet available for a library which exist in outer space.
 See concurrence (news group) ,container (D)
The concurrency stuff seems to be well under way. (An incomplete version of) std.concurrency was included with 2.043.
 I think we can say that Phobos is a ridiculous tiny library. but in case 
 that you have a look on what is  happening outside .. a lot. This is 
 where your library will/can survive.
By posting messages like this, you're not exactly helping Phobos grow and gain more developers. Potential contributor: "Hey, I have some code which I think would be useful for Phobos." You: "Forget it, you'll never get it in. Besides, Phobos sucks anyway, and there's no point in trying to improve it." I mean, what are you trying to achieve with this? -Lars
 On 15/04/2010 20:49, Gareth Charnock wrote:
 As a side effect of my PhD project I've got a collection of mathematical
 classes. I'd be happy to collect them together, tidy them up and donate
 them to phobos the authors are interested in including them. Matrices
 and vectors in particular get reinvented all the time so I'm sure users
 of D will appreciate them being there. Quaternions are probably somewhat
 more specialised; they are most often used for representing rotations
 (they have different advantages and disadvantages to rotation matrices).
 I've also written a solver for cubic equations.

 The matrix and vector classes are of the sort where the dimension is
 known at compile time and will probably be most useful for modelling
 geometry. High dimensional matrices and vectors are probably better left
 to a scientific library (I remember there was talk that one might be
 being proposed).

 Would this sort of functionality be useful for phobos? At the moment, I
 can't promise anything, I'm just trying to judge the interest should I
 find time to look into it.

 Gareth Charnock
Apr 16 2010
parent Gareth Charnock <gareth.tpc gmail.com> writes:
"Hopeful enthusiast" probably describes me quite well! :) From my point 
of view I can see a wheel that keeps getting reinvented (and the process 
of reinventing that wheel is both fiddly and quite dull), a really great 
looking language that needs better library support.

Now I am aware that D has a reputation for not being as open as one 
might like, but the general consensus seems to be that things are 
getting better, which is why I'm posting first to check if the authors 
of Phobos are open to the idea of having matrices, vectors and 
quaternions and such.

Gareth Charnock

Lars T. Kyllingstad wrote:
 BLS wrote:
 Like so many hopeful enthusiasts you are trying to bring in something. 
 I regret that I have to tell you that Phobos is a one man show.
Actually, it is more like a six- or seven-man show, and the number of developers is growing.
 ATM we have a situation where the compiler tries to support ideas 
 written in book not yet available for a library which exist in outer 
 space.
 See concurrence (news group) ,container (D)
The concurrency stuff seems to be well under way. (An incomplete version of) std.concurrency was included with 2.043.
 I think we can say that Phobos is a ridiculous tiny library. but in 
 case that you have a look on what is  happening outside .. a lot. This 
 is where your library will/can survive.
By posting messages like this, you're not exactly helping Phobos grow and gain more developers. Potential contributor: "Hey, I have some code which I think would be useful for Phobos." You: "Forget it, you'll never get it in. Besides, Phobos sucks anyway, and there's no point in trying to improve it." I mean, what are you trying to achieve with this? -Lars
 On 15/04/2010 20:49, Gareth Charnock wrote:
 As a side effect of my PhD project I've got a collection of mathematical
 classes. I'd be happy to collect them together, tidy them up and donate
 them to phobos the authors are interested in including them. Matrices
 and vectors in particular get reinvented all the time so I'm sure users
 of D will appreciate them being there. Quaternions are probably somewhat
 more specialised; they are most often used for representing rotations
 (they have different advantages and disadvantages to rotation matrices).
 I've also written a solver for cubic equations.

 The matrix and vector classes are of the sort where the dimension is
 known at compile time and will probably be most useful for modelling
 geometry. High dimensional matrices and vectors are probably better left
 to a scientific library (I remember there was talk that one might be
 being proposed).

 Would this sort of functionality be useful for phobos? At the moment, I
 can't promise anything, I'm just trying to judge the interest should I
 find time to look into it.

 Gareth Charnock
Apr 16 2010
prev sibling next sibling parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Thu, 15 Apr 2010 15:49:41 -0300, Gareth Charnock  
<gareth.charnock gmail.com> wrote:

 As a side effect of my PhD project I've got a collection of mathematical  
 classes. I'd be happy to collect them together, tidy them up and donate  
 them to phobos the authors are interested in including them. Matrices  
 and vectors in particular get reinvented all the time so I'm sure users  
 of D will appreciate them being there. Quaternions are probably somewhat  
 more specialised; they are most often used for representing rotations  
 (they have different advantages and disadvantages to rotation matrices).  
 I've also written a solver for cubic equations.

 The matrix and vector classes are of the sort where the dimension is  
 known at compile time and will probably be most useful for modelling  
 geometry. High dimensional matrices and vectors are probably better left  
 to a scientific library (I remember there was talk that one might be  
 being proposed).

 Would this sort of functionality be useful for phobos? At the moment, I  
 can't promise anything, I'm just trying to judge the interest should I  
 find time to look into it.

 Gareth Charnock
I've also re-invented this wheel for my research (vectors and quaternions). I'll gladly send you a copy if you want to have a look-see.
Apr 15 2010
parent reply Fawzi Mohamed <fawzi gmx.ch> writes:
On 16-apr-10, at 04:46, Robert Jacques wrote:

 On Thu, 15 Apr 2010 15:49:41 -0300, Gareth Charnock <gareth.charnock gmail.com 
 wrote:
 As a side effect of my PhD project I've got a collection of  
 mathematical classes. I'd be happy to collect them together, tidy  
 them up and donate them to phobos the authors are interested in  
 including them. Matrices and vectors in particular get reinvented  
 all the time so I'm sure users of D will appreciate them being  
 there. Quaternions are probably somewhat more specialised; they are  
 most often used for representing rotations (they have different  
 advantages and disadvantages to rotation matrices). I've also  
 written a solver for cubic equations.

 The matrix and vector classes are of the sort where the dimension  
 is known at compile time and will probably be most useful for  
 modelling geometry. High dimensional matrices and vectors are  
 probably better left to a scientific library (I remember there was  
 talk that one might be being proposed).

 Would this sort of functionality be useful for phobos? At the  
 moment, I can't promise anything, I'm just trying to judge the  
 interest should I find time to look into it.

 Gareth Charnock
I've also re-invented this wheel for my research (vectors and quaternions). I'll gladly send you a copy if you want to have a look- see.
I use (sligltly patched) omg versions of these http://team0xf.com:8080/omg that seem to work reasonably well for my purposes (D1.0) Fawzi
Apr 16 2010
parent "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 16 Apr 2010 08:53:28 -0300, Fawzi Mohamed <fawzi gmx.ch> wrote:

 On 16-apr-10, at 04:46, Robert Jacques wrote:

 On Thu, 15 Apr 2010 15:49:41 -0300, Gareth Charnock  
 <gareth.charnock gmail.com> wrote:

 As a side effect of my PhD project I've got a collection of  
 mathematical classes. I'd be happy to collect them together, tidy them  
 up and donate them to phobos the authors are interested in including  
 them. Matrices and vectors in particular get reinvented all the time  
 so I'm sure users of D will appreciate them being there. Quaternions  
 are probably somewhat more specialised; they are most often used for  
 representing rotations (they have different advantages and  
 disadvantages to rotation matrices). I've also written a solver for  
 cubic equations.

 The matrix and vector classes are of the sort where the dimension is  
 known at compile time and will probably be most useful for modelling  
 geometry. High dimensional matrices and vectors are probably better  
 left to a scientific library (I remember there was talk that one might  
 be being proposed).

 Would this sort of functionality be useful for phobos? At the moment,  
 I can't promise anything, I'm just trying to judge the interest should  
 I find time to look into it.

 Gareth Charnock
I've also re-invented this wheel for my research (vectors and quaternions). I'll gladly send you a copy if you want to have a look- see.
I use (sligltly patched) omg versions of these http://team0xf.com:8080/omg that seem to work reasonably well for my purposes (D1.0) Fawzi
However, license on these and their dependencies are not Phobos compatible.
Apr 16 2010
prev sibling parent reply #ponce <spam spam.spam> writes:
I don't know if this help, but here is a subset of my "math" package I've used
in real-time applications.

http://ponce.paradisia.net/temp/math_package.zip

Such code is absolutely not what one would expect to find in a standard library
(lots of assembly, almost no std.math, no safety-checks, no clever templates)
but it works for me. You may find some useful parts in it.

Maybe merging the good ideas of OMG, Yage, your code, etc... (and sorting out
licences "problems")... would lead to a better low-dimensionnal math package
class.

Thingsq important to me:
- expressivity
Apr 19 2010
next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
#ponce wrote:
 I don't know if this help, but here is a subset of my "math" package I've used
in real-time applications.
 
 http://ponce.paradisia.net/temp/math_package.zip
 
 Such code is absolutely not what one would expect to find in a standard
library (lots of assembly, almost no std.math, no safety-checks, no clever
templates) but it works for me. You may find some useful parts in it.
 
 Maybe merging the good ideas of OMG, Yage, your code, etc... (and sorting out
licences "problems")... would lead to a better low-dimensionnal math package
class.
 
 Thingsq important to me:
 - expressivity
I like this (from your math.vec3 module): struct vec3(T) { union { struct { T x, y, z; } T[3] v; } ... } That's a pretty neat trick. :) I didn't even know anonymous unions were possible. -Lars
Apr 19 2010
prev sibling parent Eric Poggel <dnewsgroup yage3d.net> writes:
On 4/19/2010 7:36 AM, #ponce wrote:
 Maybe merging the good ideas of OMG, Yage, your code, etc... (and sorting out
licences "problems")... would lead to a better low-dimensionnal math package
class.
I'm willing to re-license any of Yage's math library under whatever terms are necessary for inclusion in D's standard library, even if only bits and pieces are borrowed. http://dsource.org/projects/yage/browser/trunk/src/yage/core/math The Matrix and Quaternion classes would be better if they were templated, but there's a Vector class that's templated on both type and number of parameters. In its design I tried to lean toward immutability, so you have methods like .toRotationMatrix() instead of matrix.setFromRotationAxis(Vector axis). If nothing from Yage is used I hope to at least encourage this type of design.
Apr 19 2010