セグメの原因がわからない。
Q&A
Closed
解決したいこと
セグメの原因がわからない。
以下のコードは物理現象を再現することを目的として、電子の生成消滅演算子を再現するものです。
また、その演算子を用いて固有ベクトルに変更を加えています。
以下のコードではN=10でコアダンプするが、Nがそれ以下の偶数の場合うまく起動するようになります。
発生している問題・エラー
Segmentation fault
gdbでは以下のようになります。
Program received signal SIGSEGV, Segmentation fault.
0x00000000004050ed in main ()
(gdb) bt
#0 0x00000000004050ed in main ()
(gdb)
コード上では
creation_vector_up(), annihilatioin_vector_up(),
creation_vector_down(), annihilatioin_vector_down()
を二つ以上実行するとセグメします。内容では
void annihilation_up_eigenvector(int binary_up[N], int binary_down[N], int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_annihilation_up[size_annihilation_up], int index, int i_e_position){
int binary_annihilation[L] = {0}, binary_up_copy[N] = {0}; copy_int(N, binary_up, binary_up_copy);
annihilation_operator(binary_up, binary_up_copy, i_e_position); spin_connect(binary_annihilation, binary_up_copy, binary_down);
int decimal = binaryToDecimal(binary_annihilation, L), index_annihilaton_up = (search_gyakubiki[binaryToDecimal(binary_up_copy, N)] - 1) * NUM_KET_down
+ search_gyakubiki[binaryToDecimal(binary_down, N)];
⇒ (search_2D[index] != decimal) ? eigenvector_annihilation_up[index_annihilaton_up - 1] += eigenvector[index]
* countCrossing_new(binary_up, binary_up_copy, i_e_position): 0;
}
⇒の箇所をコメントアウトすると動くようになります。
配列の逸脱が考えられたためindex, index_annihilation_up が負、または配列よりも大きくなっていることが考えられセーフティーを設けたが、解決には至らなかった。
該当するソースコード
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <complex.h>
#include <stdlib.h>
#define Lanczos_stop 5
#define N 10
#define L 2*N
#define Cn 100
int NUM_KET_up = 0, NUM_KET_down = 0, NUM_KET_creation_up = 0, NUM_KET_creation_down = 0, NUM_KET_annihilation_up = 0, NUM_KET_annihilation_down = 0;
int size = 0, size_creation_up = 0, size_creation_down = 0, size_annihilation_up = 0, size_annihilation_down = 0, size_gyaku = 0;
int M = 0, limit = 0; double t_opt = 1.0;
void shokika_double(int length, double hairetu[length]){
for(int i = 0; i < length; i++){
hairetu[i] = 0.0;
}
}
void shokika_int(int length, int hairetu[length]){
for(int i = 0; i < length; i++){
hairetu[i] = 0.0;
}
}
void shokika_matrix(int length, double hairetu[length][length]){
for(int i = 0; i < length; i++){
for(int j = 0; j < length; j++){
hairetu[i][j] = 0.0;
}
}
}
void shokika_vector_convert(int length, double eigenvector_spin[N][length]){
for(int i = 0; i < N; i++){
for(int j = 0; j < length; j++){
eigenvector_spin[i][j] = 0.0;
}
}
}
void copy_double(int length, double hairetu_before[length], double hairetu_after[length]){
for(int i = 0; i < length; i++){
hairetu_after[i] = hairetu_before[i];
}
}
void copy_double_complex(int length, double complex hairetu_before[length], double complex hairetu_after[length]){
for(int i = 0; i < length; i++){
hairetu_after[i] = hairetu_before[i];
}
}
void copy_int(int length, int hairetu_before[length], int hairetu_after[length]){
for(int i = 0; i < length; i++){
hairetu_after[i] = hairetu_before[i];
}
}
int combination(int n, int r) {
int result = 1;
for (int i = 1; i <= r; i++) {
result *= (n - i + 1);
result /= i;
}
return result;
}
double dot_product(int length, double vector_1[length], double vector_2[length]){ //内積
double dot = 0.0;
for(int i = 0; i < length; i++){
dot += vector_1[i] * vector_2[i];
}
return dot;
}
double norm(int length, double vector[length]){ //ノルム
double norm = 0.0;
norm = dot_product(length, vector, vector);
norm = pow(norm, 0.5);
return norm;
}
void normalization(int length, double vector[length]){ //ヴェクトルの正規化
double n = 0.0;
n = norm(length, vector);
for(int i = 0; i < length; i++){
vector[i] = vector[i] / n;
}
}
//random vector creation
void r_v_c(int size_length, double vector_q_0[size_length]){
// 乱数の初期化
srand(time(NULL));
// ランダムな成分からなるベクトルを生成
for (int i = 0; i < size_length; i++) {
vector_q_0[i] = ((double)rand() / RAND_MAX) * 2.0 - 1.0;
}
double norm = 0.0;
for (int i = 0; i < size_length; i++) {
norm += vector_q_0[i] * vector_q_0[i];
}
norm = sqrt(norm);
for (int i = 0; i < size_length; i++) {
vector_q_0[i] /= norm;
}
}
int countCrossing_new(int binary_1[N], int binary_2[N], int index_left) { //operator
int andresult[N] = {0};
int count = 0, sign = 1;
for(int i = 0; i < index_left; i++){
andresult[i] = binary_1[i] & binary_2[i];
}
for(int i = 0; i < N; i++){
count += andresult[i];
}
sign = pow(-1, count);
return sign;
}
// 二進数から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;
}
}
void spin_separate(int binary[L], int binary_up[N], int binary_down[N]){
for(int i = 0; i < N; i++){
binary_up[i] = binary[i];
binary_down[i] = binary[i + N];
}
}
void spin_connect(int binary[L], int binary_up[N], int binary_down[N]){
for(int i = 0; i < N; i++){
binary[i] = binary_up[i];
binary[i + N] = binary_down[i];
}
}
int get(int decimal, int SPIN_up, int SPIN_down){
int i_up = 0, i_down = 0, binary[L] = {0}; decimalToBinary(decimal, binary, L);
for(int i = 0; i < N; i++){
i_up += binary[i]; i_down += binary[i + N];
}
int check_spin = - 1; (i_up == SPIN_up && i_down == SPIN_down) ? check_spin = 0: (check_spin = - 1);
return check_spin;
}
int get_2(int decimal, int i_spin){
int binary[N] = {0};
for(int i = 0; i < N; i++){
binary[N - i - 1] = (decimal % 2);
decimal /= 2;
}
int num_e = 0;
for(int i = 0; i < N; i++){
num_e += binary[i];
}
int check_spin = - 1;
(num_e == i_spin) ? check_spin = 0: (check_spin = - 1);
return check_spin;
}
void make_search(int size_length, int search_junbiki[size_length], int SPIN_up, int SPIN_down){
int i_cnt = 0;
for(int i = 0; i < pow(2, L) && i_cnt < size_length; i++){
int check_spin = get(i, SPIN_up, SPIN_down);
(check_spin == 0) ? (search_junbiki[i_cnt] = i, i_cnt++): 0;
}
}
void make_gyakubiki(int search_gyakubiki[size_gyaku]){
for(int i_spin = 0; i_spin < N + 1; i_spin++){
int i_cnt = 0; int size_cnt = combination(N, i_spin); size_gyaku = (int)(pow(2, N));
for(int i = 0; i < size_gyaku && i_cnt < size_cnt; i++){
int check_spin = get_2(i, i_spin); (check_spin == 0) ? (search_gyakubiki[i] = i_cnt + 1, i_cnt++): 0;
}
}
}
void search(int search_2D[size],
int search_creation_up[size_creation_up], int search_creation_down[size_creation_down],
int search_annihilation_up[size_annihilation_up], int search_annihilation_down[size_annihilation_down], int SPIN_up, int SPIN_down){
shokika_int(size, search_2D);
shokika_int(size_creation_up, search_creation_up); shokika_int(size_creation_down, search_creation_down);
shokika_int(size_annihilation_up, search_annihilation_up); shokika_int(size_annihilation_down, search_annihilation_down);
make_search(size, search_2D, SPIN_up, SPIN_down);
make_search(size_creation_up, search_creation_up, SPIN_up + 1, SPIN_down);
make_search(size_annihilation_up, search_annihilation_up, SPIN_up - 1, SPIN_down);
make_search(size_creation_down, search_creation_down, SPIN_up, SPIN_down + 1);
make_search(size_annihilation_down, search_annihilation_down, SPIN_up, SPIN_down - 1);
}
//生成・消滅演算子
void creation_operator(int binary_bf[N], int binary_af[N], int i_e_position){
(binary_bf[i_e_position] == 0) ? binary_af[i_e_position] = 1 : 0;
}
void annihilation_operator(int binary_bf[N], int binary_af[N], int i_e_position){
(binary_bf[i_e_position] == 1) ? binary_af[i_e_position] = 0 : 0;
}
void creation_up_eigenvector(int binary_up[N], int binary_down[N], int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_creation_up[size_creation_up], int index, int i_e_position){
int binary_creation[L] = {0}, binary_up_copy[N] = {0}; copy_int(N, binary_up, binary_up_copy);
creation_operator(binary_up, binary_up_copy, i_e_position); spin_connect(binary_creation, binary_up_copy, binary_down);
int decimal = binaryToDecimal(binary_creation, L), index_creation_up = (search_gyakubiki[binaryToDecimal(binary_up_copy, N)] - 1) * NUM_KET_down
+ search_gyakubiki[binaryToDecimal(binary_down, N)];
(search_2D[index] != decimal && index_creation_up - 1 >= 0 && index_creation_up - 1 < size_creation_up) ?
eigenvector_creation_up[index_creation_up - 1] += eigenvector[index] * countCrossing_new(binary_up, binary_up_copy, i_e_position): 0;
// (search_2D[index] != decimal) ? printf("%d %d %d\n", index, index_creation_up, binaryToDecimal(binary_creation, L)): 0;
}
void annihilation_up_eigenvector(int binary_up[N], int binary_down[N], int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_annihilation_up[size_annihilation_up], int index, int i_e_position){
int binary_annihilation[L] = {0}, binary_up_copy[N] = {0}; copy_int(N, binary_up, binary_up_copy);
annihilation_operator(binary_up, binary_up_copy, i_e_position); spin_connect(binary_annihilation, binary_up_copy, binary_down);
int decimal = binaryToDecimal(binary_annihilation, L), index_annihilaton_up = (search_gyakubiki[binaryToDecimal(binary_up_copy, N)] - 1) * NUM_KET_down
+ search_gyakubiki[binaryToDecimal(binary_down, N)];
(search_2D[index] != decimal && index_annihilaton_up - 1 >= 0 && index_annihilaton_up - 1 < size_annihilation_up) ?
eigenvector_annihilation_up[index_annihilaton_up - 1] += eigenvector[index] * countCrossing_new(binary_up, binary_up_copy, i_e_position): 0;
// (search_2D[index] != decimal) ? printf("%d %d %d %d\n", index, search_2D[index], index_annihilaton_up - 1, binaryToDecimal(binary_annihilation, L)): 0;
}
void creation_down_eigenvector(int binary_up[N], int binary_down[N], int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_creation_down[size_creation_down], int index, int i_e_position){
int binary_creation[L] = {0}, binary_down_copy[N] = {0}; copy_int(N, binary_down, binary_down_copy);
creation_operator(binary_down, binary_down_copy, i_e_position); spin_connect(binary_creation, binary_up, binary_down_copy);
int decimal = binaryToDecimal(binary_creation, L), index_creation_down = (search_gyakubiki[binaryToDecimal(binary_up, N)] - 1) * NUM_KET_creation_down
+ search_gyakubiki[binaryToDecimal(binary_down_copy, N)];
(search_2D[index] != decimal && index_creation_down - 1 >= 0 && index_creation_down - 1 < size_creation_down) ?
eigenvector_creation_down[index_creation_down - 1] += eigenvector[index] * countCrossing_new(binary_down, binary_down_copy, i_e_position): 0;
// printf("%d %d %d\n", index, index_creation_down, decimal);
}
void annihilation_down_eigenvector(int binary_up[N], int binary_down[N], int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_annihilation_down[size_annihilation_down], int index, int i_e_position){
int binary_annihilation[L] = {0}, binary_down_copy[N] = {0}; copy_int(N, binary_down, binary_down_copy);
annihilation_operator(binary_down, binary_down_copy, i_e_position); spin_connect(binary_annihilation, binary_up, binary_down_copy);
int decimal = binaryToDecimal(binary_annihilation, L), index_annihilaton_down = (search_gyakubiki[binaryToDecimal(binary_up, N)] - 1) * NUM_KET_annihilation_down
+ search_gyakubiki[binaryToDecimal(binary_down_copy, N)];
(search_2D[index] != decimal && index_annihilaton_down - 1 >= 0 && index_annihilaton_down - 1 < size_annihilation_down) ?
eigenvector_annihilation_down[index_annihilaton_down - 1] += eigenvector[index] * countCrossing_new(binary_down, binary_down_copy, i_e_position): 0;
// printf("%d %d %d\n", index, index_annihilaton_down, binaryToDecimal(binary_annihilation, L));
}
void creation_up(int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_creation_up[size_creation_up], int i_e_position){
int binary[L] = {0}, binary_up[N] = {0}, binary_down[N] = {0};
for(int index = 0; index < size; index++){
decimalToBinary(search_2D[index], binary, L); spin_separate(binary, binary_up, binary_down);
creation_up_eigenvector(binary_up, binary_down, search_2D, search_gyakubiki, eigenvector,
eigenvector_creation_up, index, i_e_position);
// printf("%lf\n",eigenvector[index]);
}
}
void annihilation_up(int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_annihilation_up[size_annihilation_up], int i_e_position){
int binary[L] = {0}, binary_up[N] = {0}, binary_down[N] = {0};
for(int index = 0; index < size; index++){
decimalToBinary(search_2D[index], binary, L); spin_separate(binary, binary_up, binary_down);
annihilation_up_eigenvector(binary_up, binary_down, search_2D, search_gyakubiki, eigenvector,
eigenvector_annihilation_up, index, i_e_position);
// printf("%d %d\n", search_2D[index], index);
}
}
void creation_down(int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_creation_down[size_creation_down], int i_e_position){
int binary[L] = {0}, binary_up[N] = {0}, binary_down[N] = {0};
for(int index = 0; index < size; index++){
decimalToBinary(search_2D[index], binary, L); spin_separate(binary, binary_up, binary_down);
creation_down_eigenvector(binary_up, binary_down, search_2D, search_gyakubiki, eigenvector,
eigenvector_creation_down, index, i_e_position);
// printf("%lf\n",eigenvector[index]);
}
}
void annihilation_down(int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_annihilation_down[size_annihilation_down], int i_e_position){
int binary[L] = {0}, binary_up[N] = {0}, binary_down[N] = {0};
for(int index = 0; index < size; index++){
decimalToBinary(search_2D[index], binary, L); spin_separate(binary, binary_up, binary_down);
annihilation_down_eigenvector(binary_up, binary_down, search_2D, search_gyakubiki, eigenvector,
eigenvector_annihilation_down, index, i_e_position);
// printf("%d %d\n", search_2D[index], index);
}
}
void creation_vector_up(int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_creation_up[N][size_creation_up]){
for(int i_e_position = 0; i_e_position < N; i_e_position++){
creation_up(search_2D, search_gyakubiki, eigenvector, eigenvector_creation_up[i_e_position], i_e_position);
}
}
void creation_vector_down(int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_creation_down[N][size_creation_down]){
for(int i_e_position = 0; i_e_position < N; i_e_position++){
creation_down(search_2D, search_gyakubiki, eigenvector, eigenvector_creation_down[i_e_position], i_e_position);
}
}
void annihilatioin_vector_up(int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_annihilation_up[N][size_annihilation_up]){
for(int i_e_position = 0; i_e_position < N; i_e_position++){
annihilation_up(search_2D, search_gyakubiki, eigenvector, eigenvector_annihilation_up[i_e_position], i_e_position);
}
}
void annihilatioin_vector_down(int search_2D[size], int search_gyakubiki[size_gyaku],
double eigenvector[size], double eigenvector_annihilation_down[N][size_annihilation_down]){
for(int i_e_position = 0; i_e_position < N; i_e_position++){
annihilation_down(search_2D, search_gyakubiki, eigenvector, eigenvector_annihilation_down[i_e_position], i_e_position);
}
}
int main(){
double U_t = 1.0; int size_gyaku = (int)(pow(2, N));
int search_gyakubiki[size_gyaku]; shokika_int(size_gyaku, search_gyakubiki); make_gyakubiki(search_gyakubiki);
int SPIN_up = 5, SPIN_down = 5, filling = SPIN_up + SPIN_down;
NUM_KET_up = combination(N, SPIN_up); NUM_KET_down = combination(N, SPIN_down);
NUM_KET_creation_up = combination(N, SPIN_up + 1); NUM_KET_creation_down = combination(N, SPIN_down + 1);
NUM_KET_annihilation_up = combination(N, SPIN_up - 1); NUM_KET_annihilation_down = combination(N, SPIN_down - 1);
size = NUM_KET_up * NUM_KET_down;
size_creation_up = NUM_KET_creation_up * NUM_KET_down; size_creation_down = NUM_KET_up * NUM_KET_creation_down;
size_annihilation_up = NUM_KET_annihilation_up * NUM_KET_down; size_annihilation_down = NUM_KET_up * NUM_KET_annihilation_down;
//辞書 normal creation annihilatioin
int search_2D[size];
int search_creation_up[size_creation_up], search_creation_down[size_creation_down];
int search_annihilation_up[size_annihilation_up], search_annihilation_down[size_annihilation_down];
search(search_2D, search_creation_up, search_creation_down, search_annihilation_up, search_annihilation_down, SPIN_up, SPIN_down);
double vector[size]; r_v_c(size, vector);
double eigenvector_creation_up[N][size_creation_up], eigenvector_annihilation_up[N][size_annihilation_up];
double eigenvector_creation_down[N][size_creation_down], eigenvector_annihilation_down[N][size_annihilation_down];
shokika_vector_convert(size_creation_up, eigenvector_creation_up); shokika_vector_convert(size_annihilation_up, eigenvector_annihilation_up);
shokika_vector_convert(size_creation_down, eigenvector_creation_down); shokika_vector_convert(size_annihilation_up, eigenvector_annihilation_down);
creation_vector_up(search_2D, search_gyakubiki, vector, eigenvector_creation_up);
annihilatioin_vector_up(search_2D, search_gyakubiki, vector, eigenvector_annihilation_up);
// creation_vector_down(search_2D, search_gyakubiki, vector, eigenvector_creation_down);
// annihilatioin_vector_down(search_2D, search_gyakubiki, vector, eigenvector_annihilation_down);
return 0;
}
自分で試したこと
正直、いろいろ確認しましたがよくわからなくなってしまったため、岡目八目的にアドバイスをいただきたく質問しました。
環境はメモリ8GB、windouws11,WSL上でoneAPIを用いて計算しております。
申し訳ございませんが、よろしければご助言いただけますと幸いです。
(20240508での問題は解決できました。)