Fixing the imaginary/complex mess
bearophile
bearophileHUGS at lycos.com
Sun Jun 12 15:37:37 PDT 2011
Andrei:
> Don, instead of this fix, could be at best phase everything built-in
> about complex out?
Two usages of complex numbers in the RosettaCode site.
Acommon place where you find complex numbers is to plot Mandelbrot/Julia sets:
http://rosettacode.org/wiki/Mandelbrot_set#D
import std.stdio, std.math;
void main() {
enum maxIter = 1000;
foreach (y; -39 .. 39) {
foreach (x; -39 .. 39) {
auto c = y/40.0 - 0.5 + x/40.0i,
z = 0.0 + 0.0i,
i = 0;
for (; i < maxIter && abs(z) < 4; i++)
z = z ^^ 2 + c;
write(i == maxIter ? '#' : ' ');
}
writeln();
}
}
Version using std.complex:
import std.stdio, std.complex;
void main() {
enum maxIter = 1000;
foreach (y; -39 .. 39) {
foreach (x; -39 .. 39) {
auto c = Complex!double(y/40.0 - 0.5, x/40.0),
z = Complex!double(0, 0),
i = 0;
for (; i < maxIter && z.abs() < 4; i++)
z = z ^^ 2 + c;
write(i == maxIter ? '#' : ' ');
}
writeln();
}
}
I think it's worth adding to std.complex module few examples of usage, plus a complex() function so you are allowed to write (the imaginary part defaults to zero if the real part is set to zero):
auto z = complex(5);
Instead of:
auto z = Complex!double(5, 0);
complex(5) probably has to create a Complex!double and not a Complex!int (that is not even supported, std.complex.Complex support floating point values only).
---------------------------
Another common usage of D complex numbers is to represent generic 2D points.
http://rosettacode.org/wiki/Constrained_random_points_on_a_circle#D
Original code (to plot some points in a circle):
import std.stdio, std.random, std.math;
void main() {
char[31][31] table = ' ';
foreach (i; 0 .. 100) {
int x, y;
do {
x = uniform(-15, 16);
y = uniform(-15, 16);
} while(abs(12.5 - abs(x + y * 1i)) > 2.5);
table[x + 15][y + 15] = '*';
}
foreach (row; table)
writeln(row);
}
Version using std.complex:
import std.stdio, std.random, std.complex, std.math;
void main() {
char[31][31] table = ' ';
foreach (i; 0 .. 100) {
int x, y;
do {
x = uniform(-15, 16);
y = uniform(-15, 16);
} while(abs(12.5 - Complex!double(x, y).abs) > 2.5);
table[x + 15][y + 15] = '*';
}
foreach (row; table)
writeln(row);
}
---------------------------
Regarding the printing of Complex values, this program:
import std.stdio, std.complex;
void main() {
writeln(Complex!double(0, -1));
}
Prints:
0-1i
While Python prints the same complex number as:
>>> 0-1j
-1j
Bye,
bearophile
More information about the Digitalmars-d
mailing list