Merhaba,
Bilmiyorum, tıpkı std.complex gibi matrislerde işlem yapabilmek için bir modül var mı?
Konumuz dışı ama kompleks sayılar örneğin şöyle:
import std.complex;
auto a = complex(1.0, 2.0);
auto b = pow(a, 2);
auto aÇARPIb = a * b;
// Çünkü eşittir a'nın kübüne:
assert(aÇARPIb == pow(a, 3));
Ama Ali Çehreli'nin kitabındaki, Ayrıntılı Şablonlar bölümünün sonundaki Matris örneği harikulade: http://www.ddili.org/ders/d/sablonlar_ayrintili.html
Biraz ekleme yaptım ve bir örnek (soru1) çözdüm de çalışıyor! Tabi matrislerde çarpma için biraz daha emek gerek :)
import std.stdio;
import std.format;
import std.string;
struct Matris(T) {
alias m = satırlar;
T[][] satırlar;
/* İndekslerle belirlenen satır ve sütun aralığı
* bilgisini bir araya getirir.
*/
struct Aralık { size_t baş, son; }
/* Satır ve sütun aralıklarıyla belirlenen
* alt matrisi döndürür.
*/
auto altMatris(Aralık satırAralığı, Aralık sütunAralığı) {
T[][] dilimler;
foreach (d; m[satırAralığı.baş .. satırAralığı.son]) {
dilimler ~= d[sütunAralığı.baş .. sütunAralığı.son];
}
return Matris(dilimler);
}
this(size_t yükseklik, size_t genişlik) {
/* S.Dinçer gizledi
* writeln(__FUNCTION__);
*/
this.m = new T[][](yükseklik, genişlik);
}
/* S.Dinçer ekledi */
auto opOpAssign(string op) (Matris yeniMatris) if(op == "+") {
foreach (x, satır; yeniMatris.m) {
foreach (y, sütun; satır) {
this.m[x][y] += sütun;
// writefln("%d, %d: %d", x, y, sütun);
}
}
return this;
}
/* S.Dinçer ekledi */
auto opOpAssign(string op) (Matris yeniMatris) if(op == "-") {
foreach (x, satır; yeniMatris.m) {
foreach (y, sütun; satır) {
this.m[x][y] -= sütun;
// writefln("%d, %d: %d", x, y, sütun);
}
}
return this;
}
/* Farklı boyutlardaki, örneğin 2x3 ile 3x2
* matrisleri matematikte satır/sütun ilişkisi
* çerçevesinde işlem yapılır ve sonuç 2x2'dir.
* Şimdilik ertelendi...
auto opOpAssign(string op) (Matris yeniMatris) if(op == "*") {
return this;
}
/* S.Dinçer ekledi */
auto opOpAssign(string op) (T n) if(op=="+") {
foreach(x; m) x[] += n;
return this;
}
/* S.Dinçer ekledi */
auto opOpAssign(string op) (T n) if(op=="-") {
foreach(x; m) x[] -= n;
return this;
}
/* S.Dinçer ekledi */
auto opOpAssign(string op) (T n) if(op=="*") {
foreach(x; m) x[] *= n;
return this;
}
/* S.Dinçer ekledi */
auto opOpAssign(string op) (T n) if(op=="/") {
foreach(x; m) x[] /= n;
return this;
}
/* S.Dinçer ekledi */
this(T[][] satırlar) {
this.m = satırlar;
}
void toString(void delegate(const(char)[]) hedef) const {
hedef.formattedWrite!"%(%(%5s %)\n%)"(m);
hedef.formattedWrite!"\n";
}
auto opAssign(T değer) {
foreach (satır; m) satır[] = değer;
return this;
}
size_t opDollar(size_t boyut)() const
if (boyut <= 1) {
static if (boyut == 0) {
return m.length;
} else {
return m.length ? m[0].length : 0;
}
}
auto opSlice(size_t boyut) (size_t baş, size_t son) if (boyut <= 1) {
return Aralık(baş, son);
}
auto opIndex(A...) (A param)if (A.length <= 2) {
Aralık[2] aralık = [ Aralık(0, opDollar!0),
Aralık(0, opDollar!1) ];
foreach (boyut, p; param) {
static if (is (typeof(p) == Aralık)) {
aralık[boyut] = p;
} else static if (is (typeof(p) : size_t)) {
aralık[boyut] = Aralık(p, p + 1);
} else {
static assert(
false, format("Geçersiz indeks türü: %s",
typeof(p).stringof)
);
}
/* S.Dinçer gizledi
* boyut.writeln("< boyut / aralıkla, >", aralık);
*/
}
return altMatris(aralık[0], aralık[1]);
}
auto opIndexAssign(A...)(T değer, A param) if (A.length <= 2) {
Matris altMatris = opIndex(param);
return altMatris = değer;
}
}
struct ikiliDenklem (T) {
Matris!T x, y;
string d1, d2;
this(size_t yükseklik, size_t genişlik) {
x = Matris!T(3, 3);
y = Matris!T(3, 3);
}
void terim1(string terim, T[][] matris) {
x += Matris!T(matris);
d1 = terim;
}
void terim2(string terim, T[][] matris) {
y += Matris!T(matris);
d2 = terim;
}
void toString(void delegate(const(char)[]) hedef) const {
hedef.formattedWrite!"%s =\n%(%(%5s %)\n%)"(d1, x.m);
hedef.formattedWrite!"\n";
hedef.formattedWrite!"%s =\n%(%(%5s %)\n%)"(d2, y.m);
hedef.formattedWrite!"\n";
}
}
void main() {
int[][] AartıB = [[3, 4, 9],
[7, 3, 7],
[4, 9, 6]];
int[][] ikiAeksidörtB = [[0, 2, 6],
[8, 6, 8],
[8, 6, 6]];
/* A + B = [...] ve 2A - 4B = [...]
* ise B matrisini bulunuz:
*/
auto soru1 = ikiliDenklem!int(3, 3);
soru1.terim1 ("A + B", AartıB.dup);
soru1.terim2 ("2A - 4B", ikiAeksidörtB.dup);
//++soru1.x;
soru1.writeln; // Denklemleri yazar...
with(soru1) {
"ÇÖZÜM:".writeln;
x *= 2; // Matrisi 2 ile genişletiyoruz,
y *= -1; // Tüm matris eksili oluyor...
y += x; // Toplamları y matrisinde
x /= 2; // x eski halinde: A+B matrisi
y.writeln("__________________");
writeln("[2(A+B) -1(2A-4B)]/6\nB =");
y /= 6; // Çözüm kümesi 6B olduğundan,
y.writeln; // B'nin sonucu: M/6
"A =".writeln;
x -= y;
x.writeln;
}
}/* ÇIKTISI:
A + B =
3 4 9
7 3 7
4 9 6
2A - 4B =
0 2 6
8 6 8
8 6 6
ÇÖZÜM:
6 6 12
6 0 6
0 12 6
__________________
[2(A+B) -1(2A-4B)]/6
B =
1 1 2
1 0 1
0 2 1
A =
2 3 7
6 3 6
4 7 5
*/
Başarılar...