Conjugate transpose: Difference between revisions
Content added Content deleted
(Added Kotlin) |
|||
Line 1,641: | Line 1,641: | ||
Is Normal? True |
Is Normal? True |
||
Is Unitary? True |
Is Unitary? True |
||
</pre> |
|||
=={{header|Phix}}== |
|||
Phix has no support for complex numbers, so roll our own, ditto matrix maths. Note this code has no testing for non-square matrices. |
|||
<lang Phix>enum REAL, IMAG |
|||
type complex(sequence s) |
|||
return length(s)=2 and atom(s[REAL]) and atom(s[IMAG]) |
|||
end type |
|||
function c_add(complex a, complex b) |
|||
return sq_add(a,b) |
|||
end function |
|||
function c_mul(complex a, complex b) |
|||
return {a[REAL] * b[REAL] - a[IMAG] * b[IMAG], |
|||
a[REAL] * b[IMAG] + a[IMAG] * b[REAL]} |
|||
end function |
|||
function c_conj(complex a) |
|||
return {a[REAL],-a[IMAG]} |
|||
end function |
|||
function c_print(complex a) |
|||
if a[IMAG]=0 then return sprintf("%g",a[REAL]) end if |
|||
return sprintf("%g%+gi",a) |
|||
end function |
|||
procedure m_print(sequence a) |
|||
integer l = length(a) |
|||
for i=1 to l do |
|||
for j=1 to l do |
|||
a[i][j] = c_print(a[i][j]) |
|||
end for |
|||
a[i] = "["&join(a[i],",")&"]" |
|||
end for |
|||
puts(1,join(a,"\n")&"\n") |
|||
end procedure |
|||
function conjugate_transpose(sequence a) |
|||
sequence res = a |
|||
integer l = length(a) |
|||
for i=1 to l do |
|||
for j=1 to l do |
|||
res[i][j] = c_conj(a[j][i]) |
|||
end for |
|||
end for |
|||
return res |
|||
end function |
|||
function m_unitary(sequence act) |
|||
-- note: a was normal and act = a*ct already |
|||
integer l = length(act) |
|||
for i=1 to l do |
|||
for j=1 to l do |
|||
atom {re,im} = act[i,j] |
|||
-- round to nearest billionth |
|||
-- (powers of 2 help the FPU out) |
|||
re = round(re,1024*1024*1024) |
|||
im = round(im,1024*1024*1024) |
|||
if im!=0 |
|||
or (i=j and re!=1) |
|||
or (i!=j and re!=0) then |
|||
return 0 |
|||
end if |
|||
end for |
|||
end for |
|||
return 1 |
|||
end function |
|||
function m_mul(sequence a, sequence b) |
|||
sequence res = sq_mul(a,0) |
|||
integer l = length(a) |
|||
for i=1 to l do |
|||
for j=1 to l do |
|||
for k=1 to l do |
|||
res[i][j] = c_add(res[i][j],c_mul(a[i][k],b[k][j])) |
|||
end for |
|||
end for |
|||
end for |
|||
return res |
|||
end function |
|||
procedure test(sequence a) |
|||
sequence ct = conjugate_transpose(a) |
|||
printf(1,"Original matrix:\n") |
|||
m_print(a) |
|||
printf(1,"Conjugate transpose:\n") |
|||
m_print(ct) |
|||
-- note: rounding similar to that in m_unitary may be rqd (in a similar |
|||
-- loop in a new m_equal function) on these two equality tests, |
|||
-- but as it is, all tests pass with the builtin = operator. |
|||
printf(1,"Hermitian?: %s\n",{iff(a=ct?"TRUE":"FALSE")}) -- (this one) |
|||
sequence act = m_mul(a,ct), cta = m_mul(ct,a) |
|||
bool normal = act=cta -- (&this one) |
|||
printf(1,"Normal?: %s\n",{iff(normal?"TRUE":"FALSE")}) |
|||
printf(1,"Unitary?: %s\n\n",{iff(normal and m_unitary(act)?"TRUE":"FALSE")}) |
|||
end procedure |
|||
constant x = sqrt(2)/2 |
|||
constant tests = {{{{3, 0},{2,1}}, |
|||
{{2,-1},{1,0}}}, |
|||
{{{ 1, 0},{ 1, 1},{ 0, 2}}, |
|||
{{ 1,-1},{ 5, 0},{-3, 0}}, |
|||
{{ 0,-2},{-3, 0},{ 0, 0}}}, |
|||
{{{0.5,+0.5},{0.5,-0.5}}, |
|||
{{0.5,-0.5},{0.5,+0.5}}}, |
|||
{{{ 1, 0},{ 1, 0},{ 0, 0}}, |
|||
{{ 0, 0},{ 1, 0},{ 1, 0}}, |
|||
{{ 1, 0},{ 0, 0},{ 1, 0}}}, |
|||
{{{x, 0},{x, 0},{0, 0}}, |
|||
{{0,-x},{0, x},{0, 0}}, |
|||
{{0, 0},{0, 0},{0, 1}}}, |
|||
{{{2,7},{9,-5}}, |
|||
{{3,4},{8,-6}}}} |
|||
for i=1 to length(tests) do test(tests[i]) end for</lang> |
|||
{{out}} |
|||
<pre> |
|||
Original matrix: |
|||
[3,2+1i] |
|||
[2-1i,1] |
|||
Conjugate transpose: |
|||
[3,2+1i] |
|||
[2-1i,1] |
|||
Hermitian?: TRUE |
|||
Normal?: TRUE |
|||
Unitary?: FALSE |
|||
Original matrix: |
|||
[1,1+1i,0+2i] |
|||
[1-1i,5,-3] |
|||
[0-2i,-3,0] |
|||
Conjugate transpose: |
|||
[1,1+1i,0+2i] |
|||
[1-1i,5,-3] |
|||
[0-2i,-3,0] |
|||
Hermitian?: TRUE |
|||
Normal?: TRUE |
|||
Unitary?: FALSE |
|||
Original matrix: |
|||
[0.5+0.5i,0.5-0.5i] |
|||
[0.5-0.5i,0.5+0.5i] |
|||
Conjugate transpose: |
|||
[0.5-0.5i,0.5+0.5i] |
|||
[0.5+0.5i,0.5-0.5i] |
|||
Hermitian?: FALSE |
|||
Normal?: TRUE |
|||
Unitary?: TRUE |
|||
Original matrix: |
|||
[1,1,0] |
|||
[0,1,1] |
|||
[1,0,1] |
|||
Conjugate transpose: |
|||
[1,0,1] |
|||
[1,1,0] |
|||
[0,1,1] |
|||
Hermitian?: FALSE |
|||
Normal?: TRUE |
|||
Unitary?: FALSE |
|||
Original matrix: |
|||
[0.707107,0.707107,0] |
|||
[0-0.707107i,0+0.707107i,0] |
|||
[0,0,0+1i] |
|||
Conjugate transpose: |
|||
[0.707107,0+0.707107i,0] |
|||
[0.707107,0-0.707107i,0] |
|||
[0,0,0-1i] |
|||
Hermitian?: FALSE |
|||
Normal?: TRUE |
|||
Unitary?: TRUE |
|||
Original matrix: |
|||
[2+7i,9-5i] |
|||
[3+4i,8-6i] |
|||
Conjugate transpose: |
|||
[2-7i,3-4i] |
|||
[9+5i,8+6i] |
|||
Hermitian?: FALSE |
|||
Normal?: FALSE |
|||
Unitary?: FALSE |
|||
</pre> |
</pre> |
||