Jump to page: 1 2
Thread overview
Complex numbers are harder to use than in C
Nov 19, 2016
Marduk
Nov 19, 2016
Nordlöw
Nov 19, 2016
Marc Schütz
Nov 19, 2016
Marduk
Nov 20, 2016
Marc Schütz
Nov 19, 2016
Marduk
Nov 20, 2016
Marc Schütz
Nov 22, 2016
Marduk
Nov 19, 2016
Meta
Nov 19, 2016
Marduk
Nov 20, 2016
Ilya Yaroshenko
Nov 22, 2016
Marduk
November 19, 2016
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?
November 19, 2016
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;
}
November 19, 2016
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;
November 19, 2016
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]];
November 19, 2016
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.
November 19, 2016
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'.
November 19, 2016
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).
November 20, 2016
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."
November 20, 2016
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.
November 20, 2016
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
« First   ‹ Prev
1 2