www.digitalmars.com         C & C++   DMDScript  

D - Why this strange complex type

reply "Bjornar Svingen" <bjornar.svingen ktv.no> writes:
This looks like a really nice language. I browsed through the online
documentation and stopped at the Basic Data Types. I am more into the
numerical bits of programming and nothing really take FORTRAN regarding
number crunching. Anyway if i happened to write something in D, the first
thing i had to do was to redefine the complex type. As it is it is totally
useless in any real life applications. No one will use extended floating
point precision for complex numbers other than in some very few extreme
cases. 99% would be single or double.

Complex number should have type definition of two floats (2 * 32 bit), then
a double complex type consisting of two doubles, and last a extended
precision. This would be the "natural" way of doing it since complex numbers
are afterall, only numbers. This would also make the complex type usable in
real applications without having to modify it or make new classes of
numbers.

Anyway, i have to download it and try it since it looks very apealing.
Jan 05 2003
next sibling parent reply "Walter" <walter digitalmars.com> writes:
Ok, why is 80 bit complex types not useful?

"Bjornar Svingen" <bjornar.svingen ktv.no> wrote in message
news:av9gju$20pd$1 digitaldaemon.com...
 This looks like a really nice language. I browsed through the online
 documentation and stopped at the Basic Data Types. I am more into the
 numerical bits of programming and nothing really take FORTRAN regarding
 number crunching. Anyway if i happened to write something in D, the first
 thing i had to do was to redefine the complex type. As it is it is totally
 useless in any real life applications. No one will use extended floating
 point precision for complex numbers other than in some very few extreme
 cases. 99% would be single or double.

 Complex number should have type definition of two floats (2 * 32 bit),

 a double complex type consisting of two doubles, and last a extended
 precision. This would be the "natural" way of doing it since complex

 are afterall, only numbers. This would also make the complex type usable

 real applications without having to modify it or make new classes of
 numbers.

 Anyway, i have to download it and try it since it looks very apealing.

Jan 05 2003
parent reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
For starters, the same reason people use float instead of extended:
storage!  An array of many complex types takes 2.5 times as much storage if
extended is the underlying float type instead of single.  Not to mention
that FPU's run faster for many operations if placed into single precision
mode.

You could probably templatize complex so the user could choose how much
precision they require.

Another practical concern for vendors is that since they're specified as 80
bit,  the compiler cannot choose to utilize the SSE2 registers (a pair of
double-precision floating point numbers) to acceleration operations using
SIMD on Pentium 4.

D should either have a full suite of customizable numeric types, or the
capability for programmers to make their own.  Don't add them in just
because they're in C99 and C++... I don't find those types useful either.  I
might use them if I did 2D graphics, but for 3D graphics and other higher
applications complex is just not good enough.  In any case I prefer to label
my axes X and Y instead of Real and Imaginary.

Sean

"Walter" <walter digitalmars.com> wrote in message
news:avb525$2sku$3 digitaldaemon.com...
 Ok, why is 80 bit complex types not useful?

Jan 05 2003
parent "Bjornar Svingen" <bjornar.svingen ktv.no> writes:
"Sean L. Palmer"
 For starters, the same reason people use float instead of extended:
 storage!  An array of many complex types takes 2.5 times as much storage

 extended is the underlying float type instead of single.  Not to mention
 that FPU's run faster for many operations if placed into single precision
 mode.

matrix number crunching, like CFD (computational fluid dynamics) and FEM (finite element method, for calculation of just about everything, forces, structures etc), single precision is more than enough accuracy. The inaccuracies in those calculations does not come from round off errors, but from the methods themselves and simplifications/errors in modelling. Complex is used when calculating vibrations and resonance frequencies. Often clusters of PCs in parallel are used for these calculations to speed up things and to use as much memory as possible. To model correctly and to achieve more correct results require huge amount of memory, not huge amount of machine precision.
Jan 06 2003
prev sibling parent reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
I would personally rather have the ability to build my own complex type (or
matrix, or whatever algebraic type) than have one built in that won't suit
the needs of most users.

Now that D has operator overloading, one could define a struct that
represents complex numbers fairly easily.  The only thing really missing is
a way to construct them.  D structs don't have constructors last I checked.

If complex is built into the language, may as well build in quaternions as
well.  Taken to the logical extreme, this would end up being a huge burden
on compiler vendors, and would only be used by a fraction of the potential D
programmers.  Who would decide how much functionality to build into the
types anyway?  You need exp and log, all kinds of rotations.  Would we be
able to add new properties or member functions to complex?

I'd rather see some fundamental support for doing dot products and outer
products on arrays.  D arrays are pretty powerful; we could almost use
float[2] as our complex type and float[4] as our quaternion type!

Sean

"Bjornar Svingen" <bjornar.svingen ktv.no> wrote in message
news:av9gju$20pd$1 digitaldaemon.com...
 This looks like a really nice language. I browsed through the online
 documentation and stopped at the Basic Data Types. I am more into the
 numerical bits of programming and nothing really take FORTRAN regarding
 number crunching. Anyway if i happened to write something in D, the first
 thing i had to do was to redefine the complex type. As it is it is totally
 useless in any real life applications. No one will use extended floating
 point precision for complex numbers other than in some very few extreme
 cases. 99% would be single or double.

 Complex number should have type definition of two floats (2 * 32 bit),

 a double complex type consisting of two doubles, and last a extended
 precision. This would be the "natural" way of doing it since complex

 are afterall, only numbers. This would also make the complex type usable

 real applications without having to modify it or make new classes of
 numbers.

 Anyway, i have to download it and try it since it looks very apealing.

Jan 05 2003
parent reply "Walter" <walter digitalmars.com> writes:
The back end fully supports complex types, it was a no-brainer to put it
into D. The code also internally fully supports float and double precisions
for complex, all it lacks is a name for it.

"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
news:avb71b$2ur3$1 digitaldaemon.com...
 I would personally rather have the ability to build my own complex type

 matrix, or whatever algebraic type) than have one built in that won't suit
 the needs of most users.

 Now that D has operator overloading, one could define a struct that
 represents complex numbers fairly easily.  The only thing really missing

 a way to construct them.  D structs don't have constructors last I

 If complex is built into the language, may as well build in quaternions as
 well.  Taken to the logical extreme, this would end up being a huge burden
 on compiler vendors, and would only be used by a fraction of the potential

 programmers.  Who would decide how much functionality to build into the
 types anyway?  You need exp and log, all kinds of rotations.  Would we be
 able to add new properties or member functions to complex?

 I'd rather see some fundamental support for doing dot products and outer
 products on arrays.  D arrays are pretty powerful; we could almost use
 float[2] as our complex type and float[4] as our quaternion type!

 Sean

Jan 09 2003
parent reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
That's not a very good reason to add something to a language spec.  Sure it
makes sense to add it to DMD, but not D necessarily.

If the backend doesn't emit SIMD, there's no reason for it to have anything
special for complex.

Sean

----- Original Message -----
From: "Walter" <walter digitalmars.com>
Newsgroups: D
Sent: Thursday, January 09, 2003 1:03 AM
Subject: Re: Why this strange complex type


 The back end fully supports complex types, it was a no-brainer to put it
 into D. The code also internally fully supports float and double

 for complex, all it lacks is a name for it.

Jan 09 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
news:avkgcl$20i4$1 digitaldaemon.com...
 That's not a very good reason to add something to a language spec.  Sure

 makes sense to add it to DMD, but not D necessarily.

The good reason is for it to be an upgrade from C. One design goal of D is to not take away any C features without a really strong reason. I also happened to like type complex <g>.
Jan 11 2003
next sibling parent Steve <Steve_member pathlink.com> writes:
In article <avqr6s$2l66$1 digitaldaemon.com>, Walter says...
"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
news:avkgcl$20i4$1 digitaldaemon.com...
 That's not a very good reason to add something to a language spec.  Sure

 makes sense to add it to DMD, but not D necessarily.

The good reason is for it to be an upgrade from C. One design goal of D is to not take away any C features without a really strong reason. I also happened to like type complex <g>.

point vector ? Why does it need its own built in type ?
Jan 12 2003
prev sibling parent reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
Type complex is really just an array of two real numbers with some
overloaded operators attached.

That can be done in the library, or should be able to be.  ;)

Complex numbers are just the tip of the iceberg.  Are you going to add
quaternions, octonions, etc?

Even complex should have variants matching the available machine floating
point precisions.

Sean

"Walter" <walter digitalmars.com> wrote in message
news:avqr6s$2l66$1 digitaldaemon.com...
 "Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
 news:avkgcl$20i4$1 digitaldaemon.com...
 That's not a very good reason to add something to a language spec.  Sure

 makes sense to add it to DMD, but not D necessarily.

The good reason is for it to be an upgrade from C. One design goal of D is to not take away any C features without a really strong reason. I also happened to like type complex <g>.

Jan 12 2003
next sibling parent reply Steve <Steve_member pathlink.com> writes:
Here's the start to a general solution, feedback welcome ...

vector2{64} v;  // A two dimensional vector. Each component is 64 bits wide.

// Example vector component access.
v.(0) = 1.0;
v.(1) = 1.0; 

// A syntax error the preprocessor could pick up ...
v.(2) = 1.0;  // Syntax error - the vector is only two dimensional ...

Indirect access ...
uint{64} index = 1;

v.(index) = 1.0;



So, we can represent a 64 bit precision complex number as :-

vector2{64} c;

A quaternion ...

vector4{64} q;

A high precision location in 3 dimensional space ...
vector3{128} p;

.. etc ...

Taking this idea forwards, we can tidy up the whole mess of somebody having to
get out a thesaurus every time we need a wider int or float data type.

Examples ...
uint{8} my_byte;
int{32} my_signed_number;
int{128} big_one;
float{128} f;
float{1024} not_yet;

.. etc ...

.. Additionally, native matrix support should be added.

E.g. 
matrix34{64} m; // 3x4 matrix with 64 bit floating point scalar components.

// Example component access :-
m.(3,1) = 0.0;  

.. again, the preprocessor could pick up some invalid accesses.

It is important to implement vector and matrix datatypes and operations in the
language to enable the compiler to acheive optimal parallelization. A library
implementation is not the optimal solution here.

Comments welcome ...

- Steve.
Jan 12 2003
parent reply Steve <Steve_member pathlink.com> writes:
Additionally, to complete the picture ...

ivector2{32} v;  // A two dimensional vector consisting of two 32 bit signed
integer components.

uivector2{32} v;  // A two dimensional vector consisting of two 32 bit unsigned
integer components.

imatrix21{8}; // A 2x1 matrix, each component is an signed byte ...
uimatrix21{16}; // A 2x1 matrix, each component is an unsigned 16 bit integer
..

Remember, it is *very* important that these higher dimensional data types are
implementated within the language to enable the compiler to generate highly
parallelized code on modern cpus ... Support for these features in the language
and a halfway decent compiler implementation would be reason enough to move from
C++ to D.




In article <avrruv$160s$1 digitaldaemon.com>, Steve says...
Here's the start to a general solution, feedback welcome ...

vector2{64} v;  // A two dimensional vector. Each component is 64 bits wide.

// Example vector component access.
v.(0) = 1.0;
v.(1) = 1.0; 

// A syntax error the preprocessor could pick up ...
v.(2) = 1.0;  // Syntax error - the vector is only two dimensional ...

Indirect access ...
uint{64} index = 1;

v.(index) = 1.0;



So, we can represent a 64 bit precision complex number as :-

vector2{64} c;

A quaternion ...

vector4{64} q;

A high precision location in 3 dimensional space ...
vector3{128} p;

.. etc ...

Taking this idea forwards, we can tidy up the whole mess of somebody having to
get out a thesaurus every time we need a wider int or float data type.

Examples ...
uint{8} my_byte;
int{32} my_signed_number;
int{128} big_one;
float{128} f;
float{1024} not_yet;

.. etc ...

.. Additionally, native matrix support should be added.

E.g. 
matrix34{64} m; // 3x4 matrix with 64 bit floating point scalar components.

// Example component access :-
m.(3,1) = 0.0;  

.. again, the preprocessor could pick up some invalid accesses.

It is important to implement vector and matrix datatypes and operations in the
language to enable the compiler to acheive optimal parallelization. A library
implementation is not the optimal solution here.

Comments welcome ...

- Steve.

Jan 12 2003
next sibling parent "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
You're already starting down the "bad" path by integrating the vector types
and sizes into your identifiers.

You need something more like template syntax probably;  something like:

typedef vector(int(32), 2) ipoint32;
typedef vector(float(64), 4) doublequaternion;

But why have vector when we already have arrays that are really nice?

typedef int{32}[2] ipoint32;
typedef float{64}[4] doublequaternion;

In all actuality these types really represent algebras and as such need new
operators (unless the compiler is smart enough to know how to multiply your
types automatically;  I don't think this is possible since there's so many
ways to define a multiplication).  Hopefully D operator overloading allows
you to make free module scope operators taking any two arbitrary types.

It seems likely you'd also want to be able to do something like this:

struct doublequaternion : float(64)[4]
{
    doublequaternion(float(64)[3] axis, float(64) angleradians)
    {
        ...
    }
}

But this would be nicer and cleaner using decorators probably.  Not sure if
decorators will ever make it into D.

Sean

"Steve" <Steve_member pathlink.com> wrote in message
news:avrt3d$1f3v$1 digitaldaemon.com...
 Additionally, to complete the picture ...

 ivector2{32} v;  // A two dimensional vector consisting of two 32 bit

 integer components.

 uivector2{32} v;  // A two dimensional vector consisting of two 32 bit

 integer components.

 imatrix21{8}; // A 2x1 matrix, each component is an signed byte ...
 uimatrix21{16}; // A 2x1 matrix, each component is an unsigned 16 bit

 ..

 Remember, it is *very* important that these higher dimensional data types

 implementated within the language to enable the compiler to generate

 parallelized code on modern cpus ... Support for these features in the

 and a halfway decent compiler implementation would be reason enough to

 C++ to D.




 In article <avrruv$160s$1 digitaldaemon.com>, Steve says...
Here's the start to a general solution, feedback welcome ...

vector2{64} v;  // A two dimensional vector. Each component is 64 bits


// Example vector component access.
v.(0) = 1.0;
v.(1) = 1.0;

// A syntax error the preprocessor could pick up ...
v.(2) = 1.0;  // Syntax error - the vector is only two dimensional ...

Indirect access ...
uint{64} index = 1;

v.(index) = 1.0;



So, we can represent a 64 bit precision complex number as :-

vector2{64} c;

A quaternion ...

vector4{64} q;

A high precision location in 3 dimensional space ...
vector3{128} p;

.. etc ...

Taking this idea forwards, we can tidy up the whole mess of somebody


get out a thesaurus every time we need a wider int or float data type.

Examples ...
uint{8} my_byte;
int{32} my_signed_number;
int{128} big_one;
float{128} f;
float{1024} not_yet;

.. etc ...

.. Additionally, native matrix support should be added.

E.g.
matrix34{64} m; // 3x4 matrix with 64 bit floating point scalar


// Example component access :-
m.(3,1) = 0.0;

.. again, the preprocessor could pick up some invalid accesses.

It is important to implement vector and matrix datatypes and operations


language to enable the compiler to acheive optimal parallelization. A


implementation is not the optimal solution here.

Comments welcome ...

- Steve.


Jan 12 2003
prev sibling parent "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Steve" <Steve_member pathlink.com> escreveu na mensagem
news:avrt3d$1f3v$1 digitaldaemon.com...
 Additionally, to complete the picture ...

 ivector2{32} v;  // A two dimensional vector consisting of two 32 bit

 integer components.

 uivector2{32} v;  // A two dimensional vector consisting of two 32 bit

 integer components.

 imatrix21{8}; // A 2x1 matrix, each component is an signed byte ...
 uimatrix21{16}; // A 2x1 matrix, each component is an unsigned 16 bit

 ..

 Remember, it is *very* important that these higher dimensional data types

 implementated within the language to enable the compiler to generate

 parallelized code on modern cpus ... Support for these features in the

 and a halfway decent compiler implementation would be reason enough to

 C++ to D.




 In article <avrruv$160s$1 digitaldaemon.com>, Steve says...
Here's the start to a general solution, feedback welcome ...

vector2{64} v;  // A two dimensional vector. Each component is 64 bits


// Example vector component access.
v.(0) = 1.0;
v.(1) = 1.0;

// A syntax error the preprocessor could pick up ...
v.(2) = 1.0;  // Syntax error - the vector is only two dimensional ...

Indirect access ...
uint{64} index = 1;

v.(index) = 1.0;



So, we can represent a 64 bit precision complex number as :-

vector2{64} c;

A quaternion ...

vector4{64} q;

A high precision location in 3 dimensional space ...
vector3{128} p;

.. etc ...

Taking this idea forwards, we can tidy up the whole mess of somebody


get out a thesaurus every time we need a wider int or float data type.

Examples ...
uint{8} my_byte;
int{32} my_signed_number;
int{128} big_one;
float{128} f;
float{1024} not_yet;

.. etc ...

.. Additionally, native matrix support should be added.

E.g.
matrix34{64} m; // 3x4 matrix with 64 bit floating point scalar


// Example component access :-
m.(3,1) = 0.0;

.. again, the preprocessor could pick up some invalid accesses.

It is important to implement vector and matrix datatypes and operations


language to enable the compiler to acheive optimal parallelization. A


implementation is not the optimal solution here.

Comments welcome ...

- Steve.


Hi, If we start defining multi-dimensional primitives in the languages, where do we stop. Vector and matrices are just two steps in generic tensors: we have scalars, vectors, matrices, tensors, just in the first 4 dimensions. Some people will need higher-order dimensions, with dimensional slices, strides, etc.. Also a quaternion isn't a vector4, because a vector4 can be used to represent a (x,y,z,t) position in a system, and this have different algebraic operations from a quaternion IIRC. There's more than one way to multiply a pair of vector3, it's context sensitive. Lot's of smart people spent man-years working on these problems and they usually don't agree with each other. If every D compiler developer is required to write code to deal with all these operations (hey I want everything defined in Blitz++ for my tensors) we'll have buggier compilers, hard to get semantics of types (how should matrices work with volatile access?) and less people interested in writing those. Just check the number of correct C++ compiler implementations versus the correct anything else compiler implementations. And C++ doesn't have all this types built-in. With standard libraries for these types (templatized classes/structs/whatever) with some basic implementations in D source code, we can develop and deploy faster. If you need a faster implementation, your compiler provider can make these standard types built-in as it's unique selling point. Best regards, Daniel Yokomiso. "Sanity is the playground for the unimaginative." --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.435 / Virus Database: 244 - Release Date: 31/12/2002
Jan 12 2003
prev sibling parent "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Sean L. Palmer" <seanpalmer directvinternet.com> escreveu na mensagem
news:avro2k$v0m$1 digitaldaemon.com...
 Type complex is really just an array of two real numbers with some
 overloaded operators attached.

 That can be done in the library, or should be able to be.  ;)

 Complex numbers are just the tip of the iceberg.  Are you going to add
 quaternions, octonions, etc?

 Even complex should have variants matching the available machine floating
 point precisions.

 Sean

 "Walter" <walter digitalmars.com> wrote in message
 news:avqr6s$2l66$1 digitaldaemon.com...
 "Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
 news:avkgcl$20i4$1 digitaldaemon.com...
 That's not a very good reason to add something to a language spec.



 it
 makes sense to add it to DMD, but not D necessarily.

The good reason is for it to be an upgrade from C. One design goal of D


 to not take away any C features without a really strong reason. I also
 happened to like type complex <g>.


Hi, Complex numbers *may* be represented as an array of two real numbers with overloaded operators attached, but they carry their own semantics baggage. I don't always want to store a complex number as an real/imaginary pair, sometimes it's better to store it as an radius/theta pair. Cartesian form is better for addition and subtraction, but multiplication, division, power and roots are faster when done in polar form. If I write: complex res = 0; for (int i = 0; i < values.length; i++) { res *= values[i]; } I don't to have lot's of extraneous operations needed to make all the multiplications in cartesian form. So I would require a complex(cartesian) or complex(polar) types for my specific usages (in this case values would contain complex(polar) numbers). Quaternions and octonions are other types that should be carefully defined. I don't think we should have all these built-in the language. IMO D may provide us a better way to write these as libraries without loss of efficiency or expressiveness. Best regards, Daniel Yokomiso. "Sodium and Chloride are both dangerous to humans. Therefore any combination of sodium and chloride will be dangerous to humans." --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.435 / Virus Database: 244 - Release Date: 30/12/2002
Jan 12 2003