Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
69
Task/Gaussian-elimination/D/gaussian-elimination.d
Normal file
69
Task/Gaussian-elimination/D/gaussian-elimination.d
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import std.stdio, std.math, std.algorithm, std.range, std.numeric,
|
||||
std.typecons;
|
||||
|
||||
Tuple!(double[],"x", string,"err")
|
||||
gaussPartial(in double[][] a0, in double[] b0) pure /*nothrow*/
|
||||
in {
|
||||
assert(a0.length == a0[0].length);
|
||||
assert(a0.length == b0.length);
|
||||
assert(a0.all!(row => row.length == a0[0].length));
|
||||
} body {
|
||||
enum eps = 1e-6;
|
||||
immutable m = b0.length;
|
||||
|
||||
// Make augmented matrix.
|
||||
//auto a = a0.zip(b0).map!(c => c[0] ~ c[1]).array; // Not mutable.
|
||||
auto a = a0.zip(b0).map!(c => [] ~ c[0] ~ c[1]).array;
|
||||
|
||||
// Wikipedia algorithm from Gaussian elimination page,
|
||||
// produces row-eschelon form.
|
||||
foreach (immutable k; 0 .. a.length) {
|
||||
// Find pivot for column k and swap.
|
||||
a[k .. m].minPos!((x, y) => x[k] > y[k]).front.swap(a[k]);
|
||||
if (a[k][k].abs < eps)
|
||||
return typeof(return)(null, "singular");
|
||||
|
||||
// Do for all rows below pivot.
|
||||
foreach (immutable i; k + 1 .. m) {
|
||||
// Do for all remaining elements in current row.
|
||||
a[i][k+1 .. m+1] -= a[k][k+1 .. m+1] * (a[i][k] / a[k][k]);
|
||||
|
||||
a[i][k] = 0; // Fill lower triangular matrix with zeros.
|
||||
}
|
||||
}
|
||||
|
||||
// End of WP algorithm. Now back substitute to get result.
|
||||
auto x = new double[m];
|
||||
foreach_reverse (immutable i; 0 .. m)
|
||||
x[i] = (a[i][m] - a[i][i+1 .. m].dotProduct(x[i+1 .. m])) / a[i][i];
|
||||
|
||||
return typeof(return)(x, null);
|
||||
}
|
||||
|
||||
void main() {
|
||||
// The test case result is correct to this tolerance.
|
||||
enum eps = 1e-13;
|
||||
|
||||
// Common RC example. Result computed with rational arithmetic
|
||||
// then converted to double, and so should be about as close to
|
||||
// correct as double represention allows.
|
||||
immutable a = [[1.00, 0.00, 0.00, 0.00, 0.00, 0.00],
|
||||
[1.00, 0.63, 0.39, 0.25, 0.16, 0.10],
|
||||
[1.00, 1.26, 1.58, 1.98, 2.49, 3.13],
|
||||
[1.00, 1.88, 3.55, 6.70, 12.62, 23.80],
|
||||
[1.00, 2.51, 6.32, 15.88, 39.90, 100.28],
|
||||
[1.00, 3.14, 9.87, 31.01, 97.41, 306.02]];
|
||||
immutable b = [-0.01, 0.61, 0.91, 0.99, 0.60, 0.02];
|
||||
|
||||
immutable r = gaussPartial(a, b);
|
||||
if (!r.err.empty)
|
||||
return writeln("Error: ", r.err);
|
||||
r.x.writeln;
|
||||
|
||||
immutable result = [-0.01, 1.602790394502114,
|
||||
-1.6132030599055613, 1.2454941213714368,
|
||||
-0.4909897195846576, 0.065760696175232];
|
||||
foreach (immutable i, immutable xi; result)
|
||||
if (abs(r.x[i] - xi) > eps)
|
||||
return writeln("Out of tolerance: ", r.x[i], " ", xi);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue