langs a-z

This commit is contained in:
Ingy döt Net 2013-04-10 22:43:41 -07:00
parent db842d013d
commit d066446780
11389 changed files with 98361 additions and 1020 deletions

View file

@ -0,0 +1,58 @@
(* identity matrix *)
let eye n =
let a = Array.make_matrix n n 0.0 in
for i=0 to n-1 do
a.(i).(i) <- 1.0
done;
(a)
;;
(* matrix dimensions *)
let dim a = Array.length a, Array.length a.(0);;
(* make matrix from list in row-major order *)
let matrix p q v =
if (List.length v) <> (p * q)
then failwith "bad dimensions"
else
let a = Array.make_matrix p q (List.hd v) in
let rec g i j = function
| [] -> a
| x::v ->
a.(i).(j) <- x;
if j+1 < q
then g i (j+1) v
else g (i+1) 0 v
in
g 0 0 v
;;
(* matrix product *)
let matmul a b =
let n, p = dim a
and q, r = dim b in
if p <> q then failwith "bad dimensions" else
let c = Array.make_matrix n r 0.0 in
for i=0 to n-1 do
for j=0 to r-1 do
for k=0 to p-1 do
c.(i).(j) <- c.(i).(j) +. a.(i).(k) *. b.(k).(j)
done
done
done;
(c)
;;
(* generic exponentiation, usual algorithm *)
let pow one mul a n =
let rec g p x = function
| 0 -> x
| i ->
g (mul p p) (if i mod 2 = 1 then mul p x else x) (i/2)
in
g a one n
;;
(* example with integers *)
pow 1 ( * ) 2 16;;
(* - : int = 65536 *)

View file

@ -0,0 +1,13 @@
let matpow a n =
let p, q = dim a in
if p <> q then failwith "bad dimensions" else
pow (eye p) matmul a n;;
matpow (matrix 2 2 [ 1.0; 1.0; 1.0; 0.0 ]) 10;;
(* - : float array array = [|[|89.; 55.|]; [|55.; 34.|]|] *)
(* use as infix operator *)
let ( ^^ ) = matpow;;
[| [| 1.0; 1.0|]; [| 1.0; 0.0 |] |] ^^ 10;;
(* - : float array array = [|[|89.; 55.|]; [|55.; 34.|]|] *)

View file

@ -0,0 +1,6 @@
M = [ 3, 2; 2, 1 ];
M^0
M^1
M^2
M^(-1)
M^0.5

View file

@ -0,0 +1,36 @@
subset SqMat of Array where { .elems == all(.[]».elems) }
multi infix:<*>(SqMat $a, SqMat $b) {[
for ^$a -> $r {[
for ^$b[0] -> $c {
[+] ($a[$r][] Z* $b[].map: *[$c])
}
]}
]}
multi infix:<**> (SqMat $m, Int $n is copy where { $_ >= 0 }) {
my $tmp = $m;
my $out = [for ^$m -> $i { [ for ^$m -> $j { +($i == $j) } ] } ];
loop {
$out = $out * $tmp if $n +& 1;
last unless $n +>= 1;
$tmp = $tmp * $tmp;
}
$out;
}
multi show (SqMat $m) {
my $size = 1;
for ^$m X ^$m -> $i, $j { $size max= $m[$i][$j].Str.chars; }
say join "\n", $m».fmt("%{$size}s");
}
my @m = [1, 2, 0],
[0, 3, 1],
[1, 0, 0];
for 0 .. 10 -> $order {
say "### Order $order";
show @m ** $order;
}

View file

@ -0,0 +1,92 @@
$ include "seed7_05.s7i";
include "float.s7i";
const type: matrix is array array float;
const func string: str (in matrix: mat) is func
result
var string: stri is "";
local
var integer: row is 0;
var integer: column is 0;
begin
for row range 1 to length(mat) do
for column range 1 to length(mat[row]) do
stri &:= str(mat[row][column]);
if column < length(mat[row]) then
stri &:= ", ";
end if;
end for;
if row < length(mat) then
stri &:= "\n";
end if;
end for;
end func;
enable_output(matrix);
const func matrix: (in matrix: mat1) * (in matrix: mat2) is func
result
var matrix: product is matrix.value;
local
var integer: row is 0;
var integer: column is 0;
var integer: k is 0;
begin
product := length(mat1) times length(mat1) times 0.0;
for row range 1 to length(mat1) do
for column range 1 to length(mat1) do
product[row][column] := 0.0;
for k range 1 to length(mat1) do
product[row][column] +:= mat1[row][k] * mat2[k][column];
end for;
end for;
end for;
end func;
const func matrix: (in var matrix: base) ** (in var integer: exponent) is func
result
var matrix: power is matrix.value;
local
var integer: row is 0;
var integer: column is 0;
begin
if exponent < 0 then
raise NUMERIC_ERROR;
else
if odd(exponent) then
power := base;
else
# Create identity matrix
power := length(base) times length(base) times 0.0;
for row range 1 to length(base) do
for column range 1 to length(base) do
if row = column then
power[row][column] := 1.0;
end if;
end for;
end for;
end if;
exponent := exponent div 2;
while exponent > 0 do
base := base * base;
if odd(exponent) then
power := power * base;
end if;
exponent := exponent div 2;
end while;
end if;
end func;
const proc: main is func
local
var matrix: m is [] (
[] (4.0, 3.0),
[] (2.0, 1.0));
var integer: exponent is 0;
begin
for exponent range [] (0, 1, 2, 3, 5, 7, 11, 13, 17, 19, 23) do
writeln("m ** " <& exponent <& " =");
writeln(m ** exponent);
end for;
end func;

View file

@ -0,0 +1,5 @@
#import nat
#import lin
id = @h ^|CzyCK33/1.! 0.!*
mex = ||id@l mmult:-0^|DlS/~& iota

View file

@ -0,0 +1 @@
mex = ~&ar^?\id@al (~&lr?/mmult@llPrX ~&r)^/~&alrhPX mmult@falrtPXPRiiX

View file

@ -0,0 +1,3 @@
#cast %eLLL
test = mex/*<<3.,2.>,<2.,1.>> <0,1,2,3,4,10>