www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Complex numbers are harder to use than in C

reply Marduk <mardukbp mac.com> writes:
Dear all,

I just discovered D and I am translating some numerical code I 
wrote in C. I was surprised to learn that there are at least two 
things that are easier in C than in D:

+ Writing complex numbers

C: complex double z = 2.0 + 3.0*I;

D: auto z = complex(2.0, 3.0);


+ Arrays of complex numbers

C: complex double a[2][2] = {{1.0*I, 0.0}, {0.0, 1.0*I}};

D: Complex!double[2][2] a = [[complex(0.0, 1.0), complex(0.0)], 
[complex(0.0), complex(0.0, 1.0)]];

The difference is that D is more verbose. Am I missing something? 
Can we have C's behaviour in D?
Nov 19 2016
next sibling parent reply =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Saturday, 19 November 2016 at 09:38:38 UTC, Marduk wrote:
 The difference is that D is more verbose. Am I missing 
 something? Can we have C's behaviour in D?
Something like auto I(T)(T im) if (isNumeric!T) { return complex(0, im); } unittest { auto x = 1 + 2.I; }
Nov 19 2016
next sibling parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Saturday, 19 November 2016 at 11:11:36 UTC, Nordlöw wrote:
 On Saturday, 19 November 2016 at 09:38:38 UTC, Marduk wrote:
 The difference is that D is more verbose. Am I missing 
 something? Can we have C's behaviour in D?
Something like auto I(T)(T im) if (isNumeric!T) { return complex(0, im); } unittest { auto x = 1 + 2.I; }
Or simply: enum I = complex(0, 1); auto x = 1 + 2*I;
Nov 19 2016
parent reply Marduk <mardukbp mac.com> writes:
On Saturday, 19 November 2016 at 12:55:57 UTC, Marc Schütz wrote:
 On Saturday, 19 November 2016 at 11:11:36 UTC, Nordlöw wrote:
 On Saturday, 19 November 2016 at 09:38:38 UTC, Marduk wrote:
 The difference is that D is more verbose. Am I missing 
 something? Can we have C's behaviour in D?
Something like auto I(T)(T im) if (isNumeric!T) { return complex(0, im); } unittest { auto x = 1 + 2.I; }
Or simply: enum I = complex(0, 1); auto x = 1 + 2*I;
Thanks! That's a clever idea. What I do not understand is why if I declare the array with Complex!double I need to complexify each entry. I would expect that D automatically casts 0.0 to complex(0.0).
Nov 19 2016
parent Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Saturday, 19 November 2016 at 20:24:09 UTC, Marduk wrote:
 On Saturday, 19 November 2016 at 12:55:57 UTC, Marc Schütz 
 wrote:
 On Saturday, 19 November 2016 at 11:11:36 UTC, Nordlöw wrote:
 On Saturday, 19 November 2016 at 09:38:38 UTC, Marduk wrote:
 The difference is that D is more verbose. Am I missing 
 something? Can we have C's behaviour in D?
Something like auto I(T)(T im) if (isNumeric!T) { return complex(0, im); } unittest { auto x = 1 + 2.I; }
Or simply: enum I = complex(0, 1); auto x = 1 + 2*I;
Thanks! That's a clever idea. What I do not understand is why if I declare the array with Complex!double I need to complexify each entry. I would expect that D automatically casts 0.0 to complex(0.0).
I agree, this is unfortunate. I don't know of any reason why the following couldn't work in principle: Complex!float[] arr = [1.0, 2.0, 3.0, 4.0]; // or even auto arr = [1+2*I, 2.0, 3.0, 4.0]; // compiler finds common type // just like it works for auto arr = [1, 2, 3.0, 4]; // typeof(arr) is double[] I believe it was a conscious decision. D doesn't do as many implicit type conversion as C++, because they often make it hard to understand what's going on. In the above examples though, IMO it wouldn't be a problem.
Nov 20 2016
prev sibling parent reply Marduk <mardukbp mac.com> writes:
On Saturday, 19 November 2016 at 11:11:36 UTC, Nordlöw wrote:
 On Saturday, 19 November 2016 at 09:38:38 UTC, Marduk wrote:
 The difference is that D is more verbose. Am I missing 
 something? Can we have C's behaviour in D?
Something like auto I(T)(T im) if (isNumeric!T) { return complex(0, im); } unittest { auto x = 1 + 2.I; }
Nice. But I am unsure of how to use this. I just pasted the definition of I inside the main function of my program followed by auto x = 1 + 2.I; and the compiler complained with Error: no property 'I' for type 'int'.
Nov 19 2016
parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Saturday, 19 November 2016 at 20:08:42 UTC, Marduk wrote:
 On Saturday, 19 November 2016 at 11:11:36 UTC, Nordlöw wrote:
 On Saturday, 19 November 2016 at 09:38:38 UTC, Marduk wrote:
 The difference is that D is more verbose. Am I missing 
 something? Can we have C's behaviour in D?
Something like auto I(T)(T im) if (isNumeric!T) { return complex(0, im); } unittest { auto x = 1 + 2.I; }
Nice. But I am unsure of how to use this. I just pasted the definition of I inside the main function of my program followed by auto x = 1 + 2.I; and the compiler complained with Error: no property 'I' for type 'int'.
Try placing it outside the function. Method call syntax doesn't work with nested functions, see here: https://dlang.org/spec/function.html#pseudo-member "The reason why local symbols are not considered by UFCS, is to avoid unexpected name conflicts."
Nov 20 2016
parent Marduk <mardukbp mac.com> writes:
On Sunday, 20 November 2016 at 11:46:04 UTC, Marc Schütz wrote:

 Try placing it outside the function. Method call syntax doesn't 
 work with nested functions, see here:

 https://dlang.org/spec/function.html#pseudo-member

 "The reason why local symbols are not considered by UFCS, is to 
 avoid unexpected name conflicts."
Aha! Now it works. Thank you for the explanation.
Nov 22 2016
prev sibling parent reply Meta <jared771 gmail.com> writes:
On Saturday, 19 November 2016 at 09:38:38 UTC, Marduk wrote:
 Dear all,

 I just discovered D and I am translating some numerical code I 
 wrote in C. I was surprised to learn that there are at least 
 two things that are easier in C than in D:

 + Writing complex numbers

 C: complex double z = 2.0 + 3.0*I;

 D: auto z = complex(2.0, 3.0);


 + Arrays of complex numbers

 C: complex double a[2][2] = {{1.0*I, 0.0}, {0.0, 1.0*I}};

 D: Complex!double[2][2] a = [[complex(0.0, 1.0), complex(0.0)], 
 [complex(0.0), complex(0.0, 1.0)]];

 The difference is that D is more verbose. Am I missing 
 something? Can we have C's behaviour in D?
D used to support complex numbers in the language (actually it still does, they're just deprecated). This code should compile with any D compiler: cdouble[2][2] a = [[0 + 1i, 0], [0, 0 + 1i]];
Nov 19 2016
parent reply Marduk <mardukbp mac.com> writes:
On Saturday, 19 November 2016 at 16:17:08 UTC, Meta wrote:
 On Saturday, 19 November 2016 at 09:38:38 UTC, Marduk wrote:
 Dear all,

 I just discovered D and I am translating some numerical code I 
 wrote in C. I was surprised to learn that there are at least 
 two things that are easier in C than in D:

 + Writing complex numbers

 C: complex double z = 2.0 + 3.0*I;

 D: auto z = complex(2.0, 3.0);


 + Arrays of complex numbers

 C: complex double a[2][2] = {{1.0*I, 0.0}, {0.0, 1.0*I}};

 D: Complex!double[2][2] a = [[complex(0.0, 1.0), 
 complex(0.0)], [complex(0.0), complex(0.0, 1.0)]];

 The difference is that D is more verbose. Am I missing 
 something? Can we have C's behaviour in D?
D used to support complex numbers in the language (actually it still does, they're just deprecated). This code should compile with any D compiler: cdouble[2][2] a = [[0 + 1i, 0], [0, 0 + 1i]];
Thank you! However, I am concerned that if this is deprecated, then I should not use it (it is not future-proof). I wonder why D dropped this syntax for complex numbers. It is very handy.
Nov 19 2016
parent reply Ilya Yaroshenko <ilyayaroshenko gmail.com> writes:
On Saturday, 19 November 2016 at 19:42:27 UTC, Marduk wrote:
 On Saturday, 19 November 2016 at 16:17:08 UTC, Meta wrote:
 On Saturday, 19 November 2016 at 09:38:38 UTC, Marduk wrote:
 [...]
D used to support complex numbers in the language (actually it still does, they're just deprecated). This code should compile with any D compiler: cdouble[2][2] a = [[0 + 1i, 0], [0, 0 + 1i]];
Thank you! However, I am concerned that if this is deprecated, then I should not use it (it is not future-proof). I wonder why D dropped this syntax for complex numbers. It is very handy.
You can use builtin complex numbers (cfloat/cdouble/creal). The idea of std.complex is wrong . Mir GLAS uses builtin complex numbers and I don't think they will be really deprecated. --Ilya
Nov 20 2016
parent Marduk <mardukbp mac.com> writes:
On Sunday, 20 November 2016 at 12:08:23 UTC, Ilya Yaroshenko 
wrote:

 You can use builtin complex numbers (cfloat/cdouble/creal). The 
 idea of std.complex is wrong . Mir GLAS uses builtin complex 
 numbers and I don't think they will be really deprecated. --Ilya
Good to know! The builtin syntax is more reasonable than std.complex.
Nov 22 2016