Cramer's rule: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) (Rename Perl 6 -> Raku, alphabetize, minor clean-up) |
|||
Line 288: | Line 288: | ||
-4.000 |
-4.000 |
||
1.000</pre> |
1.000</pre> |
||
=={{header|C sharp}}== |
|||
Instead of copying a bunch of arrays, I made a class with an indexer that simply accesses the correct items in the original matrix. |
|||
<lang csharp>using System; |
|||
using System.Collections.Generic; |
|||
using static System.Linq.Enumerable; |
|||
public static class CramersRule |
|||
{ |
|||
public static void Main() { |
|||
var equations = new [] { |
|||
new [] { 2, -1, 5, 1, -3 }, |
|||
new [] { 3, 2, 2, -6, -32 }, |
|||
new [] { 1, 3, 3, -1, -47 }, |
|||
new [] { 5, -2, -3, 3, 49 } |
|||
}; |
|||
var solution = SolveCramer(equations); |
|||
Console.WriteLine(solution.DelimitWith(", ")); |
|||
} |
|||
public static int[] SolveCramer(int[][] equations) { |
|||
int size = equations.Length; |
|||
if (equations.Any(eq => eq.Length != size + 1)) throw new ArgumentException($"Each equation must have {size+1} terms."); |
|||
int[,] matrix = new int[size, size]; |
|||
int[] column = new int[size]; |
|||
for (int r = 0; r < size; r++) { |
|||
column[r] = equations[r][size]; |
|||
for (int c = 0; c < size; c++) { |
|||
matrix[r, c] = equations[r][c]; |
|||
} |
|||
} |
|||
return Solve(new SubMatrix(matrix, column)); |
|||
} |
|||
private static int[] Solve(SubMatrix matrix) { |
|||
int det = matrix.Det(); |
|||
if (det == 0) throw new ArgumentException("The determinant is zero."); |
|||
int[] answer = new int[matrix.Size]; |
|||
for (int i = 0; i < matrix.Size; i++) { |
|||
matrix.ColumnIndex = i; |
|||
answer[i] = matrix.Det() / det; |
|||
} |
|||
return answer; |
|||
} |
|||
//Extension method from library. |
|||
static string DelimitWith<T>(this IEnumerable<T> source, string separator = " ") => |
|||
string.Join(separator ?? " ", source ?? Empty<T>()); |
|||
private class SubMatrix |
|||
{ |
|||
private int[,] source; |
|||
private SubMatrix prev; |
|||
private int[] replaceColumn; |
|||
public SubMatrix(int[,] source, int[] replaceColumn) { |
|||
this.source = source; |
|||
this.replaceColumn = replaceColumn; |
|||
this.prev = null; |
|||
this.ColumnIndex = -1; |
|||
Size = replaceColumn.Length; |
|||
} |
|||
private SubMatrix(SubMatrix prev, int deletedColumnIndex = -1) { |
|||
this.source = null; |
|||
this.prev = prev; |
|||
this.ColumnIndex = deletedColumnIndex; |
|||
Size = prev.Size - 1; |
|||
} |
|||
public int ColumnIndex { get; set; } |
|||
public int Size { get; } |
|||
public int this[int row, int column] { |
|||
get { |
|||
if (source != null) return column == ColumnIndex ? replaceColumn[row] : source[row, column]; |
|||
return prev[row + 1, column < ColumnIndex ? column : column + 1]; |
|||
} |
|||
} |
|||
public int Det() { |
|||
if (Size == 1) return this[0, 0]; |
|||
if (Size == 2) return this[0, 0] * this[1, 1] - this[0, 1] * this[1, 0]; |
|||
SubMatrix m = new SubMatrix(this); |
|||
int det = 0; |
|||
int sign = 1; |
|||
for (int c = 0; c < Size; c++) { |
|||
m.ColumnIndex = c; |
|||
int d = m.Det(); |
|||
det += this[0, c] * d * sign; |
|||
sign = -sign; |
|||
} |
|||
return det; |
|||
} |
|||
public void Print() { |
|||
for (int r = 0; r < Size; r++) { |
|||
Console.WriteLine(Range(0, Size).Select(c => this[r, c]).DelimitWith(", ")); |
|||
} |
|||
Console.WriteLine(); |
|||
} |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
2, -12, -4, 1 |
|||
</pre> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
Line 430: | Line 539: | ||
{{out}} |
{{out}} |
||
<pre>[2, -12, -4, 1]</pre> |
<pre>[2, -12, -4, 1]</pre> |
||
=={{header|C sharp}}== |
|||
Instead of copying a bunch of arrays, I made a class with an indexer that simply accesses the correct items in the original matrix. |
|||
<lang csharp>using System; |
|||
using System.Collections.Generic; |
|||
using static System.Linq.Enumerable; |
|||
public static class CramersRule |
|||
{ |
|||
public static void Main() { |
|||
var equations = new [] { |
|||
new [] { 2, -1, 5, 1, -3 }, |
|||
new [] { 3, 2, 2, -6, -32 }, |
|||
new [] { 1, 3, 3, -1, -47 }, |
|||
new [] { 5, -2, -3, 3, 49 } |
|||
}; |
|||
var solution = SolveCramer(equations); |
|||
Console.WriteLine(solution.DelimitWith(", ")); |
|||
} |
|||
public static int[] SolveCramer(int[][] equations) { |
|||
int size = equations.Length; |
|||
if (equations.Any(eq => eq.Length != size + 1)) throw new ArgumentException($"Each equation must have {size+1} terms."); |
|||
int[,] matrix = new int[size, size]; |
|||
int[] column = new int[size]; |
|||
for (int r = 0; r < size; r++) { |
|||
column[r] = equations[r][size]; |
|||
for (int c = 0; c < size; c++) { |
|||
matrix[r, c] = equations[r][c]; |
|||
} |
|||
} |
|||
return Solve(new SubMatrix(matrix, column)); |
|||
} |
|||
private static int[] Solve(SubMatrix matrix) { |
|||
int det = matrix.Det(); |
|||
if (det == 0) throw new ArgumentException("The determinant is zero."); |
|||
int[] answer = new int[matrix.Size]; |
|||
for (int i = 0; i < matrix.Size; i++) { |
|||
matrix.ColumnIndex = i; |
|||
answer[i] = matrix.Det() / det; |
|||
} |
|||
return answer; |
|||
} |
|||
//Extension method from library. |
|||
static string DelimitWith<T>(this IEnumerable<T> source, string separator = " ") => |
|||
string.Join(separator ?? " ", source ?? Empty<T>()); |
|||
private class SubMatrix |
|||
{ |
|||
private int[,] source; |
|||
private SubMatrix prev; |
|||
private int[] replaceColumn; |
|||
public SubMatrix(int[,] source, int[] replaceColumn) { |
|||
this.source = source; |
|||
this.replaceColumn = replaceColumn; |
|||
this.prev = null; |
|||
this.ColumnIndex = -1; |
|||
Size = replaceColumn.Length; |
|||
} |
|||
private SubMatrix(SubMatrix prev, int deletedColumnIndex = -1) { |
|||
this.source = null; |
|||
this.prev = prev; |
|||
this.ColumnIndex = deletedColumnIndex; |
|||
Size = prev.Size - 1; |
|||
} |
|||
public int ColumnIndex { get; set; } |
|||
public int Size { get; } |
|||
public int this[int row, int column] { |
|||
get { |
|||
if (source != null) return column == ColumnIndex ? replaceColumn[row] : source[row, column]; |
|||
return prev[row + 1, column < ColumnIndex ? column : column + 1]; |
|||
} |
|||
} |
|||
public int Det() { |
|||
if (Size == 1) return this[0, 0]; |
|||
if (Size == 2) return this[0, 0] * this[1, 1] - this[0, 1] * this[1, 0]; |
|||
SubMatrix m = new SubMatrix(this); |
|||
int det = 0; |
|||
int sign = 1; |
|||
for (int c = 0; c < Size; c++) { |
|||
m.ColumnIndex = c; |
|||
int d = m.Det(); |
|||
det += this[0, c] * d * sign; |
|||
sign = -sign; |
|||
} |
|||
return det; |
|||
} |
|||
public void Print() { |
|||
for (int r = 0; r < Size; r++) { |
|||
Console.WriteLine(Range(0, Size).Select(c => this[r, c]).DelimitWith(", ")); |
|||
} |
|||
Console.WriteLine(); |
|||
} |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
2, -12, -4, 1 |
|||
</pre> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Line 1,725: | Line 1,725: | ||
print "y = $y\n"; |
print "y = $y\n"; |
||
print "z = $z\n";</lang> |
print "z = $z\n";</lang> |
||
{{out}} |
|||
<pre> |
|||
w = 2 |
|||
x = -12 |
|||
y = -4 |
|||
z = 1 |
|||
</pre> |
|||
=={{header|Perl 6}}== |
|||
<lang perl6>sub det(@matrix) { |
|||
my @a = @matrix.map: { [|$_] }; |
|||
my $sign = +1; |
|||
my $pivot = 1; |
|||
for ^@a -> $k { |
|||
my @r = ($k+1 .. @a.end); |
|||
my $previous-pivot = $pivot; |
|||
if 0 == ($pivot = @a[$k][$k]) { |
|||
(my $s = @r.first: { @a[$_][$k] != 0 }) // return 0; |
|||
(@a[$s],@a[$k]) = (@a[$k], @a[$s]); |
|||
my $pivot = @a[$k][$k]; |
|||
$sign = -$sign; |
|||
} |
|||
for @r X @r -> ($i, $j) { |
|||
((@a[$i][$j] *= $pivot) -= @a[$i][$k]*@a[$k][$j]) /= $previous-pivot; |
|||
} |
|||
} |
|||
$sign * $pivot |
|||
} |
|||
sub cramers_rule(@A, @terms) { |
|||
gather for ^@A -> $i { |
|||
my @Ai = @A.map: { [|$_] }; |
|||
for ^@terms -> $j { |
|||
@Ai[$j][$i] = @terms[$j]; |
|||
} |
|||
take det(@Ai); |
|||
} »/» det(@A); |
|||
} |
|||
my @matrix = ( |
|||
[2, -1, 5, 1], |
|||
[3, 2, 2, -6], |
|||
[1, 3, 3, -1], |
|||
[5, -2, -3, 3], |
|||
); |
|||
my @free_terms = (-3, -32, -47, 49); |
|||
my ($w, $x, $y, $z) = |cramers_rule(@matrix, @free_terms); |
|||
say "w = $w"; |
|||
say "x = $x"; |
|||
say "y = $y"; |
|||
say "z = $z";</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,968: | Line 1,915: | ||
<pre>'#(2 -12 -4 1)</pre> |
<pre>'#(2 -12 -4 1)</pre> |
||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
<lang perl6>sub det(@matrix) { |
|||
my @a = @matrix.map: { [|$_] }; |
|||
my $sign = +1; |
|||
my $pivot = 1; |
|||
for ^@a -> $k { |
|||
my @r = ($k+1 .. @a.end); |
|||
my $previous-pivot = $pivot; |
|||
if 0 == ($pivot = @a[$k][$k]) { |
|||
(my $s = @r.first: { @a[$_][$k] != 0 }) // return 0; |
|||
(@a[$s],@a[$k]) = (@a[$k], @a[$s]); |
|||
my $pivot = @a[$k][$k]; |
|||
$sign = -$sign; |
|||
} |
|||
for @r X @r -> ($i, $j) { |
|||
((@a[$i][$j] *= $pivot) -= @a[$i][$k]*@a[$k][$j]) /= $previous-pivot; |
|||
} |
|||
} |
|||
$sign * $pivot |
|||
} |
|||
sub cramers_rule(@A, @terms) { |
|||
gather for ^@A -> $i { |
|||
my @Ai = @A.map: { [|$_] }; |
|||
for ^@terms -> $j { |
|||
@Ai[$j][$i] = @terms[$j]; |
|||
} |
|||
take det(@Ai); |
|||
} »/» det(@A); |
|||
} |
|||
my @matrix = ( |
|||
[2, -1, 5, 1], |
|||
[3, 2, 2, -6], |
|||
[1, 3, 3, -1], |
|||
[5, -2, -3, 3], |
|||
); |
|||
my @free_terms = (-3, -32, -47, 49); |
|||
my ($w, $x, $y, $z) = |cramers_rule(@matrix, @free_terms); |
|||
say "w = $w"; |
|||
say "x = $x"; |
|||
say "y = $y"; |
|||
say "z = $z";</lang> |
|||
{{out}} |
|||
<pre> |
|||
w = 2 |
|||
x = -12 |
|||
y = -4 |
|||
z = 1 |
|||
</pre> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |