配列を表示したときの値について
Q&A
Closed
解決したいこと
実際に計算された値と、それを渡したあとの値が異なる。
発生している問題・エラー
下に書いてあるように↓ここでハミルトニアンを表示すると。
for(int i=0;i<length; i+=2){
int binary_stage_bulk_copy[S - 2][B + 1] = {0};
int binary_stage_edge_copy[2][B] = {0};
int binary_convert[N];
int is01;
int sign = countLeftOnes(binary_copy, binary_length, binary_length - length - (length + 1) + i + 2);
for(int h=0;h<S-2;h++){
for (int j = 0; j < length+1; j++) {
binary_stage_bulk_copy[h][j] = binary_stage_bulk[h][j];
}
}
for(int h=0;h<2;h++){
for (int j = 0; j < length; j++) {
binary_stage_edge_copy[h][j] = binary_stage_edge[h][j];
}
}
flipBits01_width_dw(binary_stage_edge_copy[0], binary_stage_bulk_copy[0], i, &is01);
ket_connect(binary_convert, binary_stage_edge_copy, binary_stage_bulk_copy, binary_length, length);
int decimal_stage = binaryToDecimal(binary_convert, binary_length);
make_hamiltonian(hamiltonian, sign, index, size, ket_libra_gyakubiki, decimal_stage, t, &is01);
if(is01 != 0){
printf("%d %d %d %lf\n", binary_length - length - (length + 1) + i + 2, ket_libra_junbiki[index], decimal_stage, hamiltonian[ket_libra_gyakubiki[decimal_stage] - 1][index]);
}
}
7 31 151 1.000000
5 47 527 -1.000000
のような符号で出てくるが、下のように別の場所で表示させると
for (int i = 0; i < 20; i++) {
for (int j = 0; j < NUM_KET; j++) {
if(hamiltonian[i][j] != 0){
printf("%d, %d, %lf ", ket_libra_junbiki[i], ket_libra_junbiki[j], hamiltonian[i][j]);
printf("\n");
}
}
printf("\n");
}
31, 91, -1.000000
31, 151, -1.000000
47, 62, 1.000000
47, 107, -1.000000
47, 167, -1.000000
47, 527, -1.000000
のように異なる値が出てくる。
該当するソースコード
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define B 3 //1stage中のサイト数 length 2n+3
#define S 3 //stage
#define N 10 //全サイト数 binary_length B*2+(B+1)*(S-2)
#define NUM_KET 252 //NCM
// ケットベクトルを2進法で保存する配列
int ket[NUM_KET][N] = {0}; // half-filledのケットが入る [index][binary]
int ket_libra_junbiki[NUM_KET] = {0}; // 辞書 [index]⇒decimal 順引き
double _Complex hamiltonian[NUM_KET][NUM_KET] = {0.0};
int ket_index = 0;
// 二進数から10進数への変換関数
int binaryToDecimal(int *binary, int length) {
int decimal = 0;
for (int i = 0; i < length; i++) {
decimal = (decimal << 1) | binary[i];
}
return decimal;
}
void decimalToBinary(int decimal, int *binary, int length) {
for (int i = length - 1; i >= 0; i--) {
binary[i] = decimal & 1;
decimal >>= 1;
}
}
int countLeftOnes(int *binary, int length, int currentIndex) {
int count = 0;
for (int i = currentIndex - 2; i >= 0; i--) {
count += binary[i];
}
int sign = 1 - 2 * (count & 1);
return sign;
}
// ケットベクトルを2進法でket配列に保存する関数
void fillKet(int ones, int *binary, int binary_length, int binary_index, int size, int ket_libra_gyakubiki[size]) {
if (ket_index >= NUM_KET) {
return;
}
if (binary_index >= binary_length) {
return;
}
if (ones > 0) {
// 1を配置してみる
binary[binary_index] = 1;
fillKet(ones - 1, binary, binary_length, binary_index + 1, size, ket_libra_gyakubiki);
if (ones - 1 == 0) {
// onesの分だけ1が埋まったのでketに追加保存
for (int i = 0; i < binary_length; i++) {
ket[ket_index][i] = binary[i];
}
ket_libra_junbiki[NUM_KET - ket_index - 1] = binaryToDecimal(binary, binary_length);
ket_libra_gyakubiki[ket_libra_junbiki[NUM_KET - ket_index - 1]] = NUM_KET - ket_index ;
ket_index++;
}
}
// 0を配置してみる (onesが0でも残りの桁を0で埋める必要がある)
binary[binary_index] = 0;
fillKet(ones, binary, binary_length, binary_index + 1, size, ket_libra_gyakubiki);
}
void flipBits01_width_up(int *binary_1, int *binary_2, int i, int *is01) {
*is01 = (binary_1[i] == 0) && (binary_2[i] == 1);
int flip[2];
flip[0] = binary_1[i]; flip[1] = binary_2[i];
int decimal_flip = binaryToDecimal(flip, 2);
decimal_flip = decimal_flip * (*is01 + 1);
decimalToBinary(decimal_flip, flip, 2);
binary_1[i] = flip[0]; binary_2[i] = flip[1];
}
void flipBits10_width_up(int *binary_1, int *binary_2, int i, int *is10) {
*is10 = (binary_1[i] == 1) && (binary_2[i] == 0);
int flip[2];
flip[0] = binary_1[i]; flip[1] = binary_2[i];
int decimal_flip = binaryToDecimal(flip, 2);
decimal_flip = decimal_flip / (*is10 + 1);
decimalToBinary(decimal_flip, flip, 2);
binary_1[i] = flip[0]; binary_2[i] = flip[1];
}
void flipBits01_width_dw(int *binary_1, int *binary_2, int i, int *is01) {
*is01 = (binary_1[i] == 0) && (binary_2[i + 1] == 1);
int flip[2];
flip[0] = binary_1[i]; flip[1] = binary_2[i + 1];
int decimal_flip = binaryToDecimal(flip, 2);
decimal_flip = decimal_flip * (*is01 + 1);
decimalToBinary(decimal_flip, flip, 2);
binary_1[i] = flip[0]; binary_2[i + 1] = flip[1];
}
void flipBits10_width_dw(int *binary_1, int *binary_2, int i, int *is10) {
*is10 = (binary_1[i] == 1) && (binary_2[i + 1] == 0);
int flip[2];
flip[0] = binary_1[i]; flip[1] = binary_2[i + 1];
int decimal_flip = binaryToDecimal(flip, 2);
decimal_flip = decimal_flip / (*is10 + 1);
decimalToBinary(decimal_flip, flip, 2);
binary_1[i] = flip[0]; binary_2[i + 1] = flip[1];
}
void make_hamiltonian(double _Complex hamiltonian[NUM_KET][NUM_KET], int sign, int index, int size, int ket_libra_gyakubiki[size], int decimal, double t, int *is) {
hamiltonian[ket_libra_gyakubiki[decimal] - 1][index] += -t * sign * (*is);
}
void ket_separate(int *binary, int binary_stage_edge[2][B], int binary_stage_bulk[S - 2][B + 1], int binary_length, int length){
for(int i=0;i<length;i++){
binary_stage_edge[0][i] = binary[i];
binary_stage_edge[1][i] = binary[binary_length - length + i];
}
for(int stage = 0; stage<S-2; stage++){
for(int i=0; i<length + 1; i++){
binary_stage_bulk[stage][i] = binary[i + (length + 1)*stage + length];
}
}
}
void ket_connect(int *binary, int binary_stage_edge[2][B], int binary_stage_bulk[S - 2][B + 1],int binary_length, int length){
for(int i=0;i<length;i++){
binary[i] = binary_stage_edge[0][i];
binary[binary_length - length + i] = binary_stage_edge[1][i];
}
for(int stage = 0; stage<S-2; stage++){
for(int i=0; i<length+1; i++){
binary[i + (length + 1)*stage + length] = binary_stage_bulk[stage][i];
}
}
}
void matrix_element(int *binary, double _Complex hamiltonian[NUM_KET][NUM_KET], int binary_length, int length, int index, int size, int ket_libra_gyakubiki[size], double t) {
decimalToBinary(ket_libra_junbiki[index], binary, binary_length);
int static binary_stage_edge[2][B] = {0};
int static binary_stage_bulk[S - 2][B + 1] = {0};
ket_separate(binary, binary_stage_edge, binary_stage_bulk, binary_length, length);
int binary_copy[N] = {0};
for(int i=0;i<binary_length;i++){
binary_copy[i] = binary[i];
}
for(int i=0;i<length; i+=2){
int binary_stage_bulk_copy[S - 2][B + 1] = {0};
int binary_stage_edge_copy[2][B] = {0};
int binary_convert[N];
int is01;
int sign = countLeftOnes(binary_copy, binary_length, binary_length - length - (length + 1) + i + 1);
for(int h=0;h<S-2;h++){
for (int j = 0; j < length+1; j++) {
binary_stage_bulk_copy[h][j] = binary_stage_bulk[h][j];
}
}
for(int h=0;h<2;h++){
for (int j = 0; j < length; j++) {
binary_stage_edge_copy[h][j] = binary_stage_edge[h][j];
}
}
flipBits01_width_up(binary_stage_edge_copy[1], binary_stage_bulk_copy[S - 3], i, &is01);
ket_connect(binary_convert, binary_stage_edge_copy, binary_stage_bulk_copy, binary_length, length);
int decimal_stage = binaryToDecimal(binary_convert, binary_length);
make_hamiltonian(hamiltonian, sign, index, size, ket_libra_gyakubiki, decimal_stage, t, &is01);
}
for(int i=0;i<length; i+=2){
int binary_stage_bulk_copy[S - 2][B + 1] = {0};
int binary_stage_edge_copy[2][B] = {0};
int binary_convert[N];
int is10;
int sign = countLeftOnes(binary_copy, binary_length, binary_length - length + i + 1);
for(int h=0;h<S-2;h++){
for (int j = 0; j < length+1; j++) {
binary_stage_bulk_copy[h][j] = binary_stage_bulk[h][j];
}
}
for(int h=0;h<2;h++){
for (int j = 0; j < length; j++) {
binary_stage_edge_copy[h][j] = binary_stage_edge[h][j];
}
}
flipBits10_width_up(binary_stage_edge_copy[1], binary_stage_bulk_copy[S - 3], i, &is10);
ket_connect(binary_convert, binary_stage_edge_copy, binary_stage_bulk_copy, binary_length, length);
int decimal_stage = binaryToDecimal(binary_convert, binary_length);
make_hamiltonian(hamiltonian, sign, index, size, ket_libra_gyakubiki, decimal_stage, t, &is10);
}
for(int i=0;i<length; i+=2){
int binary_stage_bulk_copy[S - 2][B + 1] = {0};
int binary_stage_edge_copy[2][B] = {0};
int binary_convert[N];
int is01;
int sign = countLeftOnes(binary_copy, binary_length, binary_length - length - (length + 1) + i + 2);
for(int h=0;h<S-2;h++){
for (int j = 0; j < length+1; j++) {
binary_stage_bulk_copy[h][j] = binary_stage_bulk[h][j];
}
}
for(int h=0;h<2;h++){
for (int j = 0; j < length; j++) {
binary_stage_edge_copy[h][j] = binary_stage_edge[h][j];
}
}
flipBits01_width_dw(binary_stage_edge_copy[0], binary_stage_bulk_copy[0], i, &is01);
ket_connect(binary_convert, binary_stage_edge_copy, binary_stage_bulk_copy, binary_length, length);
int decimal_stage = binaryToDecimal(binary_convert, binary_length);
make_hamiltonian(hamiltonian, sign, index, size, ket_libra_gyakubiki, decimal_stage, t, &is01);
if(is01 != 0){
// printf("%d %d %d %d\n", binary_length - length - (length + 1) + i + 2, ket_libra_junbiki[index], decimal_stage, sign);
printf("%d %d %d %lf\n", binary_length - length - (length + 1) + i + 2, ket_libra_junbiki[index], decimal_stage, hamiltonian[ket_libra_gyakubiki[decimal_stage] - 1][index]);
}
}
for(int i=0;i<length; i+=2){
int binary_stage_bulk_copy[S - 2][B + 1] = {0};
int binary_stage_edge_copy[2][B] = {0};
int binary_convert[N];
int is10;
int sign = countLeftOnes(binary_copy, binary_length, i + 1);
for(int h=0;h<S-2;h++){
for (int j = 0; j < length+1; j++) {
binary_stage_bulk_copy[h][j] = binary_stage_bulk[h][j];
}
}
for(int h=0;h<2;h++){
for (int j = 0; j < length; j++) {
binary_stage_edge_copy[h][j] = binary_stage_edge[h][j];
}
}
flipBits10_width_dw(binary_stage_edge_copy[0], binary_stage_bulk_copy[0], i, &is10);
ket_connect(binary_convert, binary_stage_edge_copy, binary_stage_bulk_copy, binary_length, length);
int decimal_stage = binaryToDecimal(binary_convert, binary_length);
make_hamiltonian(hamiltonian, sign, index, size, ket_libra_gyakubiki, decimal_stage, t, &is10);
}
}
int main() {
int binary[N]; // 二進法が入る
int M;
int size = pow(2, N);
int ones; // 1の個数
int ket_libra_gyakubiki[size]; // 辞書 [decimal]⇒index 逆引き
// ket_libra_gyakubiki配列を0で初期化
for (int i = 0; i < size; i++) {
ket_libra_gyakubiki[i] = 0;
}
double t = 1.0;
if (N % 2 == 0) {
M = N / 2;
} else {
M = N / 2 + 1;
}
// ケットベクトルの生成と表示
fillKet(M, binary, N, 0, size, ket_libra_gyakubiki);
for (int index = 0; index < NUM_KET; index++) {
matrix_element(binary, hamiltonian, N, B, index, size, ket_libra_gyakubiki, t);
}
for (int i = 0; i < 20; i++) {
for (int j = 0; j < NUM_KET; j++) {
// printf("%d, %d, %lf ", ket_libra_junbiki[i], ket_libra_junbiki[j], hamiltonian[i][j]);
if(hamiltonian[i][j] != 0){
printf("%d, %d, %lf ", ket_libra_junbiki[i], ket_libra_junbiki[j], hamiltonian[i][j]);
printf("\n");
}
}
printf("\n");
}
return 0;
}
自分で試したこと
関数内で用いられている変数を確認したところ、matrix_elemen()の中ではきちんと計算されていたが、外に出すと、値が全くあわなくなったことを確認した。
またすべての組み合わせも確認したが、なぜか下の表示では異なる値が出た。