Commit 5aa235c1 authored by yuki.yahagi's avatar yuki.yahagi

Merge branch 'develop'

* develop:
  アニーリングマシンのverilogでなぜかエネルギーをreg宣言して計算していたところを直し,pythonコードでおんなじこと書いてみた
parents 5001b378 731c7ac1
def annealer(
list_spin,
interact0,
interact1,
interact2,
interact3,
interact4,
interact5,
):
spin = [0, 0, 0, 0]
spin[0] = list_spin[0] * 2 - 1
spin[1] = list_spin[1] * 2 - 1
spin[2] = list_spin[2] * 2 - 1
spin[3] = list_spin[3] * 2 - 1
H = [0, 0, 0, 0, 0]
while 1:
H[4] = ( -1 * interact0 * spin[0] * spin[1] ) \
+ ( -1 * interact1 * spin[0] * spin[2] ) \
+ ( -1 * interact2 * spin[0] * spin[3] ) \
+ ( -1 * interact3 * spin[1] * spin[2] ) \
+ ( -1 * interact4 * spin[1] * spin[3] ) \
+ ( -1 * interact5 * spin[2] * spin[3] )
H[0] = ( interact0 * spin[0] * spin[1] ) \
+ ( interact1 * spin[0] * spin[2] ) \
+ ( interact2 * spin[0] * spin[3] ) \
+ ( -1 * interact3 * spin[1] * spin[2] ) \
+ ( -1 * interact4 * spin[1] * spin[3] ) \
+ ( -1 * interact5 * spin[2] * spin[3] )
H[1] = ( interact0 * spin[0] * spin[1] ) \
+ ( -1 * interact1 * spin[0] * spin[2] ) \
+ ( -1 * interact2 * spin[0] * spin[3] ) \
+ ( interact3 * spin[1] * spin[2] ) \
+ ( interact4 * spin[1] * spin[3] ) \
+ ( -1 * interact5 * spin[2] * spin[3] )
H[2] = ( -1 * interact0 * spin[0] * spin[1] ) \
+ ( interact1 * spin[0] * spin[2] ) \
+ ( -1 * interact2 * spin[0] * spin[3] ) \
+ ( interact3 * spin[1] * spin[2] ) \
+ ( -1 * interact4 * spin[1] * spin[3] ) \
+ ( interact5 * spin[2] * spin[3] )
H[3] = ( -1 * interact0 * spin[0] * spin[1] ) \
+ ( -1 * interact1 * spin[0] * spin[2] ) \
+ ( interact2 * spin[0] * spin[3] ) \
+ ( -1 * interact3 * spin[1] * spin[2] ) \
+ ( interact4 * spin[1] * spin[3] ) \
+ ( interact5 * spin[2] * spin[3] )
if ( H[0] < H[1] ):
invert_tmp0 = 0
else:
invert_tmp0 = 1
if ( H[2] < H[3] ):
invert_tmp1 = 2
else:
invert_tmp1 = 3
if ( H[invert_tmp0] < H[invert_tmp1] ):
invert = invert_tmp0
else:
invert = invert_tmp1
if ( H[4] > H[invert] ):
spin[invert] = -spin[invert]
else:
return spin
......@@ -18,10 +18,10 @@ module annealer_2x2( // 2x2のアニーリングマシン,外部磁場を考
reg [3:0] spin; // スピンの値,今回は1, 0で表す(+1 --> 1, -1 --> 0)
reg [3:0] J0, J1, J2, J3, J4, J5; // 相互作用係数
reg [6:0] H [4:0]; // ハミルトニアン(エネルギー),相互作用係数から42 ~ -42の値をとるので7ビット必要,
wire [6:0] H [4:0]; // ハミルトニアン(エネルギー),相互作用係数から42 ~ -42の値をとるので7ビット必要,
// また,現在の状態 + ある1つのスピンの値が反転した場合の合計5通りの計算をしておく.
reg state_init, state_busy, state_end;
reg invert; // どのスピンを反転させるか
wire [1:0] invert, invert_tmp; // どのスピンを反転させるか
wire [6:0] Jscale [5:0]; // Jを7ビットに拡張する,7ビットのwireが6本
wire [6:0] Sscale [3:0]; // スピンの値を7ビットに拡張する,スピンの値を符号ビットのように扱う.
......@@ -40,6 +40,51 @@ module annealer_2x2( // 2x2のアニーリングマシン,外部磁場を考
assign Sscale[1] = { spin[1], 6'b000000 };
assign Sscale[2] = { spin[2], 6'b000000 };
assign Sscale[3] = { spin[3], 6'b000000 };
assign H[4] = ( Jscale[0] ^ Sscale[0] ^ Sscale[1] ^ 7'b1000000 )
+ ( Jscale[1] ^ Sscale[0] ^ Sscale[2] ^ 7'b1000000 )
+ ( Jscale[2] ^ Sscale[0] ^ Sscale[3] ^ 7'b1000000 )
+ ( Jscale[3] ^ Sscale[1] ^ Sscale[2] ^ 7'b1000000 )
+ ( Jscale[4] ^ Sscale[1] ^ Sscale[3] ^ 7'b1000000 )
+ ( Jscale[5] ^ Sscale[2] ^ Sscale[3] ^ 7'b1000000 );
// ハミルトニアンの計算,シグマの前の符号は各項に分配している(7'b1000000でXORを取ることで符号を反転させている)
assign H[0] = ( Jscale[0] ^ Sscale[0] ^ Sscale[1] )
+ ( Jscale[1] ^ Sscale[0] ^ Sscale[2] )
+ ( Jscale[2] ^ Sscale[0] ^ Sscale[3] )
+ ( Jscale[3] ^ Sscale[1] ^ Sscale[2] ^ 7'b1000000 )
+ ( Jscale[4] ^ Sscale[1] ^ Sscale[3] ^ 7'b1000000 )
+ ( Jscale[5] ^ Sscale[2] ^ Sscale[3] ^ 7'b1000000 );
// spin[0]が反転した時を想定したハミルトニアンの計算,
// spin[0]が使われている(Sscale[0]を含む)項の符号を反転させなければ良い
assign H[1] = ( Jscale[0] ^ Sscale[0] ^ Sscale[1] )
+ ( Jscale[1] ^ Sscale[0] ^ Sscale[2] ^ 7'b1000000 )
+ ( Jscale[2] ^ Sscale[0] ^ Sscale[3] ^ 7'b1000000 )
+ ( Jscale[3] ^ Sscale[1] ^ Sscale[2] )
+ ( Jscale[4] ^ Sscale[1] ^ Sscale[3] )
+ ( Jscale[5] ^ Sscale[2] ^ Sscale[3] ^ 7'b1000000 );
// spin[1]の反転
assign H[2] = ( Jscale[0] ^ Sscale[0] ^ Sscale[1] ^ 7'b1000000 )
+ ( Jscale[1] ^ Sscale[0] ^ Sscale[2] )
+ ( Jscale[2] ^ Sscale[0] ^ Sscale[3] ^ 7'b1000000 )
+ ( Jscale[3] ^ Sscale[1] ^ Sscale[2] )
+ ( Jscale[4] ^ Sscale[1] ^ Sscale[3] ^ 7'b1000000 )
+ ( Jscale[5] ^ Sscale[2] ^ Sscale[3] );
// spin[2]の反転
assign H[3] = ( Jscale[0] ^ Sscale[0] ^ Sscale[1] ^ 7'b1000000 )
+ ( Jscale[1] ^ Sscale[0] ^ Sscale[2] ^ 7'b1000000 )
+ ( Jscale[2] ^ Sscale[0] ^ Sscale[3] )
+ ( Jscale[3] ^ Sscale[1] ^ Sscale[2] ^ 7'b1000000 )
+ ( Jscale[4] ^ Sscale[1] ^ Sscale[3] )
+ ( Jscale[5] ^ Sscale[2] ^ Sscale[3] );
// spin[3]の反転
// ハミルトニアンが最小となる反転を見つける.
// Hはunsignedなので,キャストしてから比較
assign invert_tmp[0] = ($signed(H[0]) > $signed(H[1]));
assign invert_tmp[1] = ($signed(H[2]) > $signed(H[3]));
assign invert[1] = ($signed(H[{1'b0, invert_tmp[0]}]) > $signed(H[{1'b1, invert_tmp[1]}]));
assign invert[0] = invert_tmp[invert[1]];
always @( posedge clk or negedge reset_N ) begin
if ( !reset_N )
......@@ -53,65 +98,7 @@ module annealer_2x2( // 2x2のアニーリングマシン,外部磁場を考
{ state_init, state_busy, state_end } <= 3'b010;
end else if ( { state_init, state_busy, state_end } == 3'b010 ) begin
H[0] <= ( Jscale[0] ^ Sscale[0] ^ Sscale[1] ^ 7'b1000000 )
+ ( Jscale[1] ^ Sscale[0] ^ Sscale[2] ^ 7'b1000000 )
+ ( Jscale[2] ^ Sscale[0] ^ Sscale[3] ^ 7'b1000000 )
+ ( Jscale[3] ^ Sscale[1] ^ Sscale[2] ^ 7'b1000000 )
+ ( Jscale[4] ^ Sscale[1] ^ Sscale[3] ^ 7'b1000000 )
+ ( Jscale[5] ^ Sscale[2] ^ Sscale[3] ^ 7'b1000000 );
// ハミルトニアンの計算,シグマの前の符号は各項に分配している(7'b1000000でXORを取ることで符号を反転させている)
H[1] <= ( Jscale[0] ^ Sscale[0] ^ Sscale[1] )
+ ( Jscale[1] ^ Sscale[0] ^ Sscale[2] )
+ ( Jscale[2] ^ Sscale[0] ^ Sscale[3] )
+ ( Jscale[3] ^ Sscale[1] ^ Sscale[2] ^ 7'b1000000 )
+ ( Jscale[4] ^ Sscale[1] ^ Sscale[3] ^ 7'b1000000 )
+ ( Jscale[5] ^ Sscale[2] ^ Sscale[3] ^ 7'b1000000 );
// spin[0]が反転した時を想定したハミルトニアンの計算,
// spin[0]が使われている(Sscale[0]を含む)項の符号を反転させなければ良い
H[2] <= ( Jscale[0] ^ Sscale[0] ^ Sscale[1] )
+ ( Jscale[1] ^ Sscale[0] ^ Sscale[2] ^ 7'b1000000 )
+ ( Jscale[2] ^ Sscale[0] ^ Sscale[3] ^ 7'b1000000 )
+ ( Jscale[3] ^ Sscale[1] ^ Sscale[2] )
+ ( Jscale[4] ^ Sscale[1] ^ Sscale[3] )
+ ( Jscale[5] ^ Sscale[2] ^ Sscale[3] ^ 7'b1000000 );
// spin[1]の反転
H[3] <= ( Jscale[0] ^ Sscale[0] ^ Sscale[1] ^ 7'b1000000 )
+ ( Jscale[1] ^ Sscale[0] ^ Sscale[2] )
+ ( Jscale[2] ^ Sscale[0] ^ Sscale[3] ^ 7'b1000000 )
+ ( Jscale[3] ^ Sscale[1] ^ Sscale[2] )
+ ( Jscale[4] ^ Sscale[1] ^ Sscale[3] ^ 7'b1000000 )
+ ( Jscale[5] ^ Sscale[2] ^ Sscale[3] );
// spin[2]の反転
H[3] <= ( Jscale[0] ^ Sscale[0] ^ Sscale[1] ^ 7'b1000000 )
+ ( Jscale[1] ^ Sscale[0] ^ Sscale[2] ^ 7'b1000000 )
+ ( Jscale[2] ^ Sscale[0] ^ Sscale[3] )
+ ( Jscale[3] ^ Sscale[1] ^ Sscale[2] ^ 7'b1000000 )
+ ( Jscale[4] ^ Sscale[1] ^ Sscale[3] )
+ ( Jscale[5] ^ Sscale[2] ^ Sscale[3] );
// spin[3]の反転
// ハミルトニアンが最小となる反転を見つける.
if( $signed(H[1]) < $signed(H[2]) ) // Hはunsignedなので,キャストしてから比較
if( $signed(H[1]) < $signed(H[3]) )
if( $signed(H[1]) < $signed(H[4]) )
invert <= 1;
else
invert <= 4;
else if ( $signed(H[3]) < $signed(H[4]) )
invert <= 3;
else
invert <= 4;
else if ( $signed(H[2]) < $signed(H[3]) )
if ( $signed(H[2]) < $signed(H[4]) )
invert <= 2;
else
invert <= 4;
else if ( $signed(H[3]) < $signed(H[4]) )
invert <= 3;
else
invert <= 4;
if ( $signed(H[invert]) < $signed(H[0]) ) // 反転させた方がエネルギーが小さくなった場合
if ( $signed(H[invert]) < $signed(H[4]) ) // 反転させた方がエネルギーが小さくなった場合
spin[invert] <= ~spin[invert];
else
{state_init, state_busy, state_end} <= 3'b001;
......
# annealerについて
2x2,4つのスピンがそれぞれ他の3つのスピンと繋がっている想定で作ってみた.構文エラーは無くしたが,果たして意図した通りに動くかは謎.もっと言えば,エネルギーが悪化するスピンの反転を認めていないので,アニーリングにもなってない代物.
\ No newline at end of file
2x2,4つのスピンがそれぞれ他の3つのスピンと繋がっている想定で作ってみた.構文エラーは無くしたが,果たして意図した通りに動くかは謎.もっと言えば,エネルギーが悪化するスピンの反転を認めていないので,アニーリングにもなってない代物.
verilogの内容を一応pythonでも書いてみたり.
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment