Add tasks for all the new languages

This commit is contained in:
Tina Müller 2016-12-05 23:44:36 +01:00
parent 9dc3c2bb62
commit bba7bfd280
13208 changed files with 134745 additions and 0 deletions

View file

@ -0,0 +1,101 @@
# Computes conjugate transpose of M
let conjTransp = function conjTransp(M) {
return map(range(sizeof M[0]), function(row) {
return map(range(sizeof M), function(col) {
return cplx_conj(M[col][row]);
});
});
};
# Helper for cplxMatMul
let cplxVecScalarMul = function cplxVecScalarMul(A, B, row, col) {
var M = { "re": 0.0, "im": 0.0 };
let N = sizeof A;
for (var i = 0; i < N; i++) {
let P = cplx_mul(A[row][i], B[i][col]);
M = cplx_add(M, P);
}
return M;
};
# Multiplies matrices A and B
# A and B are assumed to be square and of the same size,
# this condition is not checked.
let cplxMatMul = function cplxMatMul(A, B) {
var R = {};
let N = sizeof A;
for (var row = 0; row < N; row++) {
R[row] = {};
for (var col = 0; col < N; col++) {
R[row][col] = cplxVecScalarMul(A, B, row, col);
}
}
return R;
};
# Helper for creating an array representing a complex number
# given its textual representation
let _ = function makeComplex(str) {
let sep = indexof(str, "+", 1);
if sep < 0 {
sep = indexof(str, "-", 1);
}
let reStr = substrto(str, sep);
let imStr = substrfrom(str, sep);
return { "re": tofloat(reStr), "im": tofloat(imStr) };
};
# Formats a complex matrix
let printCplxMat = function printCplxMat(M) {
foreach(M, function(i, row) {
foreach(row, function(j, elem) {
printf(" %.2f%+.2fi", elem.re, elem.im);
});
print();
});
};
# A Hermitian matrix
let H = {
{ _("3+0i"), _("2+1i") },
{ _("2-1i"), _("0+0i") }
};
# A normal matrix
let N = {
{ _("1+0i"), _("1+0i"), _("0+0i") },
{ _("0+0i"), _("1+0i"), _("1+0i") },
{ _("1+0i"), _("0+0i"), _("1+0i") }
};
# A unitary matrix
let U = {
{ _("0.70710678118+0i"), _("0.70710678118+0i"), _("0+0i") },
{ _("0-0.70710678118i"), _("0+0.70710678118i"), _("0+0i") },
{ _("0+0i"), _("0+0i"), _("0+1i") }
};
print("Hermitian matrix:\nH = ");
printCplxMat(H);
print("H* = ");
printCplxMat(conjTransp(H));
print();
print("Normal matrix:\nN = ");
printCplxMat(N);
print("N* = ");
printCplxMat(conjTransp(N));
print("N* x N = ");
printCplxMat(cplxMatMul(conjTransp(N), N));
print("N x N* = ");
printCplxMat(cplxMatMul(N, conjTransp(N)));
print();
print("Unitary matrix:\nU = ");
printCplxMat(U);
print("U* = ");
printCplxMat(conjTransp(U));
print("U x U* = ");
printCplxMat(cplxMatMul(U, conjTransp(U)));
print();

View file

@ -0,0 +1,6 @@
# transpose/0 expects its input to be a rectangular matrix
# (an array of equal-length arrays):
def transpose:
if (.[0] | length) == 0 then []
else [map(.[0])] + (map(.[1:]) | transpose)
end ;

View file

@ -0,0 +1,27 @@
# x must be real or complex, and ditto for y;
# always return complex
def plus(x; y):
if (x|type) == "number" then
if (y|type) == "number" then [ x+y, 0 ]
else [ x + y[0], y[1]]
end
elif (y|type) == "number" then plus(y;x)
else [ x[0] + y[0], x[1] + y[1] ]
end;
# x must be real or complex, and ditto for y;
# always return complex
def multiply(x; y):
if (x|type) == "number" then
if (y|type) == "number" then [ x*y, 0 ]
else [x * y[0], x * y[1]]
end
elif (y|type) == "number" then multiply(y;x)
else [ x[0] * y[0] - x[1] * y[1], x[0] * y[1] + x[1] * y[0]]
end;
# conjugate of a real or complex number
def conjugate:
if type == "number" then [.,0]
else [.[0], -(.[1]) ]
end;

