Topic: Quaternions [long]
Author: Hubert Holin <hubert.holin@meteo.fr>
Date: 2000/06/07 Raw View
Paris (U.E.), le 06/06/2000
Stephen Howe wrote:
>
> Hubert Holin <hubert.holin@meteo.fr> wrote in message
> news:3933A60B.5BAD438A@meteo.fr...
>
> > So far, the opposition to including quaternions (among others) in a
> > revision of the C++ standard are along one of the following lines:
[SNIP]
> There is a 6th (and to my mind the only one that really counts):
>
> 6) It has to be likely to be used by a reasonable proportion of the C++
> community.
>
> And if quaternions is allowed in, why stop at that? Why not allow _all_ the
Indeed, why not? Are we really satisfied with the selection of
functions currently in the standard? What are we using the current
selection for, and what can't we (simply) do without some more?
> functions in Abrahams and Stegun including the complex arg variants? And
> also why restrict it to just mathematical functions? I can see the
> scientific community, the statistical community, thew graphical algorithms
What would be inherently wrong with some support for the statistical community?
It has been argued that graphical algorithms should be outside the
realm of the standard library because (quite a few) targets of the
language do not have a graphical output. It has also been argued that
not position has been taken relative to threads, in part because the
programming model would have to be readressed.
But more scientific objects would need no readressing of the
programming model, and I am quite positive that not a few targets which
do not have a graphical output would benefit from the presence of these
objects (there *is* a reason some functions are called "special", after
all, and it is usually not only because of their interest to the sole
field of mathematics).
> community wanting their functions added as well. Where do you draw the line?
>
> It is not unreasonable to restrict the libraries to those functions that are
> likely to be commonly used.
>
> --
> Stephen Howe
This begs, once again, the question: how do you measure "commonly"? By
the number of coders, by the numbers of projects, by the number of
shipping products which would or do use them?
It is no secret that projects are underfoot to provide "reference"
implementations of some of these objects (see the NIST and BOOST web
pages, among others). In what way would it be detrimental to the C++
community to say these "references" are part of the *standard* (in a
future incarnation thereof)? I see benefits here, and have yet to be
convinced of costs (even to implementors, in this case, beyond the need
to adhere to the standard as it stands now).
Hubert Holin
Hubert.Holin@Bigfoot.com, hh@Holin.com
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Dietmar Kuehl <dietmar.kuehl@claas-solutions.de>
Date: 2000/06/07 Raw View
Hi,
In article <393D075B.CBB76682@meteo.fr>,
Hubert.Holin@Bigfoot.com, Hubert.Holin@fr.fr wrote:
> I see benefits here, and have yet to be convinced of costs (even to
> implementors, in this case, beyond the need to adhere to the standard
> as it stands now).
At minimum cost the number of different implementations will be reduced
if the size of the library is increased. As far as I can tell, Object
Space is struggling with getting the current library done at all, not
because they are not capable to implement it but due to lack of
resources. RogueWave took at least a long time before shipping a
standard version (if they are shipping one now), and I don't know
anything at all about Modena. The only commercial implementation I'm
aware and which is complete and available to more than one compiler is
from Dinkumware. Other than this I know only of the library shipping
with the Metrowerks compiler and the SGI one. Other than this, there
are basically two free implementations at least on the way plus a free
version of the SGI implementation under the name STLport. I know for
sure that you would kill off one of the free implementations, namely
mine, if the library is significantly increased: I think I can do what
is currently in the standard plus a reasonable increase for the next
round of standardization. However, I just can't add all areas of
scientific computing which might be of interest: not because I cannot
deal with this numeric stuff but rather because it takes time.
... and I'm pretty sure that some of the other library vendors would
also give up on the standard C++ library and rather provide libraries
for other areas or other languages. Personally, I think even the
current situation is rather bad because there is basically one
implementation dominating the market just because it is complete, not
because it is good! With an increased library this situation would get
even worse.
--
<mailto:dietmar.kuehl@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Stephen Howe" <SPAMGUARDstephen.howe@dial.pipex.co.uk>
Date: 2000/06/06 Raw View
Hubert Holin <hubert.holin@meteo.fr> wrote in message
news:3933A60B.5BAD438A@meteo.fr...
> So far, the opposition to including quaternions (among others) in a
> revision of the C++ standard are along one of the following lines:
>
> 1) We will never be able to muster the human expertise/financial
> wherewithal to include the proposals in the revised standard.
>
> 2) The standard has many more serious shortcomings that should be
addressed.
>
> 3) We do not need it, because "somebody" else might provide it.
>
> 4) It is not hardware acceleratable.
>
> 5) Hey, you can't have it 'cause my own pet project won't make the cut!
>
> Not to mention "let's not put in any math, otherwise everybody and his
> dog will run away screaming!"
There is a 6th (and to my mind the only one that really counts):
6) It has to be likely to be used by a reasonable proportion of the C++
community.
And if quaternions is allowed in, why stop at that? Why not allow _all_ the
functions in Abrahams and Stegun including the complex arg variants? And
also why restrict it to just mathematical functions? I can see the
scientific community, the statistical community, thew graphical algorithms
community wanting their functions added as well. Where do you draw the line?
It is not unreasonable to restrict the libraries to those functions that are
likely to be commonly used.
--
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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: 2000/06/01 Raw View
Hubert Holin <hubert.holin@meteo.fr> writes:
| Paris (U.E.), le 31/05/2000
|
| Actually no, "norm" in this case is perfectly correct, *if* it is
| understood as a *Cayley* norm, and not a norm as associated to a
| quadratic form.
But then why not call it cayley_norm? Just to add to the confusion?
As I understood it std::norm(const std::complex<T>&) is for numerical
computation, not abstract algebra. In the numerical computing
community, norm has a well defined meaning which is not "cayley" norm.
--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: 2000/06/01 Raw View
"John D. Hickin" <hickin@cam.org> writes:
| Naming it properly may be a a bit difficult.
I don't think so. Following the numerical computing community
terminology should make it less hard than it may appear.
| I assume that the intent, among other things, was to provide a convenient
| place in which park a function that computed re*re+im*im which is quite
| generally useful.
It isn't the usefulness that is being discussed here. It is the name.
| ... This quantity is a distance function [1]
That is wrong. For a couple of reasons. Firstly, if you read carefully
the reference you're indicating, you should notice that a distance on
complex numbers would take two complex numbers as arguments. But I'm
willing to admit that the first or second argument might be
undertstood as being zero. But then, we should be talking of norm
function, not distance.
Secondly, the property violated by the function we're discussing is
not the homogeneity, but what is called the triangular inequality,
namely given x, y, z, the following is satisfied by any distance
function d:
d(x, y) <= d(x, z) + d(z, y).
Now if you take
x = 0; y = 3; z = 1 + i;
you readly verify that
d(x, y) = 3 * 3 = 9
d(x, z) = 1*1 + 1*1 = 2
d(z, y) = 2*2 + 1*1 = 5
and we don't have d(x, y) <= d(x, z) + d(z, y).
[...]
| [1] Dieudonne, Foundations of Modern Analysis, Section 3.1, Academic Press,
| 1960, 1969
|
| [2] By this I mean Norm(lambda*x) = abs(lambda)*Norm(x).
Most importantly one should have:
norm(x + y) <= norm(x) + norm(y) (cf. [1] section 5.1)
which we don't have. Which make std::norm "broken".
Now, I should admit that in number theory (especially in the theory of
filed extensions), one defines something called "norm". For example,
admiting that the instantiation of std::complex on int is well defined
(one gets what is called gaussian integers), one could make sense of
std::norm.
But that has nothing to do with what every numerical analyst
undertands by norm.
--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/06/01 Raw View
In article <3933A60B.5BAD438A@meteo.fr>, Hubert Holin
<hubert.holin@meteo.fr> writes
> The fourth objection is in my view not valid. On the one hand I would
>find it hard to believe that every numerical function included in the
>standard has a hardware counterpart in every target for which there is a
>C++ compiler (the sheer volume of the EC++ controversy would certainly
>suggest this is not the case), and on the other hand I think I remember
>some display (for chemistry) for which rotations in 3D where
>hardware-accelerated, and hardware-accelerating quaternions would be a
>way of achieving this (though I do not remember the specifics of that
>display, or even if they disclosed their technique).
No, the point was that elements of the Standard library can use
'compiler magic' and where something might benefit from that and there
is a reasonable expectation that some hardware exists that can provide
that benefit it is legitimate to include them.
What is so special about mathematical problem domains that justifies
giving it special treatment? I would greatly encourage the development
of application specific (and those include many of the diverse areas of
mathematics) standard libraries. However these should be standardised
by domain specialists, language standards are the domain of language
designers.
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/06/01 Raw View
In article <flaehamsia.fsf@flan.cmla.ens-cachan.fr>, Gabriel Dos Reis
<dosreis@cmla.ens-cachan.fr> writes
>Actually, I feel that beats like quaternions or octonions should be
>handled by domain specific library extensions. Not that I think they
>are not important, nor unused.
Exactly, and language lawyers are not the people to write those.
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Dietmar Kuehl <dietmar.kuehl@claas-solutions.de>
Date: 2000/06/01 Raw View
Hi,
In article <3933A60B.5BAD438A@meteo.fr>,
Hubert.Holin@Bigfoot.com, Hubert.Holin@meteo.fr wrote:
> 5) Hey, you can't have it 'cause my own pet project won't make the
> cut!
Basically, the argument goes the other way around: If we start adding
everything which is useful, like eg. quaternions, we start adding quite
a lot of stuff! Those components mentioned are as useful as quaternions
and should be added under the arguments quaternions are. ... and we
have seen so far only a fraction of the useful components.
As the C++ standard works currently, I would be very careful with any
addition to the library because whatever goes in there has to be
implemented by every standard library to be conformant. The bigger that
gets, the more likely only a single vendor is able to provide a crappy
implementation. Actually, looking at the current market for standard
C++ libraries you can legitemately claim that we are already pretty
close to this situation with the existing specification!
What I consider to be a reasonable alternative is to specify optional
components: If an implementation chooses to implement a specific
component, it has to follow the rules set up in the standard. If an
implementation does not implement it, it has to say so and a third
party implementation of this component should be permitted. Whether an
implementation chooses to implement a certain component would fall into
the quality of implementation realm. ... and implementation for a
system with hardware support for a specific component might very well
choose to put the support into the compiler to access the hardware
efficiently.
With optional components quaternions can well become part of the C++
standard, as can the various other components already mentioned and
all those other useful components. The only problem we are still stuck
with are the resources needed for the proper specification of such
components.
--
<mailto:dietmar.kuehl@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: 2000/06/01 Raw View
James Kuyper <kuyper@wizard.net> writes:
[...]
| Yes, but does it belong in the language standard? I don't think so. Let
| there be a standard for scientific computing. It could even be a
| cross-language standard.
Exactly. For example, ISO/WG11 is putting effort to codify
language-independent APIs and language bindings. It produced
LIA-1. LIA-2 will attein the FDIS stage shortly. We started work on
LIA-3 (complex numbers and related functions).
For more ambituous projects, I'd recommand joining both the OON list
and WG11.
--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: 2000/05/31 Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:
| Hubert HOLIN wrote:
| >
| > Paris (U.E.), le 23/05/2000
| >
| > Quaternions are a useful, if somewhat lesser known, kin to the complex
| > numbers. It is my contention that at least minimal support should be
| > added to the C++ standard. As a first step towards that goal, I present
| > here a possible implementation, along the line of the complex numbers,
| > to help define the "existing art", when the standard comes up for
| > revision some time in the (distant) future.
|
| [...]
|
| There once was (either in this newsgroup, or in comp.lang.c++.moderated)
| a proposal to do a slight change to the definition of complex<T>.
| This proposal would have allowed to get quaternions with
| complex<complex<T> > and octonions with complex<complex<complex<T> > >
| (and so on).
| If quaternions should be included into the C++ standard, I'd say
| that's the better way to do it.
Actually, I feel that beats like quaternions or octonions should be
handled by domain specific library extensions. Not that I think they
are not important, nor unused.
--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Dietmar Kuehl <dietmar.kuehl@claas-solutions.de>
Date: 2000/05/31 Raw View
Hi,
In article <flhfbimsun.fsf@flan.cmla.ens-cachan.fr>,
Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> wrote:
> What when functions in the established interfaces are misnamed? I'm
> thinking of std::norm(const std::complex<T>&) which is everything but
> a norm.
Good point. I'm not sure whether this would qualify as a defect report
but filing it with a suggestion that this should at least be fixed in
a future revision would probably put it on the list of things to be
done.
--
<mailto:dietmar.kuehl@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hubert Holin <hubert.holin@meteo.fr>
Date: 2000/05/31 Raw View
Paris (U.E.), le 30/05/2000
Gabriel Dos Reis wrote:
>
> Francis Glassborow <francis@robinton.demon.co.uk> writes:
>
> [...]
>
> | Anyway, how about support for tensors, DR Conway's numerical system
> | (very important to Games Theorists), determinants etc. And, of course,
> | we really ought to add support for polynomials, groups and fields. If
> | you really insist I can add quite a few other 'desirable' mathematical
> | entities.
>
> Well, since I'm doing Geometry and I use C++ most of the time to
> generate complicated surfaces modeled on Riemann Surfaces, and given
> their importance to the `computational differential geometry'
> community I think Standard C++ ought to include data structures for
> Riemann surfaces. Oh, while we are at it, there ought to be a data
> structure for differential forms, ODE and PDE solvers.
>
> Of course, that list is not complete, but it is intented to make C++'s
> library not too minimalist ;-)
>
> --
> Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
So far, the opposition to including quaternions (among others) in a
revision of the C++ standard are along one of the following lines:
1) We will never be able to muster the human expertise/financial
wherewithal to include the proposals in the revised standard.
2) The standard has many more serious shortcomings that should be addressed.
3) We do not need it, because "somebody" else might provide it.
4) It is not hardware acceleratable.
5) Hey, you can't have it 'cause my own pet project won't make the cut!
Not to mention "let's not put in any math, otherwise everybody and his
dog will run away screaming!"
The first objection is a sad fact of life, provided the current way of
carrying out the standardization is maintained. I remember alternatives
being put forward in this forum.
The second objection is true (say, for instance the lack of integer
types with a fixed and guaranteed number of bits...), but only is a
valid objection when taken together with the first. Curing the first
would, I believe, cure this one as well.
The third objection is not really reasonable. True, third-party
libraries do and should exist. They provide test-beds for new ideas and
techniques, or for implementations of (very) old ones. Third-party
implementations may be nice (or not), but they would almost certainly
lead to incompatibilities. As one poster mentioned, there is no
prescription for third-party libraries so they mix well. And one could
never be sure, on a given platform/compiler that they are available.
Scientific computing, and the reasons for carrying it out, are difficult
enough that we could use all the help we could get.
Restricting the tools of scientific computing to the realm of
third-party implementation raises the question of what exactly are we
doing with the language. Forever writing the same spreadsheet or
database? Why accept a very detailed set of objects and algorithms
which, if admittedly widespread, are not important to all, and reject
objects and algorithm which are vital to a (not so) few? Why include
log10 and not Bessel functions? Why include complex numbers and not
quaternions? Should we stick only to what has more or less always be
around without wondering what we really need? In some respect, the Box
has been opened already: C did not have a "standard" library, and C++ does.
The fourth objection is in my view not valid. On the one hand I would
find it hard to believe that every numerical function included in the
standard has a hardware counterpart in every target for which there is a
C++ compiler (the sheer volume of the EC++ controversy would certainly
suggest this is not the case), and on the other hand I think I remember
some display (for chemistry) for which rotations in 3D where
hardware-accelerated, and hardware-accelerating quaternions would be a
way of achieving this (though I do not remember the specifics of that
display, or even if they disclosed their technique).
Hubert Holin
Hubert.Holin@Bigfoot.com
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "John D. Hickin" <hickin@cam.org>
Date: 2000/05/31 Raw View
Naming it properly may be a a bit difficult.
I assume that the intent, among other things, was to provide a convenient
place in which park a function that computed re*re+im*im which is quite
generally useful. This quantity is a distance function [1], lacking only one
property [2] to qualify it as a true norm. But, AFAIK, the word _distance_
has other connotations within the standard.
Regards, John.
[1] Dieudonne, Foundations of Modern Analysis, Section 3.1, Academic Press,
1960, 1969
[2] By this I mean Norm(lambda*x) = abs(lambda)*Norm(x).
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 2000/06/01 Raw View
"Hubert Holin" <hubert.holin@meteo.fr> wrote in message
news:3933A60B.5BAD438A@meteo.fr...
>
> So far, the opposition to including quaternions (among others) in a
> revision of the C++ standard are along one of the following lines:
>
> 4) It is not hardware acceleratable.
>
That's a rather narrow argument. Perhaps the original reason for the
existence of a standard library in C was to gloss over all the things
which depend on your OS or hardware. This includes things that are
hardware acceleratable, but also things that are just plain different
from one machine to another. That considerably widens the field for
"would-be" libraries, to things like threads, user interfaces, object
brokers and the like, but I don't see that it widens it far enough to
include mathematical material.
In fairness, the standard C++ library also includes things which are
"largely portable" and are there simply because they would otherwise
be reinvented by everyone, like a string class or standard containers
and algorithms. Here you are on much firmer ground, but there is already
a healthy market in third party mathematical libraries. (The maths
routines currently in C/C++ relate to common floating point hardware
and therefore qualify under your point 4.)
Besides which, I can think of several people who would argue that
quaternions are completely subsumed, along with spinors, vectors,
tensors and differential forms in Clifford algebras (such as the
Geometric Algebra popularised by David Hestenes). Providing a
standard implementation of quaternions would be a mis-direction
of effort :-)
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 2000/06/01 Raw View
Hubert Holin wrote:
....
> So far, the opposition to including quaternions (among others) in a
> revision of the C++ standard are along one of the following lines:
Rearranging to put summaries with details:
> 3) We do not need it, because "somebody" else might provide it.
....
> The third objection is not really reasonable. True, third-party
> libraries do and should exist. They provide test-beds for new ideas and
> techniques, or for implementations of (very) old ones. Third-party
> implementations may be nice (or not), but they would almost certainly
> lead to incompatibilities. As one poster mentioned, there is no
> prescription for third-party libraries so they mix well. And one could
> never be sure, on a given platform/compiler that they are available.
> Scientific computing, and the reasons for carrying it out, are difficult
> enough that we could use all the help we could get.
Yes, but does it belong in the language standard? I don't think so. Let
there be a standard for scientific computing. It could even be a
cross-language standard. The people on the C++ committee are programming
experts, but not necessarily qualified to judge scientific applications
packages.
> 4) It is not hardware acceleratable.
....
> Restricting the tools of scientific computing to the realm of
> third-party implementation raises the question of what exactly are we
> doing with the language. Forever writing the same spreadsheet or
> database? Why accept a very detailed set of objects and algorithms
> which, if admittedly widespread, are not important to all, and reject
> objects and algorithm which are vital to a (not so) few? Why include
> log10 and not Bessel functions? Why include complex numbers and not
> quaternions? Should we stick only to what has more or less always be
Because log10 is much more widely used than Bessel functions. Because
complex numbers are much more widely used than quaternions.
Standardization is intended for widely used items. The less widely used
a feature is, the less reasonable it is to make it part of the language
standard.
> around without wondering what we really need? In some respect, the Box
> has been opened already: C did not have a "standard" library, and C++ does.
What are you talking about? Section 7 of the C standard devotes several
hundred pages to describing the C standard library. The C++ standard
library explicitly incorporates the C standard library by reference,
with modifications (see Annex C.2 for details). There's a very large
portion of C++ that is not defined in the C++ standard, because it cross
references the C standard for those library functions.
> The fourth objection is in my view not valid. On the one hand I would
> find it hard to believe that every numerical function included in the
> standard has a hardware counterpart in every target for which there is a
> C++ compiler (the sheer volume of the EC++ controversy would certainly
> suggest this is not the case), and on the other hand I think I remember
> some display (for chemistry) for which rotations in 3D where
> hardware-accelerated, and hardware-accelerating quaternions would be a
> way of achieving this (though I do not remember the specifics of that
> display, or even if they disclosed their technique).
You're missing the point. One of many possible justifications for
putting something in the standard is that on many platforms it cannot be
written efficiently in standard C++ code. In that case, providing a
standard function that the implementors can connect to platform-specific
non-C code can carry significant benefits. The potential advantage
doesn't have to exist on all platforms; standardization can be justified
so long as there are a fair number of platforms where it would be a
significant advantage.
All that people are saying is that quaternions don't qualify for this
justification. No one is implying that this is a justification that must
apply for all standard library functions. Most of them qualify for some
other reason.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hubert Holin <hubert.holin@meteo.fr>
Date: 2000/06/01 Raw View
Paris (U.E.), le 31/05/2000
Actually no, "norm" in this case is perfectly correct, *if* it is
understood as a *Cayley* norm, and not a norm as associated to a
quadratic form.
This is a case of an ambiguity in the mathematical language.
However, this fact should be made perfectly clear in the standard, and
*this* could be the subject of a DR.
Hubert Holin
Hubert.Holin@Bigfoot.com, hh@Holin.com
Dietmar Kuehl wrote:
>
> Hi,
> In article <flhfbimsun.fsf@flan.cmla.ens-cachan.fr>,
> Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> wrote:
> > What when functions in the established interfaces are misnamed? I'm
> > thinking of std::norm(const std::complex<T>&) which is everything but
> > a norm.
>
> Good point. I'm not sure whether this would qualify as a defect report
> but filing it with a suggestion that this should at least be fixed in
> a future revision would probably put it on the list of things to be
> done.
> --
> <mailto:dietmar.kuehl@claas-solutions.de>
> homepage: <http://www.informatik.uni-konstanz.de/~kuehl>
>
> Sent via Deja.com http://www.deja.com/
> Before you buy._
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/05/29 Raw View
In article <392E831F.A82FB9CE@meteo.fr>, Hubert Holin
<hubert.holin@meteo.fr> writes
> IMHO it fits in the second category. These are objects on par with
>trigonometric functions (and other special functions), and they are one
>of the building blocks from which one actually computes. Complex numbers
>are (nearly) just as fundamental to use as are real numbers. Integers
>represent another set of modeling properties. C++ as a *computing*
>language would benefit from a set of models which is not too minimalist.
Well I guess that there are a lot of other types that would come ahead
of those in my list. Consider saturated integer types (I hope I have
the term right). Things like quaternions can be added through
libraries, there are other types that are not so easy to add that way.
Anyway, how about support for tensors, DR Conway's numerical system
(very important to Games Theorists), determinants etc. And, of course,
we really ought to add support for polynomials, groups and fields. If
you really insist I can add quite a few other 'desirable' mathematical
entities.
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: 2000/05/29 Raw View
Dietmar Kuehl <dietmar.kuehl@claas-solutions.de> writes:
[ part agreed snipped... ]
| One important issue about this stuff is not really addressed by the
| view mentioned above, and this is the interface to the components: It
| is fairly important that libraries from third parties mix well and thus
| they should rely on common interfaces. This is especially important
| when creating new abstractions. The current standard only coves
| interfaces for things like sequences explicitly. Numeric interfaces are
| not explicitly spelled out but apparent through the interfaces of the
| built-in types and the class templates 'std::complex' and
| 'std::valarray'.
What when functions in the established interfaces are misnamed? I'm
thinking of std::norm(const std::complex<T>&) which is everything but
a norm.
--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Dietmar Kuehl <dietmar.kuehl@claas-solutions.de>
Date: 2000/05/29 Raw View
Hi,
In article <392E831F.A82FB9CE@meteo.fr>,
Hubert.Holin@Bigfoot.com, Hubert.Holin@meteo.fr wrote:
> IMHO it fits in the second category. These are objects on par with
> trigonometric functions (and other special functions), and they are
> one of the building blocks from which one actually computes. Complex
> numbers are (nearly) just as fundamental to use as are real numbers.
> Integers represent another set of modeling properties. C++ as a
> *computing* language would benefit from a set of models which is not
> too minimalist.
The second category I mentioned is for thing benefitting from special
handling by the compiler. Trigonometric functions fall into this
category because the system might have some special way to evaluate
floating point values, eg. a FPU or special registers. Complex numbers
also fall into this category because basically the same holds for them:
I'm not sure whether there really is a processor or FPU dealing with
complex numbers but I wouldn't consider this to be unlikely. Although
not from the theoretic point of view but from the practical, there is
big leap to quaternions: I'm pretty sure that there is no hardware
supporting computations with them. If I'm wrong, quaternions could be
a candidate for the second category although it is still possible to
use a third party library.
What optimizations specific to quaternions do you see to fit them into
the second category? This is not a discussion about the usefulness of
this stuff or how it fits into the theory behind them but about the
performance improvements due to special handling by the compiler.
My feeling is that this is something best dealt with by a third party
library. The interface is basically layed out by the other numeric
types such that different vendors are likely to provide the same
interface. ... and I'm not sure that the standardization committee has
sufficient experience with numerical stuff to lay out a standard for
this stuff anyway. Having a specialized library vendor doing this seems
to provide a better chance to get reasonable results.
One thing which might be desirable to support quaternions by the C++
standard is to allow the user or a third party library to provide
specializations for 'std::complex<T>' if 'T' is a type different from
'float', 'double', and 'long double': Christopher Eltschka
(celtschk@physik.tu-muenchen.de) pointed out that quaternions would be
'std::complex<std::complex<T> >'. Under the current rules of the
standard, it is not permitted to specialize this type (except 'T' is
a user defined type) and 'std::complex' can only be used with the three
floating point types. I haven't tested it but I think my implementation
works with arbitrary types, that is, quaternions might already be
supported with my implementatin...
--
<mailto:dietmar.kuehl@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Stephen Howe" <SPAMGUARDstephen.howe@dial.pipex.co.uk>
Date: 2000/05/30 Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote in message
news:SoARGPArIrL5Ew07@robinton.demon.co.uk...
> If you really insist I can add quite a few other 'desirable' mathematical
> entities.
Yes, such as Bessel functions of the 1st and 2nd Kind, Airy functions, the
list is endless. They are all 'essential'.
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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 2000/05/30 Raw View
Dietmar Kuehl wrote:
>
> Hi,
> In article <392E831F.A82FB9CE@meteo.fr>,
> Hubert.Holin@Bigfoot.com, Hubert.Holin@meteo.fr wrote:
> > IMHO it fits in the second category. These are objects on par with
> > trigonometric functions (and other special functions), and they are
> > one of the building blocks from which one actually computes. Complex
> > numbers are (nearly) just as fundamental to use as are real numbers.
> > Integers represent another set of modeling properties. C++ as a
> > *computing* language would benefit from a set of models which is not
> > too minimalist.
>
> The second category I mentioned is for thing benefitting from special
> handling by the compiler. Trigonometric functions fall into this
> category because the system might have some special way to evaluate
> floating point values, eg. a FPU or special registers. Complex numbers
> also fall into this category because basically the same holds for them:
> I'm not sure whether there really is a processor or FPU dealing with
> complex numbers but I wouldn't consider this to be unlikely. Although
> not from the theoretic point of view but from the practical, there is
> big leap to quaternions: I'm pretty sure that there is no hardware
> supporting computations with them. If I'm wrong, quaternions could be
> a candidate for the second category although it is still possible to
> use a third party library.
>
> What optimizations specific to quaternions do you see to fit them into
> the second category? This is not a discussion about the usefulness of
> this stuff or how it fits into the theory behind them but about the
> performance improvements due to special handling by the compiler.
>
> My feeling is that this is something best dealt with by a third party
> library. The interface is basically layed out by the other numeric
> types such that different vendors are likely to provide the same
> interface. ... and I'm not sure that the standardization committee has
> sufficient experience with numerical stuff to lay out a standard for
> this stuff anyway. Having a specialized library vendor doing this seems
> to provide a better chance to get reasonable results.
>
> One thing which might be desirable to support quaternions by the C++
> standard is to allow the user or a third party library to provide
> specializations for 'std::complex<T>' if 'T' is a type different from
> 'float', 'double', and 'long double': Christopher Eltschka
> (celtschk@physik.tu-muenchen.de) pointed out that quaternions would be
> 'std::complex<std::complex<T> >'. Under the current rules of the
> standard, it is not permitted to specialize this type (except 'T' is
> a user defined type) and 'std::complex' can only be used with the three
> floating point types. I haven't tested it but I think my implementation
> works with arbitrary types, that is, quaternions might already be
> supported with my implementatin...
It's IMHO impossible for a standard conforming implementation,
since the definition of complex<complex<T> > to be quaternions
implies that at some places a complex conjugation is done,
which is not in the standard. Of course, for real types, this
complex conjugation is a no-op.
While the standard allows not to provide the specialisation
complex<complex<T> > (or any specialisation other than
float, double and long double), I doubt that an implementation
may provide specialisations with different sematics for them,
even if that semantics is useful and the standard one is not
in that case, and even if this semantic change doesn't affect
the required specialisations.
But even if I'm wrong here, your implementation doesn't
support quaternions unless you had them in mind when
implementing it. You don't add complex conjugation
unless you expect complex types to be used.
Unfortunately I can't find the article where this was first
proposed, however, the following could be part of the spec
(however, I may have gotten it wrong; it would work for
quaternions, but since I don't know octonions, there may
be some error in it):
template<class T> T conj(T const& t) { return t; }
// for non-complex types, conjugating doesn't change the value
template<class T> complex<T> conj(const complex<T>&)
{
return complex<T>(conj(a.real()), -b.imag());
}
template<class T>
complex<T> operator*(complex<T> a, complex<T> b)
{
return complex<T>(a.real()*b.real() - a.imag()*conj(b.imag()),
a.real()*b.imag() + a.imag()*conj(b.real()));
}
Of course, division would have to be handled, too, as well
as some other functions like norm etc.
With those definitions (modulo errors ;-)), the usual
complex<RealType> would not be affected at all. However,
complex<complex<double> > would give a quaternion and
(hopefully) complex<complex<complex<double> > > would give
an octonion, and so on.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: 2000/05/30 Raw View
Francis Glassborow <francis@robinton.demon.co.uk> writes:
[...]
| Anyway, how about support for tensors, DR Conway's numerical system
| (very important to Games Theorists), determinants etc. And, of course,
| we really ought to add support for polynomials, groups and fields. If
| you really insist I can add quite a few other 'desirable' mathematical
| entities.
Well, since I'm doing Geometry and I use C++ most of the time to
generate complicated surfaces modeled on Riemann Surfaces, and given
their importance to the `computational differential geometry'
community I think Standard C++ ought to include data structures for
Riemann surfaces. Oh, while we are at it, there ought to be a data
structure for differential forms, ODE and PDE solvers.
Of course, that list is not complete, but it is intented to make C++'s
library not too minimalist ;-)
--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Dietmar Kuehl <dietmar.kuehl@claas-solutions.de>
Date: 2000/05/31 Raw View
Hi,
In article <3932A1EC.6B7CEDEB@physik.tu-muenchen.de>,
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> Dietmar Kuehl wrote:
> > I haven't tested it but I think my implementation
> > works with arbitrary types, that is, quaternions might already be
> > supported with my implementatin...
>
> It's IMHO impossible for a standard conforming implementation,
> since the definition of complex<complex<T> > to be quaternions
> implies that at some places a complex conjugation is done,
> which is not in the standard. Of course, for real types, this
> complex conjugation is a no-op.
Since the behavior of all specializations for types 'T' other than
'float', 'double', and 'long double' is unspecified, an implementation
can just do the right thing. Especially, as 'std::complex<T>' is
specialized for the types with specified behavior...
> While the standard allows not to provide the specialisation
> complex<complex<T> > (or any specialisation other than
> float, double and long double), I doubt that an implementation
> may provide specialisations with different sematics for them,
> even if that semantics is useful and the standard one is not
> in that case, and even if this semantic change doesn't affect
> the required specialisations.
Intersting question... Since the exact behavior is not spelled out, I
think that an implementation would be allowed to define the operations
in a suitable way. The standard just says, eg. 'operator*=()'
multiplies the rhs with *this and stores the result. What this
multiplication means, is not explicitly specified and I think it is
legal to use conjugation on the argument provided, of course, this
operation is defined such that it is a no operation if there is no such
operations.
> But even if I'm wrong here, your implementation doesn't
> support quaternions unless you had them in mind when
> implementing it. You don't add complex conjugation
> unless you expect complex types to be used.
True. I just said it "might" support this use. Maybe I should look into
this stuff and change my implementation to support quaternions, of
course, giving a warning in higher warning levels for use of
non-standard extensions...
Thank you very much for you comments!
--
<mailto:dietmar.kuehl@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hubert Holin <hubert.holin@meteo.fr>
Date: 2000/05/26 Raw View
Somewhere in the E.U., le 25/05/2000
Jean-Daniel Nicolet wrote:
>=20
> Hubert HOLIN wrote in message <392AEC38.DA02E897@club-internet.fr>...
> >Paris (U.E.), le 23/05/2000
> >
> > Quaternions are a useful, if somewhat lesser known, kin to the comple=
x
> >numbers. It is my contention that at least minimal support should be
> >added to the C++ standard. As a first step towards that goal, I presen=
t
> >here a possible implementation, along the line of the complex numbers,
> >to help define the "existing art", when the standard comes up for
> >revision some time in the (distant) future.
>=20
> Thank you for posting your personal implementation, so it will remain i=
n the
> FAQ for the future, where anybody needing it can grab it. Though a "nat=
ural"
Well, embarrassingly enough, I found an error in the division operators
(and a few cosmetic glitches), so "just grabbing it", might lead to
disappointing results... One of the purposes of having a standard object
is to (theoretically, of course), insure that it is sound.
> extension of complex numbers, I don't feel there is an urgent need for =
them
I do not believe the need is urgent. The next revision is not exactly
tomorrow either...
> in the C++ community. Already complex numbers are porbably kind of a lu=
xury,
> used by a small percentage (less than 1% ?) of usual programmers (flame=
s, I
> feel flames in my back!).
Complex numbers are perhaps a luxury for spreadsheet writers, but
definitely not for scientific users, the very same (though perhaps not
the totality of) which would benefit from the presence of quaternions.
As I mentioned, other non-technical fields would benefit from standard
access to quaternions.
It may shock you, but I received a comment to the effect that even
octonions would be welcome. If nobody objects too seriously, I will
also post my implementation of them, when it is ready. I, however,
promise, NOT to post the implementation of hexadecimalions (now Clifford
Algebras... :-) ).
> Quaternions are probably used two orders of magnitude less than complex
> numbers, so it is not worth the standardization trouble. Moreover, now =
we
As you said, these objects are seldom used, so collisions with existing
code should be minimal at best. In such a case I do not foresee (though
I may be wrong) any standardization trouble.
> have the implementation you provided, so everything is fine! Blague =E0=
part,
> you must admit that everybody attempting a serious implementation of th=
em
> won't fall far beyond what you submitted, so the risk for incompatibili=
ties
> should be very low.
You may have failed to notice the implementation of the exponential &
all. To the best of my knowledge, this is something that I invented
(i.e., I believe I am the inventor of the closed formula), so it is most
unlikely to be found in another implementation!
> I would personnally also have chosen a namespace math with a quaternion
> class, so we even agree on names.
Actually, when the standard comes up for revision, it might be argued
that a namespace "math" should be added, and "complex" moved to it.
Calling a class by the name of what it describes is a no-brainer.
> Speaking of cryptography, elliptic curves and polynoms over finite fiel=
ds
> are probably much more useful (and difficult to implement efficiently),=
but
> I'm convinced that such mathematical specialities should remain in the
> domain of extension libraries and not clutter an already thick standard
> library.
>=20
> Remember that for each programmer finding it useful, thousand of others=
have
> to invest time learning it to finally deduce they don't need it after a=
ll.
> We've already enough similar suffering with stuff like valarrays (flame=
s
> again).
Understanding what is in a standard is by no means easy. There should
be books and the like to help one get used to what it describes, and
help one choose what one needs. That is no reason to omit important thing=
s.
As for valarrays, I do make daily use of them. I am pestering my
favorite compiler vendor to make them hardware accelerated (that is
mostly, if not entirely, what they are for).
> Jean-Daniel Nicolet
> Software Consultant
> Geneva
> Switzerland
Hubert Holin
Hubert.Holin@Bigfoot.com
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Dietmar Kuehl <dietmar.kuehl@claas-solutions.de>
Date: 2000/05/26 Raw View
Hi,
In article <392D342E.663F0243@meteo.fr>,
Hubert.Holin@Bigfoot.com, Hubert.Holin@meteo.fr wrote:
> Complex numbers are perhaps a luxury for spreadsheet writers, but
> definitely not for scientific users, the very same (though perhaps not
> the totality of) which would benefit from the presence of quaternions.
> As I mentioned, other non-technical fields would benefit from standard
> access to quaternions.
A definite *must* for the next round of standardization is speach
recognition because this is basically need in all fields! More to the
point, C++ is designed to be extensible by third party libraries and
the intention was to provide a basic library which is used in most if
not all implementations.
The whole set of library components consists basically of four
categories:
- Language support stuff, like eg. the RTTI classes, the exceptions
thrown by language constructs (eg. 'std::bad_cast'), etc. It is
pretty obvious that this should be part of the library shipping with
a compiler and should not be obtained from a third party. In fact,
all compilers I have seen ship with at least this part of the library
even if the rest is missing.
- Components which could benefit from special handling within the
compiler. For example, there might be floating point hardware which
can deal with complex numbers rather than just scalars. Although this
might be put into a library, having the compiler handle objects of
type 'std::complex<T>' (with 'T' being something reasonable) can be
more efficient. Basically the same intentation was behind the class
template 'std::valarray' where suddenly some guarantees similar to
those guaranteed by C's 'restrict' keyword or Fortran's no-aliasing
pop up which would let the compiler do better optimizations.
- Components everybody uses in programs, like lists, vectory, sorting,
copying, formatted I/O. This stuff should not be too minimalistic to
avoid falling outside the library just because something slightly off
the mainstream is needed but on the other hand it should not include
just about everything.
- Everything else: From nice to haves to special purpose libraries this
is about everything which can be put into a library.
Basically the first three categories are what has to be, should be, and
could be handled, respectively, by a standard library. The forth
category is what third parties are supposed to provide.
One important issue about this stuff is not really addressed by the
view mentioned above, and this is the interface to the components: It
is fairly important that libraries from third parties mix well and thus
they should rely on common interfaces. This is especially important
when creating new abstractions. The current standard only coves
interfaces for things like sequences explicitly. Numeric interfaces are
not explicitly spelled out but apparent through the interfaces of the
built-in types and the class templates 'std::complex' and
'std::valarray'. For new numeric components, eg. quaternions, the
interface seems to be fairly clear. For other abstractions, eg. for
image processing, voice recognition, graphs, banking, whatever, the
interfaces are not that obvious.
OK, that said, I would like to ask what category to you think a
component for quaternions fits in? I'm pretty sure it does not fit into
the first one (as currently the core language is defined without
reference to quaternions) and my guess is that it actually does not fit
the third category either but this is just a guess. It might fit well
into the second category. However, my personal feeling is that this is
something for the forth category...
The approach to push quaternions and possibly also octernions and
whatever is coming beyond this, too, is to submit the library to
Boost and have it discussed there. Several members of the library
working group a listening there and things getting into common use are
possible candidates for the next round of standardization. Even if the
stuff does not become part of the standard C++ library, this forum
gives a fair chance to standardize the interface and have third parties
use the same interface to their libraries. Potentially, this might
spawn off even library standards although I would consider this to be
rather unlikely... Anyway, have a look at <http://www.boost.org/>. I
think this is the right forum to address this stuff and if people
really want it, this a good contact to the library working group
(however, it is nothing official, it is just pure coincidence that
several members of the library working group are also interested in
Boost does...).
--
<mailto:dietmar.kuehl@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 2000/05/26 Raw View
In article <8gjl0j$g0f$1@nnrp1.deja.com>, Dietmar Kuehl
<dietmar.kuehl@claas-solutions.de> writes
>Basically the first three categories are what has to be, should be, and
>could be handled, respectively, by a standard library. The forth
>category is what third parties are supposed to provide.
It would be nice to have some standard APIs, programming toolkits for
application domains etc. However it is not the task of those writing a
language standard. Quite apart from anything else they lack the
expertise (and if you doubt that, look at the inadequacies of valarray,
and that is not to criticise anyone involved, the necessary technical
support was withdrawn by their employers leaving those without specific
expertise in the problem domain to do the best they could)
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 2000/05/27 Raw View
Hubert HOLIN wrote:
>
> Paris (U.E.), le 23/05/2000
>
> Quaternions are a useful, if somewhat lesser known, kin to the complex
> numbers. It is my contention that at least minimal support should be
> added to the C++ standard. As a first step towards that goal, I present
> here a possible implementation, along the line of the complex numbers,
> to help define the "existing art", when the standard comes up for
> revision some time in the (distant) future.
[...]
There once was (either in this newsgroup, or in comp.lang.c++.moderated)
a proposal to do a slight change to the definition of complex<T>.
This proposal would have allowed to get quaternions with
complex<complex<T> > and octonions with complex<complex<complex<T> > >
(and so on).
If quaternions should be included into the C++ standard, I'd say
that's the better way to do it.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hubert Holin <hubert.holin@meteo.fr>
Date: 2000/05/27 Raw View
Paris (U.E.), le 26/05/2000
Dietmar Kuehl wrote:
>
> Hi,
> In article <392D342E.663F0243@meteo.fr>,
> Hubert.Holin@Bigfoot.com, Hubert.Holin@meteo.fr wrote:
> > Complex numbers are perhaps a luxury for spreadsheet writers, but
> > definitely not for scientific users, the very same (though perhaps not
> > the totality of) which would benefit from the presence of quaternions.
> > As I mentioned, other non-technical fields would benefit from standard
> > access to quaternions.
[SNIP]
> The whole set of library components consists basically of four
> categories:
>
> - Language support stuff,
[SNIP]
> - Components which could benefit from special handling within the
> compiler.
[SNIP]
> - Components everybody uses in programs, like lists, vectory, sorting,
> copying, formatted I/O.
[SNIP]
> - Everything else: From nice to haves to special purpose libraries this
> is about everything which can be put into a library.
>
> Basically the first three categories are what has to be, should be, and
> could be handled, respectively, by a standard library. The forth
> category is what third parties are supposed to provide.
>
> One important issue about this stuff is not really addressed by the
> view mentioned above, and this is the interface to the components: It
> is fairly important that libraries from third parties mix well and thus
> they should rely on common interfaces. This is especially important
> when creating new abstractions. The current standard only coves
> interfaces for things like sequences explicitly. Numeric interfaces are
> not explicitly spelled out but apparent through the interfaces of the
> built-in types and the class templates 'std::complex' and
> 'std::valarray'. For new numeric components, eg. quaternions, the
> interface seems to be fairly clear. For other abstractions, eg. for
> image processing, voice recognition, graphs, banking, whatever, the
> interfaces are not that obvious.
>
> OK, that said, I would like to ask what category to you think a
> component for quaternions fits in? I'm pretty sure it does not fit into
> the first one (as currently the core language is defined without
> reference to quaternions) and my guess is that it actually does not fit
> the third category either but this is just a guess. It might fit well
> into the second category. However, my personal feeling is that this is
> something for the forth category...
IMHO it fits in the second category. These are objects on par with
trigonometric functions (and other special functions), and they are one
of the building blocks from which one actually computes. Complex numbers
are (nearly) just as fundamental to use as are real numbers. Integers
represent another set of modeling properties. C++ as a *computing*
language would benefit from a set of models which is not too minimalist.
As well, methods should be provided to act on the basic objects.
Sorting algorithms are a must, but I believe so are BLAS.
What I mean is that "Components everybody uses in programs" is
extremely subjective. In particular, scientific computing seems to be
underrepresented in the tasks C++ is put to.
> The approach to push quaternions and possibly also octernions and
> whatever is coming beyond this, too, is to submit the library to
> Boost and have it discussed there. Several members of the library
> working group a listening there and things getting into common use are
> possible candidates for the next round of standardization. Even if the
> stuff does not become part of the standard C++ library, this forum
> gives a fair chance to standardize the interface and have third parties
> use the same interface to their libraries. Potentially, this might
> spawn off even library standards although I would consider this to be
> rather unlikely... Anyway, have a look at <http://www.boost.org/>. I
> think this is the right forum to address this stuff and if people
> really want it, this a good contact to the library working group
> (however, it is nothing official, it is just pure coincidence that
> several members of the library working group are also interested in
> Boost does...).
> --
> <mailto:dietmar.kuehl@claas-solutions.de>
> homepage: <http://www.informatik.uni-konstanz.de/~kuehl>
>
> Sent via Deja.com http://www.deja.com/
> Before you buy.
Thus will it be done.
Hubert Holin
Hubert.holin@Bigfoot.com
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hubert HOLIN <h_holin@club-internet.fr>
Date: 2000/05/24 Raw View
Paris (U.E.), le 23/05/2000
Quaternions are a useful, if somewhat lesser known, kin to the complex
numbers. It is my contention that at least minimal support should be
added to the C++ standard. As a first step towards that goal, I present
here a possible implementation, along the line of the complex numbers,
to help define the "existing art", when the standard comes up for
revision some time in the (distant) future.
The quaternions described here are mostly useful for works of
animation type (though horizontal-preserving interpolation of
orientations is a more important, solved, problem, which also uses
quaternions, but some more tools, contact me if you want to discuss this).
Quaternions, and some other related objects, though in another
incarnation, can play a very interesting role in cryptography. Perhaps
an implementation of these might also be incorporated in a future
version of the standard.
As a related notes, I am also developing an implementation of
octonions, another of kin of complex numbers and quaternions. It is not
quite as clear that they should be incorporated in a future version of
the standard, if only because their use is even more specialized. If
somebody bribes me, I might even write an implementation of "the next
rung" of the real-complex-quaternion-octonion... hierarchy (which I
dubbed the hexadecimalions). Actually, I might just write it, just for
the heck of it ;-) .
Finally, I will put these items on my website, when I can find the time
to get it back up.
Hubert Holin
Hubert.Holin@Bigfoot.com
--- 8>< ----------------------- quaternion ----------------------- ><8 ---
/********************************************************************************************/
/* */
/* quaternion */
/* */
/* v 1.1.0 - 23/05/2000 */
/* */
/* Copyright Hubert Holin (Hubert.Holin@Bigfoot.com) */
/* */
/* This is freeware. No strings attached, no waranty either! */
/* */
/* Please leave the blurb about the exponential & Co. intact... */
/* */
/* This is an example implementation of quaternions for C++. IMHO
quaternions should be */
/* part of the language. So this is my contribution to the "existing
practice" to be */
/* considered at the next revision of the language. */
/* */
/* This implementation of quaternions (as structures) is *NOT*
thread-safe (as for complex */
/* numbers, I believe mutexes should not be introduced at this low
level, YMMV...). */
/* */
/* Support should be added for C9X extensions. */
/* */
/* This implementation is not optimized for speed; clarity was the goal
(hopefully, this */
/* implementation will be usefull too). */
/* */
/* Version history: */
/* */
/* 1.1.0 - 23/05/2000: changed "sinc" into "sinc_pi"; added sin cos,
sinh, cosh. */
/* 1.0.0 - 10/08/1999: first public version */
/* */
/********************************************************************************************/
#ifndef _QUATERNION
#define _QUATERNION
// NOTE: I believe this should be part of the standard library, hence
the define
// starting with an underscore (normally restricted to the implementor);
// however, I can not put quaternions in the std namespace.
#include <complex>
#include <iosfwd> // for the "<<" and ">>" operators
#include <locale> // for the "<<" operator
#include "special_functions.h" // for the Sinus cardinal
namespace math
{
template<typename T>
class quaternion
{
public:
typedef T value_type;
// constructor for H seen as R^4
// (also default constructor)
quaternion( const T & requested_a = T(),
const T & requested_b = T(),
const T & requested_c = T(),
const T & requested_d = T())
: a(requested_a),
b(requested_b),
c(requested_c),
d(requested_d)
{
// nothing to do!
};
// constructor for H seen as C^2
quaternion( const ::std::complex<T> z0,
const ::std::complex<T> z1 = ::std::complex<T>())
: a(z0.real()),
b(z0.imag()),
c(z1.real()),
d(z1.imag())
{
// nothing to do!
};
// UNtemplated copy constructor
quaternion(const quaternion & a_recopier)
: a(a_recopier.a),
b(a_recopier.b),
c(a_recopier.c),
d(a_recopier.d)
{
// nothing to do!
};
// templated copy constructor
template<typename X>
quaternion(const quaternion<X> & a_recopier)
: a(T(a_recopier.component_a())),
b(T(a_recopier.component_b())),
c(T(a_recopier.component_c())),
d(T(a_recopier.component_d()))
{
// nothing to do!
};
// destructor
~quaternion()
{
// nothing to do!
};
// accessors
//
// Note: Like complex number, quaternions do have a meaningful notion
of "real part",
// but unlike them there is no meaningful notion of "imaginary part".
// Instead there is an "unreal part" which itself is a quaternion,
and usually
// nothing simpler (as opposed to the complex number case).
// However, for practicallity, there are accessors for the other components
// (these are necessary for the templated copy constructor, for instance).
T real() const
{
return(a);
};
quaternion unreal() const
{
return(quaternion(T(0),b,c,d));
};
T component_a() const // same as "real"
{
return(a);
};
T component_b() const
{
return(b);
};
T component_c() const
{
return(c);
};
T component_d() const
{
return(d);
};
// UNtemplated assignment operator
quaternion & operator = (const quaternion & a_affecter)
{
if (this != &a_affecter)
{
a = a_affecter.a;
b = a_affecter.b;
c = a_affecter.c;
d = a_affecter.d;
}
return(*this);
};
// templated assignment operator
template<typename X>
quaternion<T> & operator = (const quaternion<X> & a_affecter)
{
a = T(a_affecter.component_a());
b = T(a_affecter.component_b());
c = T(a_affecter.component_c());
d = T(a_affecter.component_d());
return(*this);
};
// converting assignment operators
//
// NOTE: Quaternion multiplication is *NOT* commutative;
// symbolically, "q *= rhs;" means "q = q * rhs;"
// and "q /= rhs;" means "q = q * inverse_of(rhs);"
quaternion<T> & operator = (const T & a_affecter)
{
a = a_affecter;
b = c= d = T(0);
return(*this);
};
quaternion<T> & operator = (const ::std::complex<T> & a_affecter)
{
a = a_affecter.real();
b = a_affecter.imag();
c = d = T(0);
return(*this);
};
// other assignment-related operators
quaternion<T> & operator += (const T & rhs)
{
a += rhs;
return(*this);
};
quaternion<T> & operator += (const ::std::complex<T> & rhs)
{
a += rhs.real();
b += rhs.imag();
return(*this);
};
template<typename X>
quaternion<T> & operator += (const quaternion<X> & rhs)
{
a += T(rhs.component_a());
b += T(rhs.component_b());
c += T(rhs.component_c());
d += T(rhs.component_d());
return(*this);
};
quaternion<T> & operator -= (const T & rhs)
{
a -= rhs;
return(*this);
};
quaternion<T> & operator -= (const ::std::complex<T> & rhs)
{
a -= rhs.real();
b -= rhs.imag();
return(*this);
};
template<typename X>
quaternion<T> & operator -= (const quaternion<X> & rhs)
{
a -= T(rhs.component_a());
b -= T(rhs.component_b());
c -= T(rhs.component_c());
d -= T(rhs.component_d());
return(*this);
};
quaternion<T> & operator *= (const T & rhs)
{
a *= rhs;
b *= rhs;
c *= rhs;
d *= rhs;
return(*this);
};
quaternion<T> & operator *= (const ::std::complex<T> & rhs)
{
T ar = rhs.real();
T br = rhs.imag();
T at = a*ar-b*br;
T bt = a*br+ar*b;
T ct = ar*c+d*br;
T dt = ar*d-br*c;
a = at;
b = bt;
c = ct;
d = dt;
return(*this);
};
template<typename X>
quaternion<T> & operator *= (const quaternion<X> & rhs)
{
T ar = T(rhs.component_a());
T br = T(rhs.component_b());
T cr = T(rhs.component_c());
T dr = T(rhs.component_d());
T at = a*ar-b*br-c*cr-d*dr;
T bt = (a*br+ar*b)+(c*dr-cr*d);
T ct = (a*cr+ar*c)+(d*br-dr*b);
T dt = (a*dr+ar*d)+(b*cr-br*c);
a = at;
b = bt;
c = ct;
d = dt;
return(*this);
};
quaternion<T> & operator /= (const T & rhs)
{
a /= rhs;
b /= rhs;
c /= rhs;
d /= rhs;
return(*this);
};
quaternion<T> & operator /= (const ::std::complex<T> & rhs)
{
T ar = rhs.real();
T br = rhs.imag();
T denominator = ar*ar+br*br;
a = (a*ar+b*br)/denominator;
b = (ar*b-a*br)/denominator;
c = (ar*c-d*br)/denominator;
d = (ar*d+br*c)/denominator;
return(*this);
};
template<typename X>
quaternion<T> & operator /= (const quaternion<X> & rhs)
{
T ar = T(rhs.component_a());
T br = T(rhs.component_b());
T cr = T(rhs.component_c());
T dr = T(rhs.component_d());
T denominator = ar*ar+br*br+cr*cr+dr*dr;
a = (a*ar+b*br+c*cr+d*dr)/denominator;
b = ((ar*b-a*br)+(cr*d-c*dr))/denominator;
c = ((ar*c-a*cr)+(dr*b-d*br))/denominator;
d = ((ar*d-a*dr)+(br*c-b*cr))/denominator;
return(*this);
};
protected:
T a;
T b;
T c;
T d;
private:
};
// quaternion specialization
template<>
class quaternion<float>
{
public:
typedef float value_type;
// constructor for H seen as R^4
// (also default constructor)
quaternion( const float & requested_a = 0.0f,
const float & requested_b = 0.0f,
const float & requested_c = 0.0f,
const float & requested_d = 0.0f)
: a(requested_a),
b(requested_b),
c(requested_c),
d(requested_d)
{
// nothing to do!
};
// constructor for H seen as C^2
quaternion( const ::std::complex<float> z0,
const ::std::complex<float> z1 = ::std::complex<float>())
: a(z0.real()),
b(z0.imag()),
c(z1.real()),
d(z1.imag())
{
// nothing to do!
};
// UNtemplated copy constructor
quaternion(const quaternion & a_recopier)
: a(a_recopier.a),
b(a_recopier.b),
c(a_recopier.c),
d(a_recopier.d)
{
// nothing to do!
};
// explicit copy constructors (converters)
explicit quaternion(const quaternion<double> & a_recopier)
: a(a_recopier.component_a()),
b(a_recopier.component_b()),
c(a_recopier.component_c()),
d(a_recopier.component_d())
{
// nothing to do!
};
explicit quaternion(const quaternion<long double> & a_recopier)
: a(a_recopier.component_a()),
b(a_recopier.component_b()),
c(a_recopier.component_c()),
d(a_recopier.component_d())
{
// nothing to do!
};
// destructor
~quaternion()
{
// nothing to do!
};
// accessors
//
// Note: Like complex number, quaternions do have a meaningful notion
of "real part",
// but unlike them there is no meaningful notion of "imaginary part".
// Instead there is an "unreal part" which itself is a quaternion,
and usually
// nothing simpler (as opposed to the complex number case).
// However, for practicallity, there are accessors for the other components
// (these are necessary for the templated copy constructor, for instance).
float real() const
{
return(a);
};
quaternion unreal() const
{
return(quaternion(0.0f,b,c,d));
};
float component_a() const // same as "real"
{
return(a);
};
float component_b() const
{
return(b);
};
float component_c() const
{
return(c);
};
float component_d() const
{
return(d);
};
// UNtemplated assignment operator
quaternion & operator = (const quaternion & a_affecter)
{
if (this != &a_affecter)
{
a = a_affecter.a;
b = a_affecter.b;
c = a_affecter.c;
d = a_affecter.d;
}
return(*this);
};
// templated assignment operator
template<typename X>
quaternion<float> & operator = (const quaternion<X> & a_affecter)
{
a = float(a_affecter.component_a());
b = float(a_affecter.component_b());
c = float(a_affecter.component_c());
d = float(a_affecter.component_d());
return(*this);
};
// converting assignment operators
//
// NOTE: Quaternion multiplication is *NOT* commutative;
// symbolically, "q *= rhs;" means "q = q * rhs;"
// and "q /= rhs;" means "q = q * inverse_of(rhs);"
quaternion<float> & operator = (const float & a_affecter)
{
a = a_affecter;
b = c= d = 0.0f;
return(*this);
};
quaternion<float> & operator = (const ::std::complex<float> & a_affecter)
{
a = a_affecter.real();
b = a_affecter.imag();
c = d = 0.0f;
return(*this);
};
// other assignment-related operators
quaternion<float> & operator += (const float & rhs)
{
a += rhs;
return(*this);
};
quaternion<float> & operator += (const ::std::complex<float> & rhs)
{
a += rhs.real();
b += rhs.imag();
return(*this);
};
template<typename X>
quaternion<float> & operator += (const quaternion<X> & rhs)
{
a += float(rhs.component_a());
b += float(rhs.component_b());
c += float(rhs.component_c());
d += float(rhs.component_d());
return(*this);
};
quaternion<float> & operator -= (const float & rhs)
{
a -= rhs;
return(*this);
};
quaternion<float> & operator -= (const ::std::complex<float> & rhs)
{
a -= rhs.real();
b -= rhs.imag();
return(*this);
};
template<typename X>
quaternion<float> & operator -= (const quaternion<X> & rhs)
{
a -= float(rhs.component_a());
b -= float(rhs.component_b());
c -= float(rhs.component_c());
d -= float(rhs.component_d());
return(*this);
};
quaternion<float> & operator *= (const float & rhs)
{
a *= rhs;
b *= rhs;
c *= rhs;
d *= rhs;
return(*this);
};
quaternion<float> & operator *= (const ::std::complex<float> & rhs)
{
float ar = rhs.real();
float br = rhs.imag();
float at = a*ar-b*br;
float bt = a*br+ar*b;
float ct = ar*c+d*br;
float dt = ar*d-br*c;
a = at;
b = bt;
c = ct;
d = dt;
return(*this);
};
template<typename X>
quaternion<float> & operator *= (const quaternion<X> & rhs)
{
float ar = float(rhs.component_a());
float br = float(rhs.component_b());
float cr = float(rhs.component_c());
float dr = float(rhs.component_d());
float at = a*ar-b*br-c*cr-d*dr;
float bt = (a*br+ar*b)+(c*dr-cr*d);
float ct = (a*cr+ar*c)+(d*br-dr*b);
float dt = (a*dr+ar*d)+(b*cr-br*c);
a = at;
b = bt;
c = ct;
d = dt;
return(*this);
};
quaternion<float> & operator /= (const float & rhs)
{
a /= rhs;
b /= rhs;
c /= rhs;
d /= rhs;
return(*this);
};
quaternion<float> & operator /= (const ::std::complex<float> & rhs)
{
float ar = rhs.real();
float br = rhs.imag();
float denominator = ar*ar+br*br;
a = (a*ar+b*br)/denominator;
b = (ar*b-a*br)/denominator;
c = (ar*c-d*br)/denominator;
d = (ar*d+br*c)/denominator;
return(*this);
};
template<typename X>
quaternion<float> & operator /= (const quaternion<X> & rhs)
{
float ar = float(rhs.component_a());
float br = float(rhs.component_b());
float cr = float(rhs.component_c());
float dr = float(rhs.component_d());
float denominator = ar*ar+br*br+cr*cr+dr*dr;
a = (a*ar+b*br+c*cr+d*dr)/denominator;
b = ((ar*b-a*br)+(cr*d-c*dr))/denominator;
c = ((ar*c-a*cr)+(dr*b-d*br))/denominator;
d = ((ar*d-a*dr)+(br*c-b*cr))/denominator;
return(*this);
};
protected:
float a;
float b;
float c;
float d;
private:
};
template<>
class quaternion<double>
{
public:
typedef double value_type;
// constructor for H seen as R^4
// (also default constructor)
quaternion( const double & requested_a = 0.0,
const double & requested_b = 0.0,
const double & requested_c = 0.0,
const double & requested_d = 0.0)
: a(requested_a),
b(requested_b),
c(requested_c),
d(requested_d)
{
// nothing to do!
};
// constructor for H seen as C^2
quaternion( const ::std::complex<double> z0,
const ::std::complex<double> z1 = ::std::complex<double>())
: a(z0.real()),
b(z0.imag()),
c(z1.real()),
d(z1.imag())
{
// nothing to do!
};
// UNtemplated copy constructor
quaternion(const quaternion & a_recopier)
: a(a_recopier.a),
b(a_recopier.b),
c(a_recopier.c),
d(a_recopier.d)
{
// nothing to do!
};
// converting copy constructor
quaternion(const quaternion<float> & a_recopier)
: a(double(a_recopier.component_a())),
b(double(a_recopier.component_b())),
c(double(a_recopier.component_c())),
d(double(a_recopier.component_d()))
{
// nothing to do!
};
// explicit copy constructors (converters)
explicit quaternion(const quaternion<long double> & a_recopier)
: a(double(a_recopier.component_a())),
b(double(a_recopier.component_b())),
c(double(a_recopier.component_c())),
d(double(a_recopier.component_d()))
{
// nothing to do!
};
// destructor
~quaternion()
{
// nothing to do!
};
// accessors
//
// Note: Like complex number, quaternions do have a meaningful notion
of "real part",
// but unlike them there is no meaningful notion of "imaginary part".
// Instead there is an "unreal part" which itself is a quaternion,
and usually
// nothing simpler (as opposed to the complex number case).
// However, for practicallity, there are accessors for the other components
// (these are necessary for the templated copy constructor, for instance).
double real() const
{
return(a);
};
quaternion unreal() const
{
return(quaternion(0.0,b,c,d));
};
double component_a() const // same as "real"
{
return(a);
};
double component_b() const
{
return(b);
};
double component_c() const
{
return(c);
};
double component_d() const
{
return(d);
};
// UNtemplated assignment operator
quaternion & operator = (const quaternion & a_affecter)
{
if (this != &a_affecter)
{
a = a_affecter.a;
b = a_affecter.b;
c = a_affecter.c;
d = a_affecter.d;
}
return(*this);
};
// templated assignment operator
template<typename X>
quaternion<double> & operator = (const quaternion<X> & a_affecter)
{
a = double(a_affecter.component_a());
b = double(a_affecter.component_b());
c = double(a_affecter.component_c());
d = double(a_affecter.component_d());
return(*this);
};
// converting assignment operators
//
// NOTE: Quaternion multiplication is *NOT* commutative;
// symbolically, "q *= rhs;" means "q = q * rhs;"
// and "q /= rhs;" means "q = q * inverse_of(rhs);"
quaternion<double> & operator = (const double & a_affecter)
{
a = a_affecter;
b = c= d = double(0);
return(*this);
};
quaternion<double> & operator = (const ::std::complex<double> & a_affecter)
{
a = a_affecter.real();
b = a_affecter.imag();
c = d = double(0);
return(*this);
};
// other assignment-related operators
quaternion<double> & operator += (const double & rhs)
{
a += rhs;
return(*this);
};
quaternion<double> & operator += (const ::std::complex<double> & rhs)
{
a += rhs.real();
b += rhs.imag();
return(*this);
};
template<typename X>
quaternion<double> & operator += (const quaternion<X> & rhs)
{
a += double(rhs.component_a());
b += double(rhs.component_b());
c += double(rhs.component_c());
d += double(rhs.component_d());
return(*this);
};
quaternion<double> & operator -= (const double & rhs)
{
a -= rhs;
return(*this);
};
quaternion<double> & operator -= (const ::std::complex<double> & rhs)
{
a -= rhs.real();
b -= rhs.imag();
return(*this);
};
template<typename X>
quaternion<double> & operator -= (const quaternion<X> & rhs)
{
a -= double(rhs.component_a());
b -= double(rhs.component_b());
c -= double(rhs.component_c());
d -= double(rhs.component_d());
return(*this);
};
quaternion<double> & operator *= (const double & rhs)
{
a *= rhs;
b *= rhs;
c *= rhs;
d *= rhs;
return(*this);
};
quaternion<double> & operator *= (const ::std::complex<double> & rhs)
{
double ar = rhs.real();
double br = rhs.imag();
double at = a*ar-b*br;
double bt = a*br+ar*b;
double ct = ar*c+d*br;
double dt = ar*d-br*c;
a = at;
b = bt;
c = ct;
d = dt;
return(*this);
};
template<typename X>
quaternion<double> & operator *= (const quaternion<X> & rhs)
{
double ar = double(rhs.component_a());
double br = double(rhs.component_b());
double cr = double(rhs.component_c());
double dr = double(rhs.component_d());
double at = a*ar-b*br-c*cr-d*dr;
double bt = (a*br+ar*b)+(c*dr-cr*d);
double ct = (a*cr+ar*c)+(d*br-dr*b);
double dt = (a*dr+ar*d)+(b*cr-br*c);
a = at;
b = bt;
c = ct;
d = dt;
return(*this);
};
quaternion<double> & operator /= (const double & rhs)
{
a /= rhs;
b /= rhs;
c /= rhs;
d /= rhs;
return(*this);
};
quaternion<double> & operator /= (const ::std::complex<double> & rhs)
{
double ar = rhs.real();
double br = rhs.imag();
double denominator = ar*ar+br*br;
a = (a*ar+b*br)/denominator;
b = (ar*b-a*br)/denominator;
c = (ar*c-d*br)/denominator;
d = (ar*d+br*c)/denominator;
return(*this);
};
template<typename X>
quaternion<double> & operator /= (const quaternion<X> & rhs)
{
double ar = double(rhs.component_a());
double br = double(rhs.component_b());
double cr = double(rhs.component_c());
double dr = double(rhs.component_d());
double denominator = ar*ar+br*br+cr*cr+dr*dr;
a = (a*ar+b*br+c*cr+d*dr)/denominator;
b = ((ar*b-a*br)+(cr*d-c*dr))/denominator;
c = ((ar*c-a*cr)+(dr*b-d*br))/denominator;
d = ((ar*d-a*dr)+(br*c-b*cr))/denominator;
return(*this);
};
protected:
double a;
double b;
double c;
double d;
private:
};
template<>
class quaternion<long double>
{
public:
typedef long double value_type;
// constructor for H seen as R^4
// (also default constructor)
quaternion( const long double & requested_a = 0.0L,
const long double & requested_b = 0.0L,
const long double & requested_c = 0.0L,
const long double & requested_d = 0.0L)
: a(requested_a),
b(requested_b),
c(requested_c),
d(requested_d)
{
// nothing to do!
};
// constructor for H seen as C^2
quaternion( const ::std::complex<long double> z0,
const ::std::complex<long double> z1 = ::std::complex<long double>())
: a(z0.real()),
b(z0.imag()),
c(z1.real()),
d(z1.imag())
{
// nothing to do!
};
// UNtemplated copy constructor
quaternion(const quaternion & a_recopier)
: a(a_recopier.a),
b(a_recopier.b),
c(a_recopier.c),
d(a_recopier.d)
{
// nothing to do!
};
// converting copy constructor
quaternion(const quaternion<float> & a_recopier)
: a((long double)a_recopier.component_a()),
b((long double)a_recopier.component_b()),
c((long double)a_recopier.component_c()),
d((long double)a_recopier.component_d())
{
// nothing to do!
};
quaternion(const quaternion<double> & a_recopier)
: a((long double)a_recopier.component_a()),
b((long double)a_recopier.component_b()),
c((long double)a_recopier.component_c()),
d((long double)a_recopier.component_d())
{
// nothing to do!
};
// destructor
~quaternion()
{
// nothing to do!
};
// accessors
//
// Note: Like complex number, quaternions do have a meaningful notion
of "real part",
// but unlike them there is no meaningful notion of "imaginary part".
// Instead there is an "unreal part" which itself is a quaternion,
and usually
// nothing simpler (as opposed to the complex number case).
// However, for practicallity, there are accessors for the other components
// (these are necessary for the templated copy constructor, for instance).
long double real() const
{
return(a);
};
quaternion unreal() const
{
return(quaternion(0.0L,b,c,d));
};
long double component_a() const // same as "real"
{
return(a);
};
long double component_b() const
{
return(b);
};
long double component_c() const
{
return(c);
};
long double component_d() const
{
return(d);
};
// UNtemplated assignment operator
quaternion & operator = (const quaternion & a_affecter)
{
if (this != &a_affecter)
{
a = a_affecter.a;
b = a_affecter.b;
c = a_affecter.c;
d = a_affecter.d;
}
return(*this);
};
// templated assignment operator
template<typename X>
quaternion<long double> & operator = (const quaternion<X> & a_affecter)
{
a = (long double)a_affecter.component_a();
b = (long double)a_affecter.component_b();
c = (long double)a_affecter.component_c();
d = (long double)a_affecter.component_d();
return(*this);
};
// converting assignment operators
//
// NOTE: Quaternion multiplication is *NOT* commutative;
// symbolically, "q *= rhs;" means "q = q * rhs;"
// and "q /= rhs;" means "q = q * inverse_of(rhs);"
quaternion<long double> & operator = (const long double & a_affecter)
{
a = a_affecter;
b = c= d = 0.0L;
return(*this);
};
quaternion<long double> & operator = (const ::std::complex<long
double> & a_affecter)
{
a = a_affecter.real();
b = a_affecter.imag();
c = d = 0.0L;
return(*this);
};
// other assignment-related operators
quaternion<long double> & operator += (const long double & rhs)
{
a += rhs;
return(*this);
};
quaternion<long double> & operator += (const ::std::complex<long
double> & rhs)
{
a += rhs.real();
b += rhs.imag();
return(*this);
};
template<typename X>
quaternion<long double> & operator += (const quaternion<X> & rhs)
{
a += (long double)rhs.component_a();
b += (long double)rhs.component_b();
c += (long double)rhs.component_c();
d += (long double)rhs.component_d();
return(*this);
};
quaternion<long double> & operator -= (const long double & rhs)
{
a -= rhs;
return(*this);
};
quaternion<long double> & operator -= (const ::std::complex<long
double> & rhs)
{
a -= rhs.real();
b -= rhs.imag();
return(*this);
};
template<typename X>
quaternion<long double> & operator -= (const quaternion<X> & rhs)
{
a -= (long double)rhs.component_a();
b -= (long double)rhs.component_b();
c -= (long double)rhs.component_c();
d -= (long double)rhs.component_d();
return(*this);
};
quaternion<long double> & operator *= (const long double & rhs)
{
a *= rhs;
b *= rhs;
c *= rhs;
d *= rhs;
return(*this);
};
quaternion<long double> & operator *= (const ::std::complex<long
double> & rhs)
{
long double ar = rhs.real();
long double br = rhs.imag();
long double at = a*ar-b*br;
long double bt = a*br+ar*b;
long double ct = ar*c+d*br;
long double dt = ar*d-br*c;
a = at;
b = bt;
c = ct;
d = dt;
return(*this);
};
template<typename X>
quaternion<long double> & operator *= (const quaternion<X> & rhs)
{
long double ar = (long double)rhs.component_a();
long double br = (long double)rhs.component_b();
long double cr = (long double)rhs.component_c();
long double dr = (long double)rhs.component_d();
long double at = a*ar-b*br-c*cr-d*dr;
long double bt = (a*br+ar*b)+(c*dr-cr*d);
long double ct = (a*cr+ar*c)+(d*br-dr*b);
long double dt = (a*dr+ar*d)+(b*cr-br*c);
a = at;
b = bt;
c = ct;
d = dt;
return(*this);
};
quaternion<long double> & operator /= (const long double & rhs)
{
a /= rhs;
b /= rhs;
c /= rhs;
d /= rhs;
return(*this);
};
quaternion<long double> & operator /= (const ::std::complex<long
double> & rhs)
{
long double ar = rhs.real();
long double br = rhs.imag();
long double denominator = ar*ar+br*br;
a = (a*ar+b*br)/denominator;
b = (ar*b-a*br)/denominator;
c = (ar*c-d*br)/denominator;
d = (ar*d+br*c)/denominator;
return(*this);
};
template<typename X>
quaternion<long double> & operator /= (const quaternion<X> & rhs)
{
long double ar = (long double)rhs.component_a();
long double br = (long double)rhs.component_b();
long double cr = (long double)rhs.component_c();
long double dr = (long double)rhs.component_d();
long double denominator = ar*ar+br*br+cr*cr+dr*dr;
a = (a*ar+b*br+c*cr+d*dr)/denominator;
b = ((ar*b-a*br)+(cr*d-c*dr))/denominator;
c = ((ar*c-a*cr)+(dr*b-d*br))/denominator;
d = ((ar*d-a*dr)+(br*c-b*cr))/denominator;
return(*this);
};
protected:
long double a;
long double b;
long double c;
long double d;
private:
};
// operators
template<typename T>
quaternion<T> operator + (const T & lhs, const quaternion<T> rhs)
{
quaternion<T> res(lhs);
res += rhs;
return(res);
}
template<typename T>
quaternion<T> operator + (const quaternion<T> lhs, const T & rhs)
{
quaternion<T> res(lhs);
res += rhs;
return(res);
}
template<typename T>
quaternion<T> operator + (const ::std::complex<T> & lhs, const
quaternion<T> rhs)
{
quaternion<T> res(lhs);
res += rhs;
return(res);
}
template<typename T>
quaternion<T> operator + (const quaternion<T> lhs, const
::std::complex<T> & rhs)
{
quaternion<T> res(lhs);
res += rhs;
return(res);
}
template<typename T>
quaternion<T> operator + (const quaternion<T> lhs, const
quaternion<T> & rhs)
{
quaternion<T> res(lhs);
res += rhs;
return(res);
}
template<typename T>
quaternion<T> operator - (const T & lhs, const quaternion<T> rhs)
{
quaternion<T> res(lhs);
res -= rhs;
return(res);
}
template<typename T>
quaternion<T> operator - (const quaternion<T> lhs, const T & rhs)
{
quaternion<T> res(lhs);
res -= rhs;
return(res);
}
template<typename T>
quaternion<T> operator - (const ::std::complex<T> & lhs, const
quaternion<T> rhs)
{
quaternion<T> res(lhs);
res -= rhs;
return(res);
}
template<typename T>
quaternion<T> operator - (const quaternion<T> lhs, const
::std::complex<T> & rhs)
{
quaternion<T> res(lhs);
res -= rhs;
return(res);
}
template<typename T>
quaternion<T> operator - (const quaternion<T> lhs, const
quaternion<T> & rhs)
{
quaternion<T> res(lhs);
res -= rhs;
return(res);
}
template<typename T>
quaternion<T> operator * (const T & lhs, const quaternion<T> rhs)
{
quaternion<T> res(lhs);
res *= rhs;
return(res);
}
template<typename T>
quaternion<T> operator * (const quaternion<T> lhs, const T & rhs)
{
quaternion<T> res(lhs);
res *= rhs;
return(res);
}
template<typename T>
quaternion<T> operator * (const ::std::complex<T> & lhs, const
quaternion<T> rhs)
{
quaternion<T> res(lhs);
res *= rhs;
return(res);
}
template<typename T>
quaternion<T> operator * (const quaternion<T> lhs, const
::std::complex<T> & rhs)
{
quaternion<T> res(lhs);
res *= rhs;
return(res);
}
template<typename T>
quaternion<T> operator * (const quaternion<T> lhs, const
quaternion<T> & rhs)
{
quaternion<T> res(lhs);
res *= rhs;
return(res);
}
template<typename T>
quaternion<T> operator / (const T & lhs, const quaternion<T> rhs)
{
quaternion<T> res(lhs);
res /= rhs;
return(res);
}
template<typename T>
quaternion<T> operator / (const quaternion<T> lhs, const T & rhs)
{
quaternion<T> res(lhs);
res /= rhs;
return(res);
}
template<typename T>
quaternion<T> operator / (const ::std::complex<T> & lhs, const
quaternion<T> rhs)
{
quaternion<T> res(lhs);
res /= rhs;
return(res);
}
template<typename T>
quaternion<T> operator / (const quaternion<T> lhs, const
::std::complex<T> & rhs)
{
quaternion<T> res(lhs);
res /= rhs;
return(res);
}
template<typename T>
quaternion<T> operator / (const quaternion<T> lhs, const
quaternion<T> & rhs)
{
quaternion<T> res(lhs);
res /= rhs;
return(res);
}
template<typename T>
quaternion<T> operator + (const quaternion<T> & q)
{
return(q);
}
template<typename T>
quaternion<T> operator - (const quaternion<T> & q)
{
return(quaternion<T>(-q.component_a(),-q.component_b(),-q.component_c(),-q.component_d()));
}
template<typename T>
bool operator == (const T & lhs, const quaternion<T> rhs)
{
return((rhs.component_a() == lhs)&&(rhs.component_b() ==
T(0))&&(rhs.component_c() == T(0))&&(rhs.component_d() == T(0)));
}
template<typename T>
bool operator == (const quaternion<T> lhs, const T & rhs)
{
return((lhs.component_a() == rhs)&&(lhs.component_b() ==
T(0))&&(lhs.component_c() == T(0))&&(lhs.component_d() == T(0)));
}
template<typename T>
bool operator == (const ::std::complex<T> & lhs, const
quaternion<T> rhs)
{
return((rhs.component_a() == lhs.real())&&(rhs.component_b() ==
lhs.imag())&&(rhs.component_c() == T(0))&&(rhs.component_d() == T(0)));
}
template<typename T>
bool operator == (const quaternion<T> lhs, const
::std::complex<T> & rhs)
{
return((lhs.component_a() == rhs.real())&&(lhs.component_b() ==
rhs.imag())&&(lhs.component_c() == T(0))&&(lhs.component_d() == T(0)));
}
template<typename T>
bool operator == (const quaternion<T> lhs, const quaternion<T>
& rhs)
{
return((rhs.component_a() == lhs.component_a())&&(rhs.component_b() ==
lhs.component_b())&&(rhs.component_c() ==
lhs.component_c())&&(rhs.component_d() == lhs.component_d()));
}
template<typename T>
bool operator != (const T & lhs, const quaternion<T> rhs)
{
return(!(lhs == rhs));
}
template<typename T>
bool operator != (const quaternion<T> lhs, const T & rhs)
{
return(!(lhs == rhs));
}
template<typename T>
bool operator != (const ::std::complex<T> & lhs, const
quaternion<T> rhs)
{
return(!(lhs == rhs));
}
template<typename T>
bool operator != (const quaternion<T> lhs, const
::std::complex<T> & rhs)
{
return(!(lhs == rhs));
}
template<typename T>
bool operator != (const quaternion<T> lhs, const quaternion<T>
& rhs)
{
return(!(lhs == rhs));
}
// Note: we allow the following formats, whith a, b, c, and d reals
// a
// (a), (a,b), (a,b,c), (a,b,c,d)
// (a,(c)), (a,(c,d)), ((a)), ((a),c), ((a),(c)), ((a),(c,d)),
((a,b)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,))
template<typename T, typename charT, class traits>
::std::basic_istream<charT,traits> & operator >>
( ::std::basic_istream<charT,traits> & is,
quaternion<T> & q)
{
const ::std::ctype<charT> & ct = ::std::use_facet< ::std::ctype<charT> >(is.getloc());
T a = T();
T b = T();
T c = T();
T d = T();
::std::complex<T> u = ::std::complex<T>();
::std::complex<T> v = ::std::complex<T>();
charT ch = charT();
char cc;
is >> ch; // get the first lexeme
if (is.fail()) goto finish;
cc = ct.narrow(ch, char());
if (cc == '(') // read "(", possible: (a), (a,b), (a,b,c),
(a,b,c,d), (a,(c)), (a,(c,d)), ((a)), ((a),c), ((a),(c)), ((a),(c,d)),
((a,b)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,))
{
is >> ch; // get the second lexeme
if (is.fail()) goto finish;
cc = ct.narrow(ch, char());
if (cc == '(') // read "((", possible: ((a)), ((a),c),
((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,))
{
is.putback(ch);
is >> u; // we extract the first and second components
a = u.real();
b = u.imag();
if (is.fail()) goto finish;
is >> ch; // get the next lexeme
if (is.fail()) goto finish;
cc = ct.narrow(ch, char());
if (cc == ')') // format: ((a)) or ((a,b))
{
q = quaternion<T>(a,b);
}
else if (cc == ',') // read "((a)," or "((a,b),", possible:
((a),c), ((a),(c)), ((a),(c,d)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,))
{
is >> v; // we extract the third and fourth components
c = v.real();
d = v.imag();
if (is.fail()) goto finish;
is >> ch; // get the last lexeme
if (is.fail()) goto finish;
cc = ct.narrow(ch, char());
if (cc == ')') // format: ((a),c), ((a),(c)), ((a),(c,d)),
((a,b),c), ((a,b),(c)) or ((a,b,),(c,d,))
{
q = quaternion<T>(a,b,c,d);
}
else // error
{
is.setstate(::std::ios_base::failbit);
}
}
else // error
{
is.setstate(::std::ios_base::failbit);
}
}
else // read "(a", possible: (a), (a,b), (a,b,c), (a,b,c,d),
(a,(c)), (a,(c,d))
{
is.putback(ch);
is >> a; // we extract the first component
if (is.fail()) goto finish;
is >> ch; // get the third lexeme
if (is.fail()) goto finish;
cc = ct.narrow(ch, char());
if (cc == ')') // format: (a)
{
q = quaternion<T>(a);
}
else if (cc == ',') // read "(a,", possible: (a,b), (a,b,c),
(a,b,c,d), (a,(c)), (a,(c,d))
{
is >> ch; // get the fourth lexeme
if (is.fail()) goto finish;
cc = ct.narrow(ch, char());
if (cc == '(') // read "(a,(", possible: (a,(c)), (a,(c,d))
{
is.putback(ch);
is >> v; // we extract the third and fourth component
c = v.real();
d = v.imag();
if (is.fail()) goto finish;
is >> ch; // get the ninth lexeme
if (is.fail()) goto finish;
cc = ct.narrow(ch, char());
if (cc == ')') // format: (a,(c)) or (a,(c,d))
{
q = quaternion<T>(a,b,c,d);
}
else // error
{
is.setstate(::std::ios_base::failbit);
}
}
else // read "(a,b", possible: (a,b), (a,b,c), (a,b,c,d)
{
is.putback(ch);
is >> b; // we extract the second component
if (is.fail()) goto finish;
is >> ch; // get the fifth lexeme
if (is.fail()) goto finish;
cc = ct.narrow(ch, char());
if (cc == ')') // format: (a,b)
{
q = quaternion<T>(a,b);
}
else if (cc == ',') // read "(a,b,", possible: (a,b,c), (a,b,c,d)
{
is >> c; // we extract the third component
if (is.fail()) goto finish;
is >> ch; // get the seventh lexeme
if (is.fail()) goto finish;
cc = ct.narrow(ch, char());
if (cc == ')') // format: (a,b,c)
{
q = quaternion<T>(a,b,c);
}
else if (cc == ',') // read "(a,b,c,", possible: (a,b,c,d)
{
is >> d; // we extract the fourth component
if (is.fail()) goto finish;
is >> ch; // get the ninth lexeme
if (is.fail()) goto finish;
cc = ct.narrow(ch, char());
if (cc == ')') // format: (a,b,c,d)
{
q = quaternion<T>(a,b,c,d);
}
else // error
{
is.setstate(::std::ios_base::failbit);
}
}
else // error
{
is.setstate(::std::ios_base::failbit);
}
}
else // error
{
is.setstate(::std::ios_base::failbit);
}
}
}
else // error
{
is.setstate(::std::ios_base::failbit);
}
}
}
else // format: a
{
is.putback(ch);
is >> a; // we extract the first component
if (is.fail()) goto finish;
q = quaternion<T>(a);
}
finish:
return(is);
}
template<typename T, typename charT, class traits>
::std::basic_ostream<charT,traits> & operator <<
( ::std::basic_ostream<charT,traits> & os,
const quaternion<T> & q)
{
return(os << '(' << q.component_a() << ','
<< q.component_b() << ','
<< q.component_c() << ','
<< q.component_d() << ',' << ')');
}
// values
template<typename T>
T real(const quaternion<T> & q)
{
return(q.real());
}
template<typename T>
quaternion<T> unreal(const quaternion<T> & q)
{
return(q.unreal());
}
template<typename T>
T abs(const quaternion<T> & q)
{
return(::std::sqrt(norm(q)));
}
// Note: This is the Cayley norm, not the Euclidian norm...
template<typename T>
T norm(const quaternion<T> & q)
{
return(real(q*conj(q)));
}
template<typename T>
quaternion<T> conj(const quaternion<T> & q)
{
T a = q.component_a();
T b = q.component_b();
T c = q.component_c();
T d = q.component_d();
return(quaternion<T>(a,-b,-c,-d));
}
// Note: At this stage, I do not want to introduce the quaternionic equivalents
// of the complex "arg" and "polar", as the corresponding notions require
// a slew of geometry classes to be relevant. I will therefore only
do so
// in a future revision of this class.
//
// Also, the only transcendental, yet "classical" functions of a quaternion
// I know how to compute are the exponential, sinh and cosh, and the "pow"
// function implemmented below. Other versions of the "pow" functions are
// essentially meaningless (or at the very least quite useless), and
the same goes
// for sqrt. The Moivre formula for cos and sin fail in the general case,
// and there is some ambiguity in the definition of tanh (so it will
not be
// provided either).
//
// That the exponential (and related functions) alows a "closed"
formula is
// a theorem of the author.
//
// Note that the exponential uses the function "sinc_pi" ("Sinus
Cardinal of
// index pi"), which is defined on R by sinc_pi(x) = sin(x)/x (it is implemented
// in another library). We will also need the function "sinhc_pi" ("Hyperbolic
// Sinus Cardinal of index pi"), which is defined on R as sinhc_pi(x)
= sinh(x)/x.
template<typename T>
quaternion<T> exp(quaternion<T> const & q)
{
T u = ::std::exp(real(q));
T z = ::math::abs(unreal(q));
T w = ::math::sinc_pi<T>(z);
return(u*quaternion<T>(::std::cos(z),w*q.component_b(),w*q.component_c(),w*q.component_d()));
}
template<typename T>
quaternion<T> cos(const quaternion<T> & q)
{
T z = ::math::abs(unreal(q));
T w = -::std::sin(q.real())*::math::sinhc_pi(z);
return(quaternion<T>(::std::cos(q.real())*::std::cosh(z),
w*q.component_b(), w*q.component_c(), w*q.component_d()));
}
template<typename T>
quaternion<T> sin(const quaternion<T> & q)
{
T z = ::math::abs(unreal(q));
T w = +::std::cos(q.real())*::math::sinc_pi(z);
return(quaternion<T>(::std::sin(q.real())*::std::cosh(z),
w*q.component_b(), w*q.component_c(), w*q.component_d()));
}
template<typename T>
quaternion<T> cosh(const quaternion<T> & q)
{
return((exp(+q)+exp(-q))/T(2));
}
template<typename T>
quaternion<T> sinh(const quaternion<T> & q)
{
return((exp(+q)-exp(-q))/T(2));
}
template<typename T>
quaternion<T> pow(const quaternion<T> & q,
int n)
{
if (n > 0)
{
return(q*pow(q,n-1)); // yes, this can be quite slow...
}
else if (n < 0)
{
return(pow(quaternion<T>(1)/q,-n));
}
else /* n == 0 */
{
return(quaternion<T>(1));
}
}
}
#endif /* _QUATERNION */
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Jean-Daniel Nicolet" <jdn@llinkvest.ch>
Date: 2000/05/25 Raw View
Hubert HOLIN wrote in message <392AEC38.DA02E897@club-internet.fr>...
>Paris (U.E.), le 23/05/2000
>
> Quaternions are a useful, if somewhat lesser known, kin to the complex
>numbers. It is my contention that at least minimal support should be
>added to the C++ standard. As a first step towards that goal, I present
>here a possible implementation, along the line of the complex numbers,
>to help define the "existing art", when the standard comes up for
>revision some time in the (distant) future.
Thank you for posting your personal implementation, so it will remain in =
the
FAQ for the future, where anybody needing it can grab it. Though a "natur=
al"
extension of complex numbers, I don't feel there is an urgent need for th=
em
in the C++ community. Already complex numbers are porbably kind of a luxu=
ry,
used by a small percentage (less than 1% ?) of usual programmers (flames,=
I
feel flames in my back!).
Quaternions are probably used two orders of magnitude less than complex
numbers, so it is not worth the standardization trouble. Moreover, now we
have the implementation you provided, so everything is fine! Blague =E0 p=
art,
you must admit that everybody attempting a serious implementation of them
won't fall far beyond what you submitted, so the risk for incompatibiliti=
es
should be very low.
I would personnally also have chosen a namespace math with a quaternion
class, so we even agree on names.
Speaking of cryptography, elliptic curves and polynoms over finite fields
are probably much more useful (and difficult to implement efficiently), b=
ut
I'm convinced that such mathematical specialities should remain in the
domain of extension libraries and not clutter an already thick standard
library.
Remember that for each programmer finding it useful, thousand of others h=
ave
to invest time learning it to finally deduce they don't need it after all.
We've already enough similar suffering with stuff like valarrays (flames
again).
Jean-Daniel Nicolet
Software Consultant
Geneva
Switzerland
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]