Conjugate transpose: Difference between revisions
m
syntax highlighting fixup automation
(Realize in F#) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 38:
{{trans|Nim}}
<
F to_str(m)
Line 131:
test(M3)
print("\n")
test(M4)</
{{out}}
Line 185:
=={{header|Ada}}==
<
with Ada.Complex_Text_IO; use Ada.Complex_Text_IO;
with Ada.Numerics.Complex_Types; use Ada.Numerics.Complex_Types;
Line 231:
Put_Line("nmat:"); Examine(nmat); New_Line;
Put_Line("umat:"); Examine(umat);
end ConTrans;</
{{out}}
<pre>hmat:
Line 269:
=={{header|ALGOL 68}}==
Uses the same test cases as the Ada sample.
<
# returns the conjugate transpose of m #
OP CONJUGATETRANSPOSE = ( [,]COMPL m )[,]COMPL:
Line 367:
)
)
END</
{{out}}
<pre>
Line 399:
=={{header|C}}==
<
#include<stdlib.h>
Line 579:
return 0;
}</
{{out}}
<pre>
Line 600:
=={{header|C++}}==
<
#include <cmath>
#include <complex>
Line 790:
test(matrix3);
return 0;
}</
{{out}}
Line 832:
=={{header|Common Lisp}}==
<syntaxhighlight lang="lisp">
(defun matrix-multiply (m1 m2)
(mapcar
Line 863:
(defun unitary-p (m)
(identity-p (matrix-multiply m (conjugate-transpose m))) )
</syntaxhighlight>
{{out}}
Line 886:
=={{header|D}}==
{{trans|Python}} A well typed and mostly imperative version:
<
std.numeric;
Line 992:
writefln("Unitary? %s.\n", isUnitary(mat, ct));
}
}</
{{out}}
<pre>Matrix:
Line 1,031:
===Alternative Version===
A more functional version that contains some typing problems (same output).
<
std.numeric, std.exception, std.traits;
Line 1,120:
writefln("Unitary? %s.\n", isUnitary(mat, ct));
}
}</
=={{header|F_Sharp|F#}}==
<
// Conjugate transpose. Nigel Galloway: January 10th., 2022
let fN g=let g=g|>List.map(List.map(fun(n,g)->System.Numerics.Complex(n,g)))|>MathNet.Numerics.LinearAlgebra.MatrixExtensions.matrix in (g,g.ConjugateTranspose())
Line 1,129:
let test=[fN [[(3.0,0.0);(2.0,1.0)];[(2.0,-1.0);(1.0,0.0)]];fN [[(1.0,0.0);(1.0,0.0);(0.0,0.0)];[(0.0,0.0);(1.0,0.0);(1.0,0.0)];[(1.0,0.0);(0.0,0.0);(1.0,0.0)]];fN [[(1.0/sqrt 2.0,0.0);(1.0/sqrt 2.0,0.0);(0.0,0.0)];[(0.0,1.0/sqrt 2.0);(0.0,-1.0/sqrt 2.0);(0.0,0.0)];[(0.0,0.0);(0.0,0.0);(0.0,1.0)]]]
test|>List.iter(fun(n,g)->printfn $"Matrix\n------\n%A{n}\nConjugate transposed\n--------------------\n%A{g}\nIs hermitian: %A{n.IsHermitian()}\nIs normal: %A{n*g=g*n}\nIs unitary: %A{fG n g}\n")
</syntaxhighlight>
{{out}}
<pre>
Line 1,188:
{{works with|Factor|development (future 0.95)}}
<
IN: rosetta.hermitian
Line 1,201:
: unitary-matrix? ( matrix -- ? )
[ dup conj-t m. ] [ length identity-matrix ] bi = ;</
Usage:
Line 1,219:
The examples and algorithms are taken from the j solution, except for UnitaryQ. The j solution uses the matrix inverse verb. Compilation on linux, assuming the program is file f.f08 :<pre>
gfortran -std=f2008 -Wall -fopenmp -ffree-form -fall-intrinsics -fimplicit-none f.f08 -o f</pre>
<syntaxhighlight lang="fortran">
program conjugate_transpose
Line 1,284:
end program conjugate_transpose
</syntaxhighlight>
<pre>
-*- mode: compilation; default-directory: "/tmp/" -*-
Line 1,331:
=={{header|FreeBASIC}}==
<
type complex
real as double
Line 1,460:
print is_hermitian(A), is_normal(A), is_unitary(A)
print is_hermitian(B), is_normal(B), is_unitary(B)
print is_hermitian(C), is_normal(C), is_unitary(C)</
{{out}}
<pre>true true true
Line 1,467:
=={{header|Go}}==
<
import (
Line 1,578:
}
return m3
}</
Output:
<pre>
Line 1,621:
=={{header|Haskell}}==
Slow implementation using lists.
<
import Data.List (transpose)
Line 1,695:
:: Num a
=> Matrix (Complex a) -> Matrix (Complex a)
conjTranspose = map (map conjugate) . transpose</
Output:
<pre>
Line 1,735:
=={{header|J}}==
'''Solution''': <
'''Examples''': <
HERMITIAN =: 3 2j1 ,: 2j_1 1
Line 1,748:
UNITARY =: (-:%:2) * 1 1 0 , 0j_1 0j1 0 ,: 0 0 0j1 * %:2
(ct -: %.) UNITARY NB. A_ct = A^-1
1</
'''Reference''' (example matrices for other langs to use):<
+--------+-----+--------------------------+
| 3 2j1|1 1 0| 0.707107 0.707107 0|
Line 1,765:
+-----+-----+-----+
|1 1 0|0 1 0|0 1 1|
+-----+-----+-----+</
=={{header|jq}}==
Line 1,777:
If your jq does not have "transpose" then the following may be used:
<
# (an array of equal-length arrays):
def transpose:
if (.[0] | length) == 0 then []
else [map(.[0])] + (map(.[1:]) | transpose)
end ;</
'''(2) Operations on real/complex numbers'''
<
# always return complex
def plus(x; y):
Line 1,810:
if type == "number" then [.,0]
else [.[0], -(.[1]) ]
end;</
'''(3) Array operations'''
<
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]) ));</
'''(4) Matrix operations'''
<
def to_complex:
def toc: if type == "number" then [.,0] else . end;
Line 1,855:
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;</
====Conjugate transposition====
<
def conjugate_transpose:
map( map(conjugate) ) | transpose;
Line 1,879:
| complex_identity(length) as $I
| approximately_equal( $I; matrix_multiply($H;$M); 1e-10)
and approximately_equal( $I ; matrix_multiply($M;$H); 1e-10) ; </
====Examples====
<
[ [ 3, [2,1]],
[[2,-1], 1 ] ];
Line 1,910:
;
demo</
{{out}}
<
Hermitian example:
Line 1,927:
Normal example: true
Unitary example: true</
=={{header|Julia}}==
Julia has a built-in matrix type, and the conjugate-transpose of a complex matrix <code>A</code> is simply:
<syntaxhighlight lang
(similar to Matlab). You can check whether <code>A</code> is Hermitian via the built-in function
<syntaxhighlight lang
Ignoring the possibility of roundoff errors for floating-point matrices (like most of the examples in the other languages), you can check whether a matrix is normal or unitary by the following functions
<
isnormal(A) = size(A,1) == size(A,2) && A'*A == A*A'
isunitary(A) = size(A,1) == size(A,2) && A'*A == eye(A)</
=={{header|Kotlin}}==
As Kotlin doesn't have built in classes for complex numbers or matrices, some basic functionality needs to be coded in order to tackle this task:
<
typealias C = Complex
Line 2,065:
println("Unitary? ${mct.isUnitary()}\n")
}
}</
{{out}}
Line 2,112:
=={{header|Maple}}==
The commands <code>HermitianTranspose</code> and <code>IsUnitary</code> are provided by the <code>LinearAlgebra</code> package.
<
with(LinearAlgebra):
Line 2,121:
type(M,'Matrix'(hermitian));
IsNormal(M);
IsUnitary(M);</
Output:
<pre> [ 3 2 + I]
Line 2,138:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
UnitaryQ[m_List?MatrixQ] := (Conjugate@Transpose@m.m == IdentityMatrix@Length@m)
Line 2,154:
{HermitianMatrixQ@#, NormalMatrixQ@#, UnitaryQ@#}&@m
-> {False, False, False}</
=={{header|Nim}}==
Line 2,160:
The complex type is defined as generic regarding the type of real an imaginary part. We have chosen to use Complex[float] and make only our Matrix type generic regarding the dimensions. Thus, a Matrix has a two dimensions M and N which are static, i.e. known at compile time. We have enforced the condition M = N for square matrices (also at compile time).
<
type Matrix[M, N: static Positive] = array[M, array[N, Complex[float]]]
Line 2,312:
test(M2)
test(M3)
test(M4)</
{{out}}
Line 2,376:
=={{header|PARI/GP}}==
<syntaxhighlight lang="text">conjtranspose(M)=conj(M~)
isHermitian(M)=M==conj(M~)
isnormal(M)=my(H=conj(M~));H*M==M*H
isunitary(M)=M*conj(M~)==1</
=={{header|Perl}}==
In general, using two or more modules which overload operators can be problematic. For this task, using both Math::Complex and Math::MatrixReal gives us the behavior we want for everything except matrix I/O, i.e. parsing and stringification.
<
use English;
use Math::Complex;
Line 2,466:
$m->assign(3, 3, cplx(0, 1));
return $m;
}</
{{out}}
<pre>
Line 2,506:
=={{header|Phix}}==
Note this code has no testing for non-square matrices.
<!--<
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">include</span> <span style="color: #004080;">complex</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
Line 2,605:
<span style="color: #7060A8;">papply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">,</span><span style="color: #000000;">test</span><span style="color: #0000FF;">)</span>
<!--</
{{out}}
<pre>
Line 2,676:
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
test: procedure options (main); /* 1 October 2012 */
declare n fixed binary;
Line 2,726:
end MMULT;
end test;
</syntaxhighlight>
Outputs from separate runs:
<pre>
Line 2,770:
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
function conjugate-transpose($a) {
$arr = @()
Line 2,847:
"Normal? `$m = $(are-eq $mhm $hmm)"
"Unitary? `$m = $((are-eq $id2 $hmm) -and (are-eq $id2 $mhm))"
</syntaxhighlight>
<b>Output:</b>
<pre>
Line 2,873:
=={{header|Python}}==
Internally, matrices must be represented as rectangular tuples of tuples of complex numbers.
<
return tuple(tuple(n.conjugate() for n in row) for row in zip(*m))
Line 2,944:
print('Hermitian? %s.' % ishermitian(matrix, ct))
print('Normal? %s.' % isnormal(matrix, ct))
print('Unitary? %s.' % isunitary(matrix, ct))</
{{out}}
Line 2,982:
=={{header|Racket}}==
<
#lang racket
(require math)
Line 2,999:
(define (hermitian? M)
(equal? (H M) M))
</syntaxhighlight>
Test:
<
(define M (matrix [[3.000+0.000i +2.000+1.000i]
[2.000-1.000i +1.000+0.000i]]))
Line 3,008:
(unitary? M)
(hermitian? M)
</syntaxhighlight>
Output:
<
(array #[#[3.0-0.0i 2.0+1.0i] #[2.0-1.0i 1.0-0.0i]])
#t
#f
#f
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2015-12-13}}
<syntaxhighlight lang="raku"
[ 1, 1+i, 2i],
[ 1-i, 5, -3],
Line 3,071:
}
sub say-it (@array) { $_».fmt("%9s").say for @array }</
{{out}}
<pre>Matrix:
Line 3,114:
=={{header|REXX}}==
<
parse arg N elements; if N==''|N=="," then N=3 /*Not specified? Then use the default.*/
k= 0; do r=1 for N
Line 3,192:
numeric digits; parse value format(x,2,1,,0) 'E0' with g 'E' _ .; g=g *.5'e'_ % 2
m.=9; do j=0 while h>9; m.j=h; h=h%2+1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g)*.5; end /*k*/; return g</
{{out|output|text= when using the default input:}}
<pre>
Line 3,235:
=={{header|Ruby}}==
{{works with|Ruby|2.0}}
<
# Start with some matrix.
Line 3,259:
print ' normal? false'
print ' unitary? false'
end</
Note: Ruby 1.9 had a bug in the Matrix#hermitian? method. It's fixed in 2.0.
=={{header|Rust}}==
Uses external crate 'num', version 0.1.34
<
extern crate num; // crate for complex numbers
Line 3,344:
println!("Unitary?: FALSE");
}
}</
Output:
<pre>
Line 3,368:
=={{header|Scala}}==
<
case class Complex(re: Double, im: Double) {
Line 3,444:
}
}</
{{out}}
<pre>
Line 3,464:
=={{header|Sidef}}==
{{trans|Raku}}
<
func mat_mult (Array a, Array b, Number ε = -3) {
Line 3,529:
say "Is Normal?\t#{is_Normal(m, t)}"
say "Is Unitary?\t#{is_Unitary(m, t)}"
}</
{{out}}
<pre>
Line 3,575:
Sparkling has support for basic complex algebraic operations, but complex matrix operations are not in the standard library.
<
let conjTransp = function conjTransp(M) {
return map(range(sizeof M[0]), function(row) {
Line 3,675:
print("U x U* = ");
printCplxMat(cplxMatMul(U, conjTransp(U)));
print();</
=={{header|Stata}}==
In Mata, the ' operator is always the conjugate transpose. To get only the matrix transpose without complex conjugate, use the [ transposeonly] function.
<
: a=1,2i\3i,4
Line 3,712:
: a'*a==I(rows(a))
0
</syntaxhighlight>
=={{header|Tcl}}==
Line 3,718:
{{tcllib|math::complexnumbers}}
{{tcllib|struct::matrix}}
<
package require math::complexnumbers
Line 3,774:
}
return $mat
}</
Using these tools to test for the properties described in the task:
<
if {[$matrix rows] != [$matrix columns]} {
# Must be square!
Line 3,827:
$mmh destroy
return $result
}</
<!-- Wot, no demonstration? -->
Line 3,838:
However, if we use the ''almostEquals'' method with the default tolerance of 1.0e-14, then we do get a ''true'' result.
<
import "/fmt" for Fmt
Line 3,871:
var cm4 = cm3 * cm3.conjTranspose
var id = CMatrix.identity(3)
System.print("Unitary : %(cm4.almostEquals(id))")</
{{out}}
|