View file

@ -0,0 +1,5 @@
# a and b are arrays of real/complex numbers
def dot_product(a; b):
a as $a | b as $b
| reduce range(0;$a|length) as $i
(0; . as $s | plus($s; multiply($a[$i]; $b[$i]) ));

View file

@ -0,0 +1,38 @@
# convert a matrix of mixed real/complex entries to all complex entries
def to_complex:
def toc: if type == "number" then [.,0] else . end;
map( map(toc) );
# simple matrix pretty-printer
def pp(wide):
def pad: tostring | (wide - length) * " " + .;
def row: reduce .[] as $x (""; . + ($x|pad));
reduce .[] as $row (""; . + "\n\($row|row)");
# Matrix multiplication
# A and B should both be real/complex matrices,
# A being m by n, and B being n by p.
def matrix_multiply(A; B):
A as $A | B as $B
| ($B[0]|length) as $p
| ($B|transpose) as $BT
| reduce range(0; $A|length) as $i
([]; reduce range(0; $p) as $j
(.; .[$i][$j] = dot_product( $A[$i]; $BT[$j] ) )) ;
# Complex identity matrix of dimension n
def complex_identity(n):
def indicator(i;n): [range(0;n)] | map( [0,0]) | .[i] = [1,0];
reduce range(0; n) as $i ([]; . + [indicator( $i; n )] );
# Approximate equality of two matrices
# Are two real/complex matrices essentially equal
# in the sense that the sum of the squared element-wise differences
# is less than or equal to epsilon?
# The two matrices must be conformal.
def approximately_equal(M; N; epsilon):
def norm: multiply(. ; conjugate ) | .[0];
def sqdiff( x; y): plus(x; multiply(y; -1)) | norm;
reduce range(0;M|length) as $i
(0; reduce range(0; M[0]|length) as $j
(.; 0 + sqdiff( M[$i][$j]; N[$i][$j] ) ) ) <= epsilon;

View file

@ -0,0 +1,23 @@
# (entries may be real and/or complex)
def conjugate_transpose:
map( map(conjugate) ) | transpose;
# A Hermitian matrix equals its own conjugate transpose
def is_hermitian:
to_complex == conjugate_transpose;
# A matrix is normal if it commutes multiplicatively
# with its conjugate transpose
def is_normal:
. as $M
| conjugate_transpose as $H
| matrix_multiply($H; $M) == matrix_multiply($H; $M);
# A unitary matrix (U) has its inverse equal to its conjugate transpose (T)
# i.e. U^-1 == T; NASC is I == UT == TU
def is_unitary:
. as $M
| conjugate_transpose as $H
| complex_identity(length) as $I
| approximately_equal( $I; matrix_multiply($H;$M); 1e-10)
and approximately_equal( $I ; matrix_multiply($M;$H); 1e-10) ;

View file

@ -0,0 +1,29 @@
def hermitian_example:
[ [ 3, [2,1]],
[[2,-1], 1 ] ];
def normal_example:
[ [1, 1, 0],
[0, 1, 1],
[1, 0, 1] ];
def unitary_example:
0.707107
| [ [ [., 0], [., 0], 0 ],
[ [0, -.], [0, .], 0 ],
[ 0, 0, [0,1] ] ];
def demo:
hermitian_example
| ("Hermitian example:", pp(8)),
"",
("Its conjugate transpose is:", (to_complex | conjugate_transpose | pp(8))),
"",
"Hermitian example: \(hermitian_example | is_hermitian )",
"",
"Normal example: \(normal_example | is_normal )",
"",
"Unitary example: \(unitary_example | is_unitary)"
;
demo

View file

@ -0,0 +1,16 @@
$ jq -r -c -n -f Conjugate_transpose.jq
Hermitian example:
3 [2,1]
[2,-1] 1
Conjugate transpose:
[3,-0] [2,1]
[2,-1] [1,-0]
Hermitian example: true
Normal example: true
Unitary example: true