kisara11235
@kisara11235

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

配列を表示したときの値について

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()の中ではきちんと計算されていたが、外に出すと、値が全くあわなくなったことを確認した。
またすべての組み合わせも確認したが、なぜか下の表示では異なる値が出た。

0

1Answer

main()の表示部分での [i][j]が逆と思います。

-printf("%d, %d, %lf ", ket_libra_junbiki[i], ket_libra_junbiki[j], hamiltonian[i][j]);
+printf("%d, %d, %lf ", ket_libra_junbiki[i], ket_libra_junbiki[j], hamiltonian[j][i]);

どうでしょう?

0Like

Comments

  1. @kisara11235

    Questioner

    返信が遅くなり申し訳ないです。
    結果としては順番が変わっただけで、配列の表示としては行がi、列にjを表示したいので解決はしていないです。

  2. 結果としては順番が変わっただけで

    行列に対する値が以前と変わらず異なる値でしょうか? 
     (行値,列値,値 = 31, 151, 1.000000 が  行値,列値,値 31, 151, -1.000000 表示される様な)  
    もう少し具体的にコメントか正解の結果提示をお願いします。

    配列の表示としては行がi、列にjを表示したい
    "行列に対する値は問題ないけど表示をhamiltonian[i][j]で行いたい’と解釈してコメントします。"

    元プログラムが
    main()で iが行で jが列とすると

    printf("%d, %d, %lf ", ket_libra_junbiki[i], ket_libra_junbiki[j], hamiltonian[i][j]);
    

    ket_libra_junbiki[i] =>iを使ってるから列値
    ket_libra_junbiki[j] =>jを使ってるから列値
    hamiltonian[i][j] =>hamiltonian[行][列]
    この表示は、行値, 列値, hamiltonian[行][列] の順となります。
    関数内表示

    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]);
    

    hamiltonian[行][列]とすると indexが列の情報であることがわかります。また、ket_libra_gyakubiki[decimal_stage]を行情報として扱ってるので 、decimal_stageは行値なのでしょう。

    binary_length - length - (length + 1) + i + 2 => *
    ket_libra_junbiki[index] => indexを使ってるから列情報
    decimal_stage => 行値
    hamiltonian[ket_libra_gyakubiki[decimal_stage] - 1][index] => hamiltonian[行][列]
    この表示は、 *、列data、多分 行data, hamiltonian[行][列] の順となります。

    これらから 関数内のデータと関数外のデータの表示順序(行data,列dataが逆)が違うことがわかります。
    順序が反対に見えたので、関数内表示を正しい順序と見て、回答を[i][j]が反対つまり [列][行]で回答しました。

    関数外の表示をそのままにするのであれば、関数内の表示順序が誤っているのではないでしょうか?
    元のコードに以下の修正すれば良いです、

    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]);
    printf("%d %d %d %lf\n", binary_length - length - (length + 1) + i + 2, decimal_stage, ket_libra_junbiki[index], hamiltonian[ket_libra_gyakubiki[decimal_stage] - 1][index]);
    

    そもそも関数内と関数外で値を確認しているということは、関数外でなにかしらの値に異常があったと思いますので、’こうなるはずが このようになる’の情報提示があればいいのですが・・・・

  3. @kisara11235

    Questioner

    返信ありがとうございます。
    関数ミスでした、申し訳ございません。指摘していただいたところですが、hamiltonian{j}{i}とすれば-1.0000のように表示されました。

    しかし、根本的な原因はここではなく、countleft関数にありました。

    お騒がせ致しました。

Your answer might help someone💌