int main(int np, char** p) { double * current, *error; double * current_pre, *error_pre;//preliminary input int i,j,k,t; FILE* file_in_current; FILE* file_in_matrix; FILE* file_out; FILE* file_out_excl; FILE* file_const; int par_int; double par_double; double int_result, int_error; double center; double omega; gsl_vector * R; gsl_vector * omega_R; //for real center definition gsl_vector * Q; gsl_vector * Q_initial; gsl_matrix * S;//covariance matrix gsl_matrix * S_pre;//covariance matrix (preliminary input) file_in_current=fopen(p[2],"r"); file_in_matrix=fopen(p[3],"r"); sprintf(directory,"%s", p[4]); Nt_2=atoi(p[1]); dNt_2=(double) Nt_2; //reading parameters file file_const=fopen(p[5],"r"); //double accuracy=1e-8; parse_option(file_const,"%le",&accuracy); //long int N_int_steps=1000000; parse_option(file_const,"%ld",&N_int_steps); //double omega_plot_delta=0.01; parse_option(file_const,"%le",&omega_plot_delta); //double omega_plot_limit=30.0; parse_option(file_const,"%le",&omega_plot_limit); //double lambda=1.0; parse_option(file_const,"%le",&lambda); //double center_start=3.0; parse_option(file_const,"%le",¢er_start); //double center_stop=18.01; parse_option(file_const,"%le",¢er_stop); //double center_delta=3.0; parse_option(file_const,"%le",¢er_delta); //int flag_exclude parse_option(file_const,"%d",&flag_exclude_delta); //int count_start parse_option(file_const,"%d",&count_start_exclude); //int flag_model parse_option(file_const,"%d",&flag_model); if(flag_model==1) { fscanf(file_const, "%d", &N_valid_points); points_numbers=(int*) calloc(N_valid_points, sizeof(int)); for(i=0;i<N_valid_points; i++) fscanf(file_const, "%d", &(points_numbers[i])); } else { N_valid_points=Nt_2; points_numbers=(int*) calloc(N_valid_points, sizeof(int)); for(i=0;i<N_valid_points; i++) points_numbers[i]=i+1; } fclose(file_const); file_out=fopen_control("parameters.txt","w"); fprintf(file_out,"number of points (=half of physical number of timeslices)=%d\n", Nt_2); fprintf(file_out,"file with current correlator:\n %s\n", p[2]); fprintf(file_out,"file with covariance matrix:\n %s\n", p[3]); fprintf(file_out,"path for output:\n %s\n", p[4]); fprintf(file_out,"file with parameters:\n %s\n", p[5]); //double accuracy=1e-8; fprintf(file_out,"accuracy=%.15le\n",accuracy); //long int N_int_steps=1000000; fprintf(file_out,"Number os steps in numerical interation=%ld\n",N_int_steps); //double omega_plot_delta=0.01; fprintf(file_out,"Step in plots of resolution function(omega)=%.15le\n",omega_plot_delta); //double omega_plot_limit=30.0; fprintf(file_out,"Limit in plots of resolution function(omega)=%.15le\n",omega_plot_limit); //double lambda=1.0; fprintf(file_out,"Lambda(regularization)=%.15le\n(=1 - without regularization)\n",lambda); //double center_start=3.0; fprintf(file_out,"Center of resolution function starts from = %.15le\n",center_start); //double center_stop=18.01; fprintf(file_out,"Center of resolution function stops at %.15le\n",center_stop); //double center_delta=3.0; fprintf(file_out,"Step in center of resolution function = %.15le\n",center_delta); //flag_exclude_delta; fprintf(file_out,"TExclude or not (1 or 0) initial delta finction %d\n",flag_exclude_delta); //count_start_exclude fprintf(file_out,"Number of iteration for center to start exclusion of initial delta-function = %d\n",count_start_exclude); //model_flag; fprintf(file_out,"Take into account all (0) or not all (1) timeslices = %d\n",flag_model); if(flag_model==1) { fprintf(file_out,"Number of timeslices taken into account = %d\n",N_valid_points); for(i=0;i<N_valid_points;i++) { fprintf(file_out,"%d\n",points_numbers[i]); } } fclose(file_out); current_pre=(double*) calloc(Nt_2, sizeof(double)); error_pre=(double*) calloc(Nt_2, sizeof(double)); S_pre=gsl_matrix_calloc(Nt_2, Nt_2); for(t=1;t<=Nt_2;t++) { fscanf(file_in_current, "%d", &par_int); fscanf(file_in_current, "%le", &par_double); current_pre[t-1]=par_double; fscanf(file_in_current, "%le", &par_double); error_pre[t-1]=par_double; } fclose(file_in_current); file_out=fopen_control("current_control_pre.txt","w"); for(t=0;t<Nt_2;t++) { fprintf(file_out,"%d\t%.15le\t%.15le\n", t, current_pre[t], error_pre[t]); } fclose(file_out); for(i=1;i<=Nt_2;i++) for(t=1;t<=Nt_2;t++) { fscanf(file_in_matrix, "%le", &par_double); gsl_matrix_set(S_pre, i-1, t-1, par_double); } fclose(file_in_matrix); file_out=fopen_control("cov_matrix_control_pre.txt","w"); for(i=0;i<Nt_2;i++){ for(t=0;t<Nt_2;t++) { fprintf(file_out,"%.15le\t", gsl_matrix_get(S_pre, i,t)); } fprintf(file_out,"\n"); } fclose(file_out); //conversion to real arrays taken into account only certain timeslices /////////////////////////////////////////// /////////////////////////////////////////// /////////////////////////////////////////// { int count1, count2; Nt_2_pre=Nt_2; dNt_2_pre=(double) Nt_2_pre; if(flag_model==1) { Nt_2=N_valid_points; dNt_2=(double)Nt_2; } current=(double*) calloc(Nt_2, sizeof(double)); error=(double*) calloc(Nt_2, sizeof(double)); S=gsl_matrix_calloc(Nt_2, Nt_2); for(count1=0;count1<Nt_2;count1++) { current[count1]=current_pre[points_numbers[count1]-1]; error[count1]=error_pre[points_numbers[count1]-1]; } fclose(file_in_current); file_out=fopen_control("current_control_fin.txt","w"); for(t=0;t<Nt_2;t++) { fprintf(file_out,"%d\t%.15le\t%.15le\n", points_numbers[t], current[t], error[t]); } fclose(file_out); for(count1=0;count1<Nt_2;count1++) for(count2=0;count2<Nt_2;count2++) { par_double=gsl_matrix_get(S_pre,points_numbers[count1]-1, points_numbers[count2]-1); gsl_matrix_set(S, count1, count2, par_double); } fclose(file_in_matrix); file_out=fopen_control("cov_matrix_control.txt","w"); for(i=0;i<Nt_2;i++){ for(t=0;t<Nt_2;t++) { fprintf(file_out,"%.15le\t", gsl_matrix_get(S, i,t)); } fprintf(file_out,"\n"); } fclose(file_out); } //end of conversion /////////////////////////////////////////// /////////////////////////////////////////// /////////////////////////////////////////// //integration to obtain R vector file_out=fopen_control("R_control.txt","w"); R=gsl_vector_alloc(Nt_2); { gsl_integration_workspace * w = gsl_integration_workspace_alloc (N_int_steps); gsl_function F; F.function = &kernel_int; for(t=1;t<=Nt_2;t++) { F.params = &t; gsl_integration_qagiu (&F, 0.0, accuracy, accuracy, N_int_steps, w, &int_result, &int_error); gsl_vector_set(R,t-1,int_result); fprintf(file_out,"%d\t%.15le\t%.15le\n", t, int_result, int_error); fflush(file_out); } gsl_integration_workspace_free (w); } fclose(file_out); /////// //integration to obtain omega_R vector file_out=fopen_control("omega_R_control.txt","w"); omega_R=gsl_vector_alloc(Nt_2); { gsl_integration_workspace * w = gsl_integration_workspace_alloc (N_int_steps); gsl_function F; F.function = &omega_kernel_int; for(t=1;t<=Nt_2;t++) { F.params = &t; gsl_integration_qagiu (&F, 0.0, accuracy, accuracy, N_int_steps, w, &int_result, &int_error); gsl_vector_set(omega_R,t-1,int_result); fprintf(file_out,"%d\t%.15le\t%.15le\n", t, int_result, int_error); fflush(file_out); } gsl_integration_workspace_free (w); } fclose(file_out); /////// { int count_center=0; double C, C0; gsl_vector* Q_real; Q_initial=gsl_vector_calloc(Nt_2); for(center=center_start; center<=center_stop; center+=center_delta) { double center_real=center/(2.0*dNt_2_pre); double center_calculated=0.0; double center_calculated_real=0.0; char file_name[1000]; sprintf(file_name,"delta_function_c=%3.3leT.txt", center); Q=gsl_vector_calloc(Nt_2); Q_real=gsl_vector_calloc(Nt_2); calculate_Q(Q, R, S, center_real); if(count_center==0) { for(i=0;i<Nt_2;i++) gsl_vector_set(Q_initial, i, gsl_vector_get(Q,i)); } if(count_center==0) { for(i=0;i<Nt_2;i++) gsl_vector_set(Q_real, i, gsl_vector_get(Q,i)); } else { if(flag_exclude_delta==1 && count_center>=count_start_exclude) { FILE* log_exclusion; log_exclusion=fopen_log("log_exclusion.txt","a", center_real); C=delta0(Q); C0=delta0(Q_initial); fprintf(log_exclusion,"C=%.15le\nC0=%.15le\n",C,C0);fflush(log_exclusion); for(i=0;i<Nt_2;i++) gsl_vector_set(Q_real, i, gsl_vector_get(Q,i)-(C/C0)*gsl_vector_get(Q_initial,i)); //normalization double new_norma=0.0; for(i=0;i<Nt_2;i++) { new_norma += gsl_vector_get(Q_real, i) * gsl_vector_get(R,i); } fprintf(log_exclusion, "norma_old=%.15le\n", new_norma);fflush(log_exclusion); for(i=0;i<Nt_2;i++) { gsl_vector_set(Q_real,i,gsl_vector_get(Q_real, i)/new_norma ); } new_norma=0.0; for(i=0;i<Nt_2;i++) { new_norma += gsl_vector_get(Q_real, i) * gsl_vector_get(R,i); } fprintf(log_exclusion, "norma_new=%.15le\n", new_norma);fflush(log_exclusion); fclose(log_exclusion); } else { for(i=0;i<Nt_2;i++) gsl_vector_set(Q_real, i, gsl_vector_get(Q,i)); } } //delta function output file_out=fopen_control(file_name,"w"); for(omega=0;omega<omega_plot_limit/(2.0*dNt_2_pre);omega+=omega_plot_delta/(2.0*dNt_2_pre)) { fprintf(file_out,"%.15le\t%.15le\t%.15le\n", omega*2.0*dNt_2_pre, delta(omega,Q), delta(omega, Q_real)); fflush(file_out); } fclose(file_out); //output of dimensionless spectral function double rho, rho_stat_err, width; double rho_real, rho_stat_err_real, width_real; //values to really characterize delta functions double start, stop, center1, width1; double real_start, real_stop, real_center1, real_width1; file_out=fopen_control("rho.txt", "a"); file_out_excl=fopen_control("rho_excl.txt", "a"); calculate_rho(Q, current, error, &rho, &rho_stat_err); width=delta_width_calculation(Q, center_real); delta_characteristics_calculation(&start, &stop, ¢er1, Q, center_real); width1=(stop-start)/2.0; calculate_rho(Q_real, current, error, &rho_real, &rho_stat_err_real); width_real=delta_width_calculation(Q_real, center_real); delta_characteristics_calculation(&real_start, &real_stop, &real_center1, Q_real, center_real); real_width1=(real_stop-real_start)/2.0; fprintf(file_out,"%.15le\t%.15le\t%.15le\t%.15le\t%.15le\t%.15le\n", center, width*2.0*dNt_2_pre, center1, width1, rho, rho_stat_err); fprintf(file_out_excl,"%.15le\t%.15le\t%.15le\t%.15le\t%.15le\t%.15le\n", center, width_real*2.0*dNt_2_pre, real_center1, real_width1, rho_real, rho_stat_err_real); fclose(file_out); fclose(file_out_excl); gsl_vector_free(Q); gsl_vector_free(Q_real); count_center++; } gsl_vector_free(Q_initial); } gsl_vector_free(R); gsl_vector_free(omega_R); gsl_matrix_free(S); gsl_matrix_free(S_pre); free(current); free(error); free(current_pre); free(error_pre); if(flag_model==1) free(points_numbers); return 0; }
int q_sig_search(int g_m) { int i, j, k; double time; int m_num; //char can_name_buffer[256]; //char avr_can_name_buffer[256]; char match_name_buffer[256]; double temp0, temp1, switch_point, proba; double beta[MAX_PARTI]; //char can_index_name_buffer[256]; //char avr_can1_name_buffer[256]; //sprintf(can_name_buffer, "./can_stat_m=%d_q=%d_o=%d.txt", g_m, g_q, order_num); //sprintf(can_index_name_buffer, "./index_stat_m=%d_q=%d_o=%d_can.txt", g_m, g_q, order_num); sprintf(match_name_buffer, "./match_m=%d_q=%d_o=%d.txt", g_m, g_q, order_num); //init power_hashmap power_hashmap = init_power_hashmap(N, power_hashmap); //init bitmap mask for (i = 0; i < U_INT_LEN / 2; i++) { mask[i] = 3 << (i << 1); } /* if (g_element_random_order == 1) { order_num = 0; } */ // link data to stream FILE * fp_record; if ((fp_record = fopen(data_source, "rt+")) == NULL) { fprintf(stderr, "No Document has been found.\n"); return EXIT_FAILURE; } // set a buffer to store combining elements as a sig // read data g_curr_record_num = read_all_documents(fp_record, g_records); fclose(fp_record); //calculate best Q based on m g_q = calculate_Q(g_records[0].len, g_m); //fprintf(stdout, "partition length is %d\n", g_q); //if (g_q <= 15){ //collapse_filtering = 0; //} //sig_str_buffer = (char *) malloc(sizeof (char) * 2 * g_q * MAX_ELEMENT_LEN); if (g_curr_record_num < 0) { fprintf(stderr, "Error: Read data error\n"); return EXIT_FAILURE; } // init the hashtable init_element_index(MAX_ELEMENT_NUM); // create space for elements for (i = 0; i < g_curr_record_num; i++) { if ((g_records[i].element_slots = (element_slot_t *) malloc(sizeof (element_slot_t) * g_records[i].len)) == NULL) { fprintf(stderr, "ERROR: Out of memory\n"); exit(-1); } // build the element list build_record_elements(g_records[i].str, g_records[i].len, g_records[i].element_slots); } //random the frq to random the element order //if (g_element_random_order == 1) { if (bit_fv) { hash_element_in_dimension(_element_block_head); bitwise_record(g_records, g_curr_record_num); } free(_buffer); //sort_all_element_list_by_freq(g_records, g_curr_record_num); //} // initiate index /* if(collapse_filtering){ rand_bucket_num(_element_block_head); //fprintf(stdout,"%u\t%u\t%u\t%u\n", g_records[0].element_slots[0].element->bucket_num, g_records[0].element_slots[1].element->bucket_num, //g_records[0].element_slots[2].element->bucket_num, g_records[0].element_slots[3].element->bucket_num ); rec_bucket_init(g_records, g_curr_record_num); //fprintf(stdout,"%u\t%u\t%u\t%u\n", g_records[0].bucket[0], g_records[0].bucket[1], //g_records[0].bucket[3], g_records[0].bucket[4]); } */ init_sig_index(MAX_SIG_NUM); // create data sigs for each record from their elements for (i = 0; i < g_curr_record_num; i++) { //calculate the number of sig_prefix for each record g_records[i].sig_num = calculate_sig_num(&g_records[i], g_m); //set space for those sigs if ((g_records[i].sig_slots = (sig_slot *) malloc(sizeof (sig_slot) * g_records[i].sig_num)) == NULL) { fprintf(stderr, "ERROR: Out of memory\n"); exit(-1); } //create sigs build_sigs(&g_records[i], g_q, g_m); } //random the frq to random the sig order //if (g_sig_random_order == 1) { // random_sig_frq(_sig_block_head); //} //sort those sigs by idf //sort_all_sig_list_by_freq(g_records, g_curr_record_num); // build index build_sig_idf_list(g_records, g_curr_record_num, g_m, g_q); fprintf(stdout, "The number of documents:%d\n", g_curr_record_num); printf("\n"); // print out the average length of the documents in data source int sum = 0; int avg_len = 0; for (i = 0; i < g_curr_record_num; i++) { sum += g_records[i].len; } avg_len = sum / g_curr_record_num; fprintf(stdout, "The average length of these documents is:%d\n", avg_len); fprintf(stdout, "\n"); //show the information in the index fprintf(stdout, "The number of different elements is %d\n", g_element_num); fprintf(stdout, "The number of different sigs is %d\n", g_sig_num); //search part #ifndef DEBUG_INDEX //output result if ((fp_query_match = fopen(match_name_buffer, "w+")) == NULL) { fprintf(stderr, "Error: create file error\n"); return EXIT_FAILURE; } //output candidate status /* if ((fp_query_cand = fopen(can_name_buffer, "w+")) == NULL) { fprintf(stderr, "Document creating error.\n"); return EXIT_FAILURE; } if ((fp_query_cand_index = fopen(can_index_name_buffer, "w+")) == NULL) { fprintf(stderr, "Document creating error.\n"); return EXIT_FAILURE; } */ //FILE * fp_query_stat; //if ((fp_query_stat = fopen("/Users/xyzhang/Desktop/q_sig/search_stat.txt", "w+")) == NULL) { // fprintf(stderr, "Document creating error.\n"); // return EXIT_FAILURE; //} // data query FILE * fp_query; if ((fp_query = fopen(query_source, "rt+")) == NULL) { fprintf(stderr, "No Document has been found.\n"); return EXIT_FAILURE; } //read query data g_curr_query_num = read_all_queries(fp_query, g_query); fclose(fp_query); //reset timer if (g_curr_query_num < 0) { fprintf(stderr, "Error: Read query error\n"); return EXIT_FAILURE; } double average_can0, average_can1, average_can2, average_can3, average_can4, average_can5, average_esti_can1; average_can0 = 0; average_can1 = 0; average_can2 = 0; average_can3 = 0; average_can4 = 0; average_can5 = 0; //average_esti_can1 = 0; for (i = 0; i < g_curr_query_num; i++) { //for (i = 63; i<64 ;i++){ //init_query_element_head(); //set space for query elements if ((g_query[i].element_slots = (element_slot_t *) malloc(sizeof (element_slot_t) * g_query[i].len)) == NULL) { fprintf(stderr, "ERROR: Out of memory\n"); exit(-1); } //create query elements build_query_elements(g_query[i].str, g_query[i].len, g_query[i].element_slots); if (bit_fv) { bitwise_query(g_query, i); } //set order by dimension /* if(collapse_filtering){ //init_query_sig_head(); que_bucket_init(g_query, i); } */ } ResetUsage(); mytimer preptimer; preptimer.timesum = 0; mytimer probetimer; probetimer.timesum = 0; init_search(g_curr_record_num); for (i = 0; i < g_curr_query_num; i++) { #ifdef DEBUG_OUTPUT can0 = 0; can1 = 0; can2 = 0; can3 = 0; can4 = 0; can5 = 0; #endif proba = 0; temp0 = 1; temp1 = 0; //calculate the number of sig_prefix for each query g_query[i].sig_num = calculate_query_sig_num(&g_query[i], g_m); if ((g_query[i].sig_slots = (sig_slot *) malloc(sizeof (sig_slot) * g_query[i].sig_num)) == NULL) { fprintf(stderr, "ERROR: Out of memory\n"); exit(-1); } //build query sigs build_query_sigs(&(g_query[i]), g_q, g_m); k = 0; for (j = 0; j < (N- g_m +3)/2; j++) { //idf[k]= g_query[i].sig_slots[j].sig->last_idf; can0 += partition_can0[j]; beta[k] = (double)(partition_can0[j] - (partition_len[j] - 1) * partition_exact[j] )/ (double)g_curr_record_num; temp0 *= (1 - beta[k]); k++; } for (j = 0; j < k; j++) { //fprintf(stderr, "%e %e\n", temp0, beta[j]); proba = (temp0 / (1 - beta[j])) * beta[j]; //fprintf(stderr, "%e\n", proba); temp1 += proba; } switch_point = (double)can0 / ((double)g_curr_record_num * (temp0 + temp1)); //average_esti_can1 += ((double)g_curr_record_num * ((double)1 - temp0 - temp1)); if ((N - g_m) % 2 == 0) { if ( switch_point > alpha_even) { StartTimer(&probetimer); can1 = g_curr_record_num; for (j = 0; j < g_curr_record_num; j++) { m_num = bitwise_check_line_based(&(g_query[i]), &(g_records[j]), g_m); if (m_num >= g_m) { can4++; } } PauseTImer(&probetimer); can0 = g_curr_record_num; } else { StartTimer(&probetimer); search_in_index(g_query, i, g_records, g_curr_record_num, g_m, g_q); PauseTImer(&probetimer); } } else { if ( switch_point > alpha_odd) { can1 = g_curr_record_num; StartTimer(&probetimer); for (j = 0; j < g_curr_record_num; j++) { m_num = bitwise_check_line_based(&(g_query[i]), &(g_records[j]), g_m); if (m_num >= g_m) { can4++; } } PauseTImer(&probetimer); can0 = g_curr_record_num; } else { StartTimer(&probetimer); search_in_index_odd(g_query, i, g_records, g_curr_record_num, g_m, g_q); PauseTImer(&probetimer); } } //free malloc space //free(g_query[i].element_slots); //free(g_query[i].sig_slots); #ifdef DEBUG_OUTPUT average_can0 += can0; average_can1 += can1; average_can2 += can2; average_can3 += can3; average_can4 += can4; average_can5 += can5; //average_m_num += avg_m_num; #endif } // fprintf(fp_query_stat,"query[%d]\t%d\t%d\n", i, g_query[i].can0, g_query[i].pair_num); //} /* #ifdef dump_one_query char order_buffer[256]; sprintf(order_buffer, "./order_m=%d_q=%d_o=%d.txt", g_m, g_q, order_num); if ((fp_output_order = fopen(order_buffer, "w+")) == NULL) { fprintf(stderr, "Error: create file error\n"); return EXIT_FAILURE; } for (i =0; i<order_num;i++){ dump_element_random_order(_element_block_head, g_m, g_q, i); } #endif */ //#ifdef DEBUG_OUTPUT time = ShowUsage(); fprintf(stdout, "Usage: %s\n", __usage_information); average_can0 /= g_curr_query_num; average_can1 /= g_curr_query_num; average_can2 /= g_curr_query_num; average_can3 /= g_curr_query_num; average_can4 /= g_curr_query_num; average_can5 /= g_curr_query_num; //average_esti_can1 /= g_curr_query_num; /* FILE * fp_avr_cand1_num; if ((fp_avr_cand1_num = fopen(avr_can1_name_buffer, "rt+")) == NULL) { fprintf(stderr, "No Document has been found.\n"); return EXIT_FAILURE; } */ //print out the query's name int p; char * data; data = query_source; p = strlen(data) - 1; while (data[p] != '/') { p--; } p++; while (data[p] != '\0' && data[p] != '.') { fprintf(stderr, "%c", data[p]); p++; } fprintf(stderr, " "); fprintf(stderr, "m %d partition_len %d ", g_m, g_q); fprintf(stderr, "time %.6f can0 %f ", time, average_can0); fprintf(stderr, "can1 %f ", average_can1); //fprintf(stderr, "esti_can1 %f ", average_esti_can1); fprintf(stderr, "can2 %f ", average_can2); fprintf(stderr, "can3 %f ", average_can3); //fprintf(stderr, "can4 %Lf ", average_can5); fprintf(stderr, "can4 %f bitnum: %d\n", average_can4, bit_per_d); //fprintf(stderr, "avg_m_num_in_pfx\t%Lf\n", average_m_num); //dump useful order //dump_element_order(_element_block_head, g_m, g_q); //dump_sig_order(_sig_block_head, g_m, g_q); //dump_sig_order_in_prefix(_sig_block_head, g_m, g_q); //free space /* destroy_element_index(); destroy_sig_index(); for (i = 0; i < g_curr_record_num; i++) { free(g_records[i].element_slots); free(g_records[i].sig_slots); } //destroy_query_element_blocks(); //destroy_query_sig_blocks(); free(sig_str_buffer); free(_buffer); */ //#endif #endif return EXIT_SUCCESS; }
/******************************************************************************* ** Calculate the bond order parameters and filter atoms (if required). ** ** Inputs: ** - visibleAtoms: the list of atoms that are currently visible ** - pos: positions of all the atoms ** - maxBondDistance: the maximum bond distance to consider ** - scalarsQ4: array to store the Q4 parameter value ** - scalarsQ6: array to store the Q6 parameter value ** - cellDims: simulation cell dimensions ** - PBC: periodic boundaries conditions ** - NScalars: the number of previously calculated scalar values ** - fullScalars: the full list of previously calculated scalars ** - NVectors: the number of previously calculated vector values ** - fullVectors: the full list of previously calculated vectors ** - filterQ4: filter atoms by the Q4 parameter ** - minQ4: the minimum Q4 for an atom to be visible ** - maxQ4: the maximum Q4 for an atom to be visible ** - filterQ6: filter atoms by the Q6 parameter ** - minQ6: the minimum Q6 for an atom to be visible ** - maxQ6: the maximum Q6 for an atom to be visible *******************************************************************************/ static PyObject* bondOrderFilter(PyObject *self, PyObject *args) { int NVisibleIn, *visibleAtoms, *PBC, NScalars, filterQ4Enabled, filterQ6Enabled; int NVectors; double maxBondDistance, *scalarsQ4, *scalarsQ6, *cellDims; double *pos, *fullScalars, minQ4, maxQ4, minQ6, maxQ6; PyArrayObject *posIn=NULL; PyArrayObject *visibleAtomsIn=NULL; PyArrayObject *PBCIn=NULL; PyArrayObject *scalarsQ4In=NULL; PyArrayObject *scalarsQ6In=NULL; PyArrayObject *cellDimsIn=NULL; PyArrayObject *fullScalarsIn=NULL; PyArrayObject *fullVectors=NULL; int i, NVisible, boxstat; double *visiblePos, maxSep2; struct Boxes *boxes; struct NeighbourList *nebList; struct AtomStructureResults *results; /* parse and check arguments from Python */ if (!PyArg_ParseTuple(args, "O!O!dO!O!O!O!iO!iddiddiO!", &PyArray_Type, &visibleAtomsIn, &PyArray_Type, &posIn, &maxBondDistance, &PyArray_Type, &scalarsQ4In, &PyArray_Type, &scalarsQ6In, &PyArray_Type, &cellDimsIn, &PyArray_Type, &PBCIn, &NScalars, &PyArray_Type, &fullScalarsIn, &filterQ4Enabled, &minQ4, &maxQ4, &filterQ6Enabled, &minQ6, &maxQ6, &NVectors, &PyArray_Type, &fullVectors)) return NULL; if (not_intVector(visibleAtomsIn)) return NULL; visibleAtoms = pyvector_to_Cptr_int(visibleAtomsIn); NVisibleIn = (int) PyArray_DIM(visibleAtomsIn, 0); if (not_doubleVector(posIn)) return NULL; pos = pyvector_to_Cptr_double(posIn); if (not_doubleVector(scalarsQ4In)) return NULL; scalarsQ4 = pyvector_to_Cptr_double(scalarsQ4In); if (not_doubleVector(scalarsQ6In)) return NULL; scalarsQ6 = pyvector_to_Cptr_double(scalarsQ6In); if (not_doubleVector(cellDimsIn)) return NULL; cellDims = pyvector_to_Cptr_double(cellDimsIn); if (not_intVector(PBCIn)) return NULL; PBC = pyvector_to_Cptr_int(PBCIn); if (not_doubleVector(fullScalarsIn)) return NULL; fullScalars = pyvector_to_Cptr_double(fullScalarsIn); if (not_doubleVector(fullVectors)) return NULL; /* construct array of positions of visible atoms */ visiblePos = malloc(3 * NVisibleIn * sizeof(double)); if (visiblePos == NULL) { PyErr_SetString(PyExc_MemoryError, "Could not allocate visiblePos"); return NULL; } for (i = 0; i < NVisibleIn; i++) { int index = visibleAtoms[i]; int ind3 = 3 * index; int i3 = 3 * i; visiblePos[i3 ] = pos[ind3 ]; visiblePos[i3 + 1] = pos[ind3 + 1]; visiblePos[i3 + 2] = pos[ind3 + 2]; } /* box visible atoms */ boxes = setupBoxes(maxBondDistance, PBC, cellDims); if (boxes == NULL) { free(visiblePos); return NULL; } boxstat = putAtomsInBoxes(NVisibleIn, visiblePos, boxes); if (boxstat) { free(visiblePos); return NULL; } /* build neighbour list */ maxSep2 = maxBondDistance * maxBondDistance; nebList = constructNeighbourList(NVisibleIn, visiblePos, boxes, cellDims, PBC, maxSep2); /* only required for building neb list */ free(visiblePos); freeBoxes(boxes); /* return if failed to build the neighbour list */ if (nebList == NULL) return NULL; /* allocate results structure */ results = malloc(NVisibleIn * sizeof(struct AtomStructureResults)); if (results == NULL) { PyErr_SetString(PyExc_MemoryError, "Could not allocate results"); freeNeighbourList(nebList, NVisibleIn); return NULL; } /* first calc q_lm for each atom over all m values */ complex_qlm(NVisibleIn, visibleAtoms, nebList, pos, cellDims, PBC, results); /* free neighbour list */ freeNeighbourList(nebList, NVisibleIn); /* calculate Q4 and Q6 */ calculate_Q(NVisibleIn, results); /* do filtering here, storing results along the way */ NVisible = 0; for (i = 0; i < NVisibleIn; i++) { int j; double q4 = results[i].Q4; double q6 = results[i].Q6; /* skip if not within the valid range */ if (filterQ4Enabled && (q4 < minQ4 || q4 > maxQ4)) continue; if (filterQ6Enabled && (q6 < minQ6 || q6 > maxQ6)) continue; /* store in visible atoms array */ visibleAtoms[NVisible] = visibleAtoms[i]; /* store calculated values */ scalarsQ4[NVisible] = q4; scalarsQ6[NVisible] = q6; /* update full scalars/vectors arrays */ for (j = 0; j < NScalars; j++) { int nj = j * NVisibleIn; fullScalars[nj + NVisible] = fullScalars[nj + i]; } for (j = 0; j < NVectors; j++) { int nj = j * NVisibleIn; DIND2(fullVectors, nj + NVisible, 0) = DIND2(fullVectors, nj + i, 0); DIND2(fullVectors, nj + NVisible, 1) = DIND2(fullVectors, nj + i, 1); DIND2(fullVectors, nj + NVisible, 2) = DIND2(fullVectors, nj + i, 2); } NVisible++; } /* free results memory */ free(results); return Py_BuildValue("i", NVisible); }