How do you overload a 2/3D "vector" to produce its length?

M

Mirco Wahab

Hi,

after working with some more algebra and a
homebrewn overloaded (lightweight) vector/matrix
class, I'm somehow weary of writing V.length() all
the time ;-)

After looking through available operators,
the only feasible operator would be the '~',
for the vector length, therefore having code
like this:

...
double cos_a = ( (C-A) * (B-A) ) // V * W => some dot product
/ ( ~(C-A) * ~(B-A) ); // ~V => vector scalar length
...

which looks "almost" idiomatic.

Any other ideas? Are there potential
precedence traps to be expected?

Or should I better stick with
...
/ ( (C-A).length() * (B-A).length() )
...

Thanks & Regards

Mirco
 
J

joecook

Any other ideas? Are there potential
precedence traps to be expected?

Or should I better stick with
   ...
   / ( (C-A).length() * (B-A).length() )
   ...

Absolutely. There is no built-in operator that has the same semantics
as "length". Using "~" is impossible to read and maintain. Writing
out "length()" on the other hand is extremely clear.

Joe C
 
C

Carlo Milanesi

Mirco said:
after working with some more algebra and a
homebrewn overloaded (lightweight) vector/matrix
class, I'm somehow weary of writing V.length() all
the time ;-)

I prefer to use the word "norm", as in "v.norm()", instead of "length".
 
J

Jim Langston

Carlo Milanesi said:
I prefer to use the word "norm", as in "v.norm()", instead of "length".

However, norm might get confused with being a normalized vector. I would
stick with length or distance.
 
J

James Kanze

Mirco Wahab wrote:
You could instead define a stand-alone length function that
calls the length method. That would save you the . operator,
and leverage the existing parentheses in your sample code.

/ ( length(C-A) * length(B-A) )

That's an interesting idea. I don't buy the "saving the .
operator" part, but the notation does seem to conform more to
typical mathematic notation. I'd argue for the use of . is
preferred with objects have some associated "behavior", but I
don't think that that's really the case here. And other
functions, which you add later (or which someone who doesn't
have access to the matrix code adds) will also use this syntax.
It is common in the STL to call these functions "size," rather
than "length:"
/ ( size(C-A) * size(B-A) )

It's also common in many places for size to indicate the number
of bytes (as in the sizeof operator) and length the number of
elements.

In this case, however, I think he's concerned with a
mathematical concept. In which case, he should use whatever is
most frequent in mathematics. (If he wants to be really clear:
elementCount for the number of elements, magnitude for the
corresponding mathematical concept. Of course, if he's already
complaining about the length of length...)
 
M

Maxim Yegorushkin

after working with some more algebra and a
homebrewn overloaded (lightweight) vector/matrix
class, I'm somehow weary of writing V.length() all
the time ;-)

After looking through available operators,
the only feasible operator would be the '~',
for the vector length, therefore having code
like this:

  ...
  double cos_a = (  (C-A) *  (B-A) )     //  V * W => some dot product
               / ( ~(C-A) * ~(B-A) );    // ~V     => vector scalar length
  ...

which looks "almost" idiomatic.

Any other ideas? Are there potential
precedence traps to be expected?

Or should I better stick with
   ...
   / ( (C-A).length() * (B-A).length() )
   ...

Another option would be to have length() member function as well as a
"shortcut" namespace:

template<class T>
struct Vector
{
// ...
size_t length() const;
// ...
};

namespace Shortcuts {

template<class T>
inline size_t L(Vector<T> const& v)
{
return v.length();
}

}

int main()
{
Vector<int> v;

size_t s = v.length();

using Shortcuts::L;
s = L(v);
}
 
M

Mirco Wahab

Thanks to all involved for this interesting
discussion about flavor and elegancy ;-)

For my personal taste, I like the STL-like
notion of FUNC(object), as has been suggested
by Jeff. Furthermore, 'length' does change
the meaning depending of context. 'norm' would
be a correct (and short) term but is easy to
confuse with 'normalize' or 'normalized'.

After consulting, Wikipedia
http://en.wikipedia.org/wiki/Euclidean_vector
I think I'll go for 'magnitude' which
can be shortened to 'mag' without ambiguity
(this has been already suggested by Daniel).

A source snippet like below would IMHO be both
self-explanatory and uncluttered:

...
double cos_a = ( (C-A) * (B-A) ) / ( mag(C-A) * mag(B-A) ),
cos_b = ( (A-B) * (C-B) ) / ( mag(A-B) * mag(C-B) ),
cos_c = ( (A-C) * (B-C) ) / ( mag(A-C) * mag(B-C) );
...

Thanks & Regards

M.
 
S

SG

  double cos_a = ( (C-A) * (B-A) ) / ( mag(C-A) * mag(B-A) ),
         cos_b = ( (A-B) * (C-B) ) / ( mag(A-B) * mag(C-B) ),
         cos_c = ( (A-C) * (B-C) ) / ( mag(A-C) * mag(B-C) );

You might also want to
* reuse the result of the vector subtractions
* write a function for this expression
* add a "mag2" function for the squared magnitude
* replace operator* with a more descriptive function name for the
inner product like "inner_prod".

Your function could look like this:

double cosine(Vect x, Vect y, const Vect& sub) {
using std::sqrt;
x -= sub;
y -= sub;
return inner_prod(x,y) / sqrt( mag2(x) * mag2(y) );
}

:
double cos_a = cosine(C,B,A);
:

just my 2 cents,
SG
 
Z

Zeppe

Carlo said:
I prefer to use the word "norm", as in "v.norm()", instead of "length".

I personally find "norm" quite misleading in this case, because in
mathematics the concept is related to the length of a (numerical) vector
in some space, rather than the dimensionality of the space that is
returned by the length() function.

Zeppe
 
Z

Zeppe

Zeppe said:
I personally find "norm" quite misleading in this case, because in
mathematics the concept is related to the length of a (numerical) vector
in some space, rather than the dimensionality of the space that is
returned by the length() function.

sorry, reading a later post I actually realised that the function was
indeed meant to return the norm of a vector :) Then I perfectly agree
with Carlo!

Zeppe
 
T

Thomas J. Gritzan

Mirco said:
Thanks to all involved for this interesting
discussion about flavor and elegancy ;-)

For my personal taste, I like the STL-like
notion of FUNC(object), as has been suggested
by Jeff. Furthermore, 'length' does change
the meaning depending of context. 'norm' would
be a correct (and short) term but is easy to
confuse with 'normalize' or 'normalized'.

After consulting, Wikipedia
http://en.wikipedia.org/wiki/Euclidean_vector
I think I'll go for 'magnitude' which
can be shortened to 'mag' without ambiguity
(this has been already suggested by Daniel).

The standard library uses std::abs() and std::norm() for std::complex,
where std::abs() returns the magnitude, and std::norm() returns the
squared magnitude.
 
C

Carlo Milanesi

Thomas said:
Mirco Wahab schrieb:
The standard library uses std::abs() and std::norm() for std::complex,
where std::abs() returns the magnitude, and std::norm() returns the
squared magnitude.

std::norm() has a bad name, as it not a norm in the mathematical sense,
and in any other sense either.
No surprise from the fellows that called "vector" a thing that cannot be
added to another vector and cannot be multiplied by a number.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top