76 lines
2.2 KiB
D
76 lines
2.2 KiB
D
import std.stdio, std.string, std.math, std.array, std.algorithm;
|
|
|
|
struct SquareMat(T = creal) {
|
|
public static string fmt = "%8.3f";
|
|
private alias TM = T[][];
|
|
private TM a;
|
|
|
|
public this(in size_t side) pure nothrow @safe
|
|
in {
|
|
assert(side > 0);
|
|
} body {
|
|
a = new TM(side, side);
|
|
}
|
|
|
|
public this(in TM m) pure nothrow @safe
|
|
in {
|
|
assert(!m.empty);
|
|
assert(m.all!(row => row.length == m.length)); // Is square.
|
|
} body {
|
|
// 2D dup.
|
|
a.length = m.length;
|
|
foreach (immutable i, const row; m)
|
|
a[i] = row.dup;
|
|
}
|
|
|
|
string toString() const @safe {
|
|
return format("<%(%(" ~ fmt ~ ", %)\n %)>", a);
|
|
}
|
|
|
|
public static SquareMat identity(in size_t side) pure nothrow @safe {
|
|
auto m = SquareMat(side);
|
|
foreach (immutable r, ref row; m.a)
|
|
foreach (immutable c; 0 .. side)
|
|
row[c] = (r == c) ? 1+0i : 0+0i;
|
|
return m;
|
|
}
|
|
|
|
public SquareMat opBinary(string op:"*")(in SquareMat other)
|
|
const pure nothrow @safe in {
|
|
assert (a.length == other.a.length);
|
|
} body {
|
|
immutable side = other.a.length;
|
|
auto d = SquareMat(side);
|
|
foreach (immutable r; 0 .. side)
|
|
foreach (immutable c; 0 .. side) {
|
|
d.a[r][c] = 0+0i;
|
|
foreach (immutable k, immutable ark; a[r])
|
|
d.a[r][c] += ark * other.a[k][c];
|
|
}
|
|
return d;
|
|
}
|
|
|
|
public SquareMat opBinary(string op:"^^")(int n) // The task part.
|
|
const pure nothrow @safe in {
|
|
assert(n >= 0, "Negative exponent not implemented.");
|
|
} body {
|
|
auto sq = SquareMat(this.a);
|
|
auto d = SquareMat.identity(a.length);
|
|
for (; n > 0; sq = sq * sq, n >>= 1)
|
|
if (n & 1)
|
|
d = d * sq;
|
|
return d;
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
alias M = SquareMat!();
|
|
enum real q = 0.5.sqrt;
|
|
immutable m = M([[ q + 0*1.0Li, q + 0*1.0Li, 0.0L + 0.0Li],
|
|
[0.0L - q*1.0Li, 0.0L + q*1.0Li, 0.0L + 0.0Li],
|
|
[0.0L + 0.0Li, 0.0L + 0.0Li, 0.0L + 1.0Li]]);
|
|
M.fmt = "%5.2f";
|
|
foreach (immutable p; [0, 1, 23, 24])
|
|
writefln("m ^^ %d =\n%s", p, m ^^ p);
|
|
}
|