|
Boost : |
From: Andreas Harnack (ah.boost.04_at_[hidden])
Date: 2007-03-05 18:27:36
Further to the ongoing discussion of (physical) dimensional analysis and
the physical dimension/unit library I'd like to propose a library
providing two services:
1.Orientational analysis, i.e. compile time analysis for dimensions
indicating a direction in space, also called mathematical dimensions (in
contrast to physical dimensions).
2.Aggregation of values carrying orientational dimensions into a data
structure suitable to represent the concept of vectors in the
geometrical and algebraical sense. A major application of such a vector
class will be Euclidean geometry, so for lack of a better name and to
distinguish it from other concepts using the name vector I'd like to
talk about Euclidean vectors.
The library is not intended to be a linear algebra library. No
algorithms are provided that go beyond scalar and cross product. A
matrix class is included too, but restricted to diagonal matrices, since
matrix inversion is involved and matrix inversion is trivial only for
diagonal matrices.
I'm going to uploaded a proposal into the boost vault under the name
'euclid'. It comes with test programs, examples and a documentation,
discussing some issues of dimensional analyses in general, the current
implementation of Euclidean vectors and possible ways of extending
orientational analysis to a linear algebra library.
The code presented here is real life code taken from a former
application project. It has not been designed with a standalone library
in mind. As such it's likely to have some deficiencies. However, it
seems to be a useful concept, yet reasonably simple, and worth of
sharing. If there's interest in the community , I'd take the effort to
boost it up to the required standards.
The library began as a template providing orientational analysis in an
application project involving graphical programming in both, character
cell graphic as well as pixel graphic. A major source of errors was the
risk to mix up of x and y coordinates, especially since several
libraries where involved with different interface conventions. Using
orientational analysis reduced the error rate significantly.
After having a system of type distinct coordinates and coordinate
expressions that could be check at compile time, it soon became apparent
that it would be helpful to aggregate coordinates into vectors. However,
accepting coordinates as being type distinct has some fundamental
implications on the design of a vector class: the vector can no longer
be a container, since container aggregate equally typed objects. Neither
access operators nor iterators can be defined in the traditional way,
since type would change depending on the object returned or referenced.
Consequently, vectors are better represented by structures rather than
arrays. To allow for an arbitrary number of dimensions a recursive
template structure has been defined. Component access is provided by
explicit type conversion into the component type:
namespace euclid
{
// dimension class template
template<typename T, unsigned int D> class dim
{
T v;
public:
// operations allowed for dim ...
};
// vector class template
template<typename T, unsigned int D> class vec
{
dim<T, D-1> d;
vec<T, D-1> v;
public:
// element access
template <unsigned int I>
operator dim<T,I>() const { return dim<T, I>(v); }
operator dim<T,D-1>() const { return d; }
// vector operations ...
};
// vector class base case specialization
template<typename T> class vec<T,1>
{
dim<T,0> d;
public:
// element access
operator dim<T,0>() const { return d; }
// vector operations ...
};
};
The operations defined for vectors and dimensions are those typically
defined for vector spaces including some (hopefully) reasonable access
and conversion operations.
Applications will typically start by specializing the templates to their
specific needs, like:
namespace myApplication
{
typedef int scalar;
typedef euclid::dim<scalar,0> dimX;
typedef euclid::dim<scalar,1> dimY;
typedef euclid::vec<scalar,2> vect;
// ...
}
or may be templated:
template <class T> class myClass
{
public:
typedef euclid::dim<T,0> dimX;
typedef euclid::dim<T,1> dimY;
typedef euclid::vec<T,2> vect;
// ...
}
Now these types can be used almost like build-in types with the benefits
of additional type checking
void foo(vect v);
void bar(dimX x);
void bar(dimX x, dimY y);
int main()
{
dimX x, x0, x1;
dimY y;
vect v;
x = x0+x1; // OK
y = x; // Error
bar(x) // OK
bar(2*x0+x1) // OK
bar(x+y) // Error
bar(x,y) // OK
bar(x,x) // Error
bar(y,y) // Error
bar(y,x) // Error
bar(v,v) // OK, calls bar(dimX(v), dimY(v));
foo(2*v) // OK
// etc.
}
The library addresses a problem that occurs (at least) in any
application or library involving graphical programming. It is, however,
surprisingly simple in both, implementation and usage. To my knowledge,
no graphical library has addressed orientational analysis yet, while
vectors are typically implemented by some library specific data
structures, requiring unnecessary conversions when passing data from on
library to another. Euclidean vectors could offer a way to solve this
interface problem.
As mentioned above, there's still a way to go to get the code ready for
formal review, in particular naming, layout, format and licensing
issues. If there's interest in the community I'd be happy to do this, so
please let my know.
I will, however, need assistance in proving (and improving) portability.
The library compiles with GNU g++ 3.0.4, 3.3.5 and 3.4.4, but I will be
unable to test it on any other platform in the near future.
Looking forward to any comments,
Andreas
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk