March 08, 2003
Another question for the group:

There doesn't appear to be an abs() method for types creal.  I know this is a very simple function and done by hand easily enough such as:

import math;

/* no errors caught here */

real abs( creal c) {
    return sqrt( c.re*c.re + c.im*c.im);
}

I don't know if this is correct (casting to real necessary in sqrt function?) since I'm very much a beginner with D.

Nevertheless, it would be nice to have maybe a property of creals that renders the "abs" value just like the properties "re" and "im".  Is this possible?

if there are properties:
    .re
    .im

then the property:
    .abs     is equivalent to the above function.

might also be useful. :)

Thanks,
John


March 08, 2003
"John Reimer" <jjreimer@telus.net> wrote in message news:b4bhe6$2lfa$1@digitaldaemon.com...
> Another question for the group:
>
> There doesn't appear to be an abs() method for types creal.  I know this
is
> a very simple function and done by hand easily enough such as:
>
> import math;
>
> /* no errors caught here */
>
> real abs( creal c) {
>     return sqrt( c.re*c.re + c.im*c.im);
> }

I just realized the above is not quite correct since c.im*c.im would render the -1.  The proper calculation drops the imaginary i first.  Please disregard that :-P.

- John


March 08, 2003
I'm having another problem.  I cannot figure out how to construct a complex
expression legally...
The last I tried caused the compiler to crash:

Internal error: ..\ztc\cg87.c 1219

.. Basic complex expressions are easy like:

creal a = 1.0 + 2.0i;

But I cannot create an expression like this (which are important in circuit
calculations):

creal Z1;

Z1 = (1/R1) + (2.0i*PI*F*(C1+C2));

where R1, PI, F, C1 and C2 are all "real."

As you can see I tried putting the imaginary 'i' next to one of the values in an attempt to force that side of the expression to be imaginary.  Didn't work...  I also tried putting the i at the end of the expression... Didn't work either (compiler complains in this case of undefined i).  The above expression seems to crash the compiler. Casting the imaginary portion of the above expression to 'ireal' doesn't seem to work either.

So how do I make a proper complex expression with more complicated subexpressions.

Python does it this way...

Z1 = complex(1/R1, (2.0*pi*F*(C1+C2))

which works just fine...

The short program listing is available if anyone is interested to see why the compiler crashed...

Thanks,

John




March 08, 2003
I'm not sure how the creal is represented in memory, but assuming it's just two 80 bit floats (IEEE 754, or whatever the standard is) right next to eachother, and assuming the comiler won't cry foul if you try to treat a pointer as an array (it works in C, i'm not sure about D) you could save a LOT of processor time doing something like this:

creal abs(creal c)
{
    ubyte* cbytes=cast(byte*)&c;

    //this gives the absolute value of the real part (i'm guessing)
    cbytes[9]&=0x7F;

    //this gives the absolute value of the imaginary part (i'm guessing)
    cbytes[19]&=0x7F;

    return c;
}

Of course this isn't portable at all and there are probably assembly instructions that would do it for you, but I don't know them.  You could also just do a test, if it's less than zero then multiply by -1, that would still be portable and leagues faster just because square roots are even slower than multiplication.

"John Reimer" <jjreimer@telus.net> wrote in message news:b4bhe6$2lfa$1@digitaldaemon.com...
> Another question for the group:
>
> There doesn't appear to be an abs() method for types creal.  I know this
is
> a very simple function and done by hand easily enough such as:
>
> import math;
>
> /* no errors caught here */
>
> real abs( creal c) {
>     return sqrt( c.re*c.re + c.im*c.im);
> }
>
> I don't know if this is correct (casting to real necessary in sqrt function?) since I'm very much a beginner with D.
>
> Nevertheless, it would be nice to have maybe a property of creals that renders the "abs" value just like the properties "re" and "im".  Is this possible?
>
> if there are properties:
>     .re
>     .im
>
> then the property:
>     .abs     is equivalent to the above function.
>
> might also be useful. :)
>
> Thanks,
> John
>
>


March 08, 2003
"Jon Allen" <jallen@minotstateu.edu> wrote in message news:b4cbfn$r9$1@digitaldaemon.com...
> I'm not sure how the creal is represented in memory, but assuming it's
just
> two 80 bit floats (IEEE 754, or whatever the standard is) right next to eachother, and assuming the comiler won't cry foul if you try to treat a pointer as an array (it works in C, i'm not sure about D) you could save a LOT of processor time doing something like this:
>
> creal abs(creal c)
> {
>     ubyte* cbytes=cast(byte*)&c;
>
>     //this gives the absolute value of the real part (i'm guessing)
>     cbytes[9]&=0x7F;
>
>     //this gives the absolute value of the imaginary part (i'm guessing)
>     cbytes[19]&=0x7F;
>
>     return c;
> }
>
> Of course this isn't portable at all and there are probably assembly instructions that would do it for you, but I don't know them.  You could also just do a test, if it's less than zero then multiply by -1, that
would
> still be portable and leagues faster just because square roots are even slower than multiplication.
>

Ok, thanks for the tip, Jon. I only wish it were that simple.  I assumed that since the language provided complex numbers that everything would be ready to go as far as manipulating them was concerned.  I guess not quite yet or maybe I just don't know how it's supposed to work.

But I think your solution is not quite what I was getting at.  The "abs" as in absolute value is not the typical mathematical absolute value when complex numbers are concerned.  Perhaps you were thinking that I wanted the non-negative values of both real and imaginary parts? .

Not so I'm afraid... I'm looking for the resultant magnitude of a complex pair (also referred as the absolute value in complex math for some weird reason) which is the pythagorean sum of the real and imaginary parts, or the squareroot of the sum of the squares of the magnitudes of the real and imaginary parts (phew, what a mouthful).  Complex numbers are used in electronics AC analysis and are often called phasors.  They are also represented in polar form in which case the complex parts are converted to a magnitude (abs) and a relative phase angle.  It becomes necessary to convert between formats now and again.

As far as the lowlevel optimization goes, that's not really my concern yet... I just want it to work :-P.  The implementor of the language's complex numbers should do those optimizations for me, I think :-).

I guess I still have to figure out how to do all this in D.  Python does it seamlessly and provides all the necessary methods out of the box.  D must not be there yet... :-) Oh well, it's a neat language, still.

Thanks for the suggestion though; that's some pretty slick D hacking. :-)

Later,

John.



March 08, 2003
John Reimer wrote:
> Another question for the group:
> 
> There doesn't appear to be an abs() method for types creal.  I know this is
> a very simple function and done by hand easily enough such as:
> 
> import math;
> 
> /* no errors caught here */
> 
> real abs( creal c) {
>     return sqrt( c.re*c.re + c.im*c.im);
> }
> 
> I don't know if this is correct (casting to real necessary in sqrt
> function?) since I'm very much a beginner with D.

It's syntactually correct, but better is:

   real abs(creal c) {
      return math2.hypot(c.re, c.im);
   }

As sqrt uses double, and hypot can do some overflow/underflow minimisation.

> Nevertheless, it would be nice to have maybe a property of creals that
> renders the "abs" value just like the properties "re" and "im".  Is this
> possible?

Yes, and it should be in.  Feedback on what users of complex need is valuable, as there aren't many serious users of it here.  Don't expect anything in the near future, however.

March 08, 2003
So you're saying it should be

return sqrt( c.re*c.re - c.im*c.im );

hehe

This is true for any numeric array type:

float x[3];
return sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]); // calculate magnitude of
vector

It's pythagoras' theorem for christ's sake... one of the most fundamental constructs in all of math.  Nowadays it's usually called the vector norm or the magnitude, but abs works as well.  Length would be another good word for it.

I would like to have a standard library template function to compute it.

I am not sure it's a good idea for this kind of thing to be a property, because then when you write a template that takes unknown types and gets its abs, it's not possible to make every type have an abs property.  There is confusion between member function call syntax and property get syntax.  It *is* however possible to make a global overloaded function that takes one of your types as an argument, so that appears to be the correct approach;  the one with the least limitations.

Sean

"John Reimer" <jjreimer@telus.net> wrote in message news:b4bk8j$2mvh$1@digitaldaemon.com...
>
> "John Reimer" <jjreimer@telus.net> wrote in message news:b4bhe6$2lfa$1@digitaldaemon.com...
> > Another question for the group:
> >
> > There doesn't appear to be an abs() method for types creal.  I know this
> is
> > a very simple function and done by hand easily enough such as:
> >
> > import math;
> >
> > /* no errors caught here */
> >
> > real abs( creal c) {
> >     return sqrt( c.re*c.re + c.im*c.im);
> > }
>
> I just realized the above is not quite correct since c.im*c.im would
render
> the -1.  The proper calculation drops the imaginary i first.  Please disregard that :-P.
>
> - John


March 08, 2003
"Sean L. Palmer" <seanpalmer@directvinternet.com> wrote in message news:b4dits$mue$1@digitaldaemon.com...
> So you're saying it should be
>
> return sqrt( c.re*c.re - c.im*c.im );
>
> hehe

Yes. That was what I was trying to say. :-)

>
> This is true for any numeric array type:
>
> float x[3];
> return sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]); // calculate magnitude of
> vector
>
> It's pythagoras' theorem for christ's sake... one of the most fundamental constructs in all of math.  Nowadays it's usually called the vector norm
or
> the magnitude, but abs works as well.  Length would be another good word
for
> it.

Hmm.. I have no idea what Christ has to do with it... but, yes, it is a basic distance equation also called the pythagorean theorem.  I'm sorry you felt you had to point that basic concept out.  However, my only concern here was dealing with the complex aspect of it, and whether or not there was the basic abs function available.  I was not really concerned as to whether people could identify it's origin.  Perhaps I misjudged your manner here.  I am new to the list and perhaps should not have presumed to ask these questions until I was better acquainted with the people here or at least they were better acquainted with me.

>
> I would like to have a standard library template function to compute it.
>
> I am not sure it's a good idea for this kind of thing to be a property, because then when you write a template that takes unknown types and gets
its
> abs, it's not possible to make every type have an abs property.  There is confusion between member function call syntax and property get syntax.  It *is* however possible to make a global overloaded function that takes one
of
> your types as an argument, so that appears to be the correct approach;
the
> one with the least limitations.
>
> Sean

Good point.  I'm not extrememely knowledgeable as to language design practice; right now it's more "get the job done."  But you seem to know what you're talking about.

Thanks for your time,

John


March 08, 2003
>
> It's syntactually correct, but better is:
>
>     real abs(creal c) {
>        return math2.hypot(c.re, c.im);
>     }
>
> As sqrt uses double, and hypot can do some overflow/underflow
minimisation.

That does look good :-).  But I've never seen a math2 module before.  Is it now part of phobos?

>
> > Nevertheless, it would be nice to have maybe a property of creals that renders the "abs" value just like the properties "re" and "im".  Is this possible?
>
> Yes, and it should be in.  Feedback on what users of complex need is valuable, as there aren't many serious users of it here.  Don't expect anything in the near future, however.
>

Thanks, I understand what you're saying.  Just checking to see if there were some answers that I didn't know about yet.

Thanks for your response, Burton.  Much appreciated.

Later,

John


March 09, 2003
> >
> > This is true for any numeric array type:
> >
> > float x[3];
> > return sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]); // calculate magnitude
of
> > vector
> >
> > It's pythagoras' theorem for christ's sake... one of the most
fundamental
> > constructs in all of math.  Nowadays it's usually called the vector norm
> or
> > the magnitude, but abs works as well.  Length would be another good word
> for
> > it.
>
> Hmm.. I have no idea what Christ has to do with it... but, yes, it is a basic distance equation also called the pythagorean theorem.  I'm sorry
you
> felt you had to point that basic concept out.  However, my only concern
here
> was dealing with the complex aspect of it, and whether or not there was
the
> basic abs function available.  I was not really concerned as to whether people could identify it's origin.  Perhaps I misjudged your manner here.
I
> am new to the list and perhaps should not have presumed to ask these questions until I was better acquainted with the people here or at least they were better acquainted with me.
>

I think the point was that the usual (an accepted) name of the functions you
call abs
is magnitude, modulus or norm depending on the item and if your a mathmation
or engineer (j not i)
is there a mathmatical 'abs' for a complex number, quaternion, vector,
matrix ?
I though it was just reals that had an abs;  a vector abs I would expect to
abs the elements not return magnitude.

does D have a conjugate property for complex ?

magnitude ::= a * a.conjugate; // (a+ib)*(a-ib) = a*a + b*b;









« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home