use strict; use warnings; use QKey qw/ randseq quantumencode analyze ynseq bobkey alicekey /; # Alice my @randseq = randseq(43); my @quantumencode = quantumencode(@randseq); # Bob my @analyze = analyze(@quantumencode); my @ynseq = ynseq(@analyze); my @bobkey = bobkey(@analyze); # Alice my @alicekey = alicekey(\@ynseq, \@randseq); print "@bobkey\n"; print "@alicekey\n"; __END__ 0 1 1 1 0 1 0 0 0 0 1 1 1 0 1 0 0 0 #### package QKey; use strict; use Exporter; use Math::MatrixReal; use QStuff qw(entangle); our @ISA = qw(Exporter); our @EXPORT_OK = qw(randseq quantumencode analyze ynseq bobkey alicekey %ms); our %ms; # seq of measurements used sub randseq { map{int rand(2)} 1..($_[0]) } # Alice sub quantumencode { # Alice map { $_ ? entangle(1/sqrt(2), 0, 1/sqrt(2), 1) : entangle(1, 0, 0, 1) } @_ } # measurements(@quantumEncode): seq of measurements gonna use sub _measurements { # Bob my $ms = {}; $ms->{ms} = [ entangle(1/sqrt(2), 0, -1/sqrt(2), 1), entangle(0, 0, 1, 1) ]; $ms->{seq} = [ map{int rand(2)} 0..$#_ ]; return $ms; } # analyze(@quantumEncode): return measurement results sub analyze { # Bob %ms = %{_measurements(@_)}; map{ $_[$_]->proj($ms{ms}[$ms{seq}[$_]]) } 0..$#_; } # ynseq(@analyze): return y/n seq of "results" sub ynseq { # Bob map{ $_->cmpquanta($ms{ms}[0]) or $_->cmpquanta($ms{ms}[1]) ? 1 : 0 } @_; } # bobkey(@analyze) sub bobkey { # Bob my @key; for (@_) { push(@key, 0) if $_->cmpquanta($ms{ms}[0]); push(@key, 1) if $_->cmpquanta($ms{ms}[1]); } return @key; } # alicekey(\@ynseq, \@randseq) sub alicekey { # Alice my @key; for(0..$#{$_[0]}){ push(@key, ${$_[1]}[$_]) if ${$_[0]}[$_] } return @key; } 1; #### package QStuff; use strict; use Exporter; use Math::MatrixReal; use Quantum::Entanglement; our @ISA = qw/Quantum::Entanglement Exporter/; our @EXPORT_OK = qw/entangle/; sub entangle {bless Quantum::Entanglement::entangle(@_)} # args($entangle) returns values passed to entangle() sub args { map {@{$_}} @{${$_[0]->[0]}} } # $entange->probs returns probs only sub probs { my @ar = args(shift); return map {@ar[$_*2]} 0..(int($#ar/2)); } # $entange->states return states only sub states { my @ar = args(shift); return map {@ar[$_*2+1]} 0..(int($#ar/2)); } # $a->cmpquanta($b) sees if 2 quanta the same sub cmpquanta { return 0 unless $_[0]->cmpstates($_[1]); my @probs0 = $_[0]->probs; my @probs1 = $_[1]->probs; for(0..$#probs0){return 0 unless abs($probs0[$_] - $probs1[$_]) < 0.000001} return 1; } # $a->cmpstates($b) sees if $a & $b have the same state space sub cmpstates { my @a = $_[0]->states; my @b = $_[1]->states; return 0 if $#a != $#b; for (0..$#a) {return 0 if $a[$_] != $b[$_]}; return 1; } # project $a onto the subspace of $b sub proj { my ($a, $b) = @_; # checking states compatability to be implemented my @bstates = $b->states; my ($I, $prob, $Pb, $measure, $norm, $measure); $b = Math::MatrixReal->new_from_cols([[$b->probs]]); $a = Math::MatrixReal->new_from_cols([[$a->probs]]); $I = Math::MatrixReal->new_diag( [1, 1] ); $prob = (~$a * $b * ~$b * $a)->element(1,1); $Pb = rand(1) < $prob ? $b * ~$b : ($I - $b * ~$b ); # quantum thing $measure = $Pb * $a; $norm = sqrt((~($measure) * $measure)->element(1,1)); $measure = $Pb * $a * (1/$norm); bless QStuff::entangle( map {$measure->element($_+1, 1) => $bstates[$_]} 0..$#bstates ); } 1; #### use strict; use warnings; use QStuff qw/entangle/; my $a0 = entangle(1, 0, 0, 1); my $a1 = entangle(1/sqrt(2), 0, 1/sqrt(2), 1); my $b0 = entangle(1/sqrt(2), 0, -1/sqrt(2), 1); my $b1 = entangle(0, 0, 1, 1); print "proj\n"; print $a0->proj($b0)->show_states; print $a1->proj($b1)->show_states; print $a0->proj($b1)->show_states; print $a1->proj($b0)->show_states; print "\n\n"; exit; print "cmpquanta\n"; print $a1->cmpquanta($b0) . "\n"; print $a1->cmpquanta($b1) . "\n"; print $a1->cmpquanta($a1) . "\n"; print $b1->cmpquanta($a0) . "\n"; print "\n\n"; print "cmpstates\n"; print $a1->cmpstates($b0) . "\n"; print $a1->cmpstates($b1) . "\n"; print $a1->cmpstates($a1) . "\n"; print $b1->cmpstates($a0) . "\n"; print "\n\n"; print "states\n"; print "@{[$a0->states]}\n"; print "@{[$a1->states]}\n"; print "@{[$b0->states]}\n"; print "@{[$b1->states]}\n"; print "\n\n"; print "probs\n"; print "@{[$a0->probs]}\n"; print "@{[$a1->probs]}\n"; print "@{[$b0->probs]}\n"; print "@{[$b1->probs]}\n"; print "\n\n"; print "args\n"; print "@{[$a0->args]}\n"; print "@{[$a1->args]}\n"; print "@{[$b0->args]}\n"; print "@{[$b1->args]}\n";