void QwtHistogram::loadDataFromMatrix() { if (!d_matrix) return; int size = d_matrix->numRows() * d_matrix->numCols(); const double *data = d_matrix->matrixModel()->dataVector(); int n; gsl_histogram *h; if (d_autoBin) { double min, max; d_matrix->range(&min, &max); d_begin = floor(min); d_end = ceil(max); d_bin_size = 1.0; n = static_cast<int>(floor((d_end - d_begin) / d_bin_size)); if (!n) return; h = gsl_histogram_alloc(n); if (!h) return; gsl_histogram_set_ranges_uniform(h, floor(min), ceil(max)); } else { n = static_cast<int>((d_end - d_begin) / d_bin_size + 1); if (!n) return; h = gsl_histogram_alloc(n); if (!h) return; double *range = new double[n + 2]; for (int i = 0; i <= n + 1; i++) range[i] = d_begin + i * d_bin_size; gsl_histogram_set_ranges(h, range, n + 1); delete[] range; } for (int i = 0; i < size; i++) gsl_histogram_increment(h, data[i]); QVarLengthArray<double> X(n), Y(n); // stores ranges (x) and bins (y) for (int i = 0; i < n; i++) { Y[i] = gsl_histogram_get(h, i); double lower, upper; gsl_histogram_get_range(h, i, &lower, &upper); X[i] = lower; } setData(X.data(), Y.data(), n); d_mean = gsl_histogram_mean(h); d_standard_deviation = gsl_histogram_sigma(h); d_min = gsl_histogram_min_val(h); d_max = gsl_histogram_max_val(h); gsl_histogram_free(h); }
void QwtHistogram::initData(double *Y, int size) { if(size<2 || (size == 2 && Y[0] == Y[1])) {//non valid histogram data double x[2], y[2]; for (int i = 0; i<2; i++ ){ y[i] = 0; x[i] = 0; } setData(x, y, 2); return; } int n = 10;//default value QVarLengthArray<double> x(n), y(n);//double x[n], y[n]; //store ranges (x) and bins (y) gsl_histogram * h = gsl_histogram_alloc (n); if (!h) return; gsl_vector *v; v = gsl_vector_alloc (size); for (int i = 0; i<size; i++ ) gsl_vector_set (v, i, Y[i]); double min, max; gsl_vector_minmax (v, &min, &max); gsl_vector_free (v); d_begin = floor(min); d_end = ceil(max); gsl_histogram_set_ranges_uniform (h, floor(min), ceil(max)); for (int i = 0; i<size; i++ ) gsl_histogram_increment (h, Y[i]); for (int i = 0; i<n; i++ ){ y[i] = gsl_histogram_get (h, i); double lower, upper; gsl_histogram_get_range (h, i, &lower, &upper); x[i] = lower; } setData(x.data(), y.data(), n);//setData(x, y, n); d_bin_size = (d_end - d_begin)/(double)n; d_autoBin = true; d_mean = gsl_histogram_mean(h); d_standard_deviation = gsl_histogram_sigma(h); d_min = gsl_histogram_min_val(h); d_max = gsl_histogram_max_val(h); gsl_histogram_free (h); }
void QwtHistogram::loadData() { if (d_matrix){ loadDataFromMatrix(); return; } int r = abs(d_end_row - d_start_row) + 1; QVarLengthArray<double> Y(r); int ycol = d_table->colIndex(title().text()); int size = 0; for (int i = 0; i<r; i++ ){ QString yval = d_table->text(i, ycol); if (!yval.isEmpty()){ bool valid_data = true; Y[size] = ((Graph *)plot())->locale().toDouble(yval, &valid_data); if (valid_data) size++; } } if(size < 2 || (size==2 && Y[0] == Y[1])){//non valid histogram double X[2]; Y.resize(2); for (int i = 0; i<2; i++ ){ Y[i] = 0; X[i] = 0; } setData(X, Y.data(), 2); return; } int n; gsl_histogram *h; if (d_autoBin){ n = 10; h = gsl_histogram_alloc (n); if (!h) return; gsl_vector *v = gsl_vector_alloc (size); for (int i = 0; i<size; i++ ) gsl_vector_set (v, i, Y[i]); double min, max; gsl_vector_minmax (v, &min, &max); gsl_vector_free (v); d_begin = floor(min); d_end = ceil(max); d_bin_size = (d_end - d_begin)/(double)n; gsl_histogram_set_ranges_uniform (h, floor(min), ceil(max)); } else { n = int((d_end - d_begin)/d_bin_size + 1); h = gsl_histogram_alloc (n); if (!h) return; double *range = new double[n+2]; for (int i = 0; i<= n+1; i++ ) range[i] = d_begin + i*d_bin_size; gsl_histogram_set_ranges (h, range, n+1); delete[] range; } for (int i = 0; i<size; i++ ) gsl_histogram_increment (h, Y[i]); #ifdef Q_CC_MSVC QVarLengthArray<double> X(n); //stores ranges (x) and bins (y) #else double X[n]; //stores ranges (x) and bins (y) #endif Y.resize(n); for (int i = 0; i<n; i++ ){ Y[i] = gsl_histogram_get (h, i); double lower, upper; gsl_histogram_get_range (h, i, &lower, &upper); X[i] = lower; } #ifdef Q_CC_MSVC setData(X.data(), Y.data(), n); #else setData(X, Y.data(), n); #endif d_mean = gsl_histogram_mean(h); d_standard_deviation = gsl_histogram_sigma(h); d_min = gsl_histogram_min_val(h); d_max = gsl_histogram_max_val(h); gsl_histogram_free (h); }
main (int argc,char *argv[]) { int ia,ib,ic,id,it,inow,ineigh,icont; int in,ia2,ia3,irun,icurrent,ORTOGONALFLAG; int RP, P,L,N,NRUNS,next,sweep,SHOWFLAG; double u,field1,field2,field0,q,aux1,aux2; double alfa,aux,Q1,Q2,QZ,RZQ,rho,R; double pm,D,wmax,mQ,wx,wy,h_sigma,h_mean; double TOL,MINLOGF,E; double DELTA; double E_new,Ex,DeltaE,ER; double EW,meanhist,hvalue,wE,aratio; double logG_old,logG_new,lf; size_t i_old,i_new; long seed; double lGvR,lGv,DlG; size_t iL,iR,i1,i2; int I_endpoint[NBINS]; double lower,upper; size_t i0; FILE * wlsrange; FILE * dos; FILE * thermodynamics; FILE * canonical; FILE * logfile; //FILE * pajek; //*********************************** // Help //*********************************** if (argc<15){ help(); return(1); } else{ DELTA = atof(argv[1]); P = atoi(argv[2]); RP = atoi(argv[3]); L = atoi(argv[4]); N = atoi(argv[5]); TOL = atof(argv[6]); MINLOGF = atof(argv[7]); } wlsrange=fopen(argv[8],"w"); dos=fopen(argv[9],"w"); thermodynamics=fopen(argv[10],"w"); canonical=fopen(argv[11],"w"); logfile=fopen(argv[12],"w"); SHOWFLAG = atoi(argv[13]); ORTOGONALFLAG = atoi(argv[14]); if ((ORTOGONALFLAG==1) && (P>L)) P=L; //maximum number of orthogonal issues if (SHOWFLAG==1){ printf("# parameters are DELTA=%1.2f P=%d ",DELTA,P); printf("D=%d L=%d M=%d TOL=%1.2f MINLOGF=%g \n",L,N,RP,TOL,MINLOGF); } fprintf(logfile,"# parameters are DELTA=%1.2f P=%d D=%d",DELTA,P,L); fprintf(logfile,"L=%d M=%d TOL=%1.2f MINLOGF=%g\n",L,RP,TOL,MINLOGF); //********************************************************************** // Alocate matrices //********************************************************************** gsl_matrix * sociedade = gsl_matrix_alloc(SIZE,L); gsl_matrix * issue = gsl_matrix_alloc(P,L); gsl_vector * current_issue = gsl_vector_alloc(L); gsl_vector * v0 = gsl_vector_alloc(L); gsl_vector * v1 = gsl_vector_alloc(L); gsl_vector * Z = gsl_vector_alloc(L); gsl_vector * E_borda = gsl_vector_alloc(NBINS); //********************************************************************** // Inicialization //********************************************************************** const gsl_rng_type * T; gsl_rng * r; gsl_rng_env_setup(); T = gsl_rng_default; r=gsl_rng_alloc (T); seed = time (NULL) * getpid(); //seed = 13188839657852; gsl_rng_set(r,seed); igraph_t graph; igraph_vector_t neighbors; igraph_vector_t result; igraph_vector_t dim_vector; igraph_real_t res; igraph_bool_t C; igraph_vector_init(&neighbors,1000); igraph_vector_init(&result,0); igraph_vector_init(&dim_vector,DIMENSION); for(ic=0;ic<DIMENSION;ic++) VECTOR(dim_vector)[ic]=N; gsl_histogram * HE = gsl_histogram_alloc (NBINS); gsl_histogram * logG = gsl_histogram_alloc (NBINS); gsl_histogram * LG = gsl_histogram_alloc (NBINS); //******************************************************************** // Social Graph //******************************************************************** //Barabasi-Alberts network igraph_barabasi_game(&graph,SIZE,RP,&result,1,0); /* for (inow=0;inow<SIZE;inow++){ igraph_neighbors(&graph,&neighbors,inow,IGRAPH_OUT); printf("%d ",inow); for(ic=0;ic<igraph_vector_size(&neighbors);ic++) { ineigh=(int)VECTOR(neighbors)[ic]; printf("%d ",ineigh); } printf("\n"); }*/ //pajek=fopen("graph.xml","w"); // igraph_write_graph_graphml(&graph,pajek); //igraph_write_graph_pajek(&graph, pajek); //fclose(pajek); //********************************************************************** //Quenched issues set and Zeitgeist //********************************************************************** gsl_vector_set_zero(Z); gera_config(Z,issue,P,L,r,1.0); if (ORTOGONALFLAG==1) gsl_matrix_set_identity(issue); for (ib=0;ib<P;ib++) { gsl_matrix_get_row(current_issue,issue,ib); gsl_blas_ddot(current_issue,current_issue,&Q1); gsl_vector_scale(current_issue,1/sqrt(Q1)); gsl_vector_add(Z,current_issue); } gsl_blas_ddot(Z,Z,&QZ); gsl_vector_scale(Z,1/sqrt(QZ)); //********************************************************************** // Ground state energy //********************************************************************** double E0; gera_config(Z,sociedade,SIZE,L,r,0); E0 = hamiltoneana(sociedade,issue,SIZE,L,P,DELTA,graph); double EMIN=E0; double EMAX=-E0; double E_old=E0; gsl_histogram_set_ranges_uniform (HE,EMIN,EMAX); gsl_histogram_set_ranges_uniform (logG,EMIN,EMAX); if (SHOWFLAG==1) printf("# ground state: %3.0f\n",E0); fprintf(logfile,"# ground state: %3.0f\n",E0); //********************************************************************** // Find sampling interval //********************************************************************** //printf("#finding the sampling interval...\n"); lf=1; sweep=0; icont=0; int iflag=0; int TMAX=NSWEEPS; while(sweep<=TMAX){ if (icont==10000) { //printf("%d sweeps\n",sweep); icont=0; } for(it=0;it<SIZE;it++){ igraph_vector_init(&neighbors,SIZE); //choose a random site do{ inow=gsl_rng_uniform_int(r,SIZE); }while((inow<0)||(inow>=SIZE)); gsl_matrix_get_row(v1,sociedade,inow); igraph_neighbors(&graph,&neighbors,inow,IGRAPH_OUT); //generates a random vector v1 gsl_vector_memcpy(v0,v1); gera_vetor(v1,L,r); //calculates energy change when v0->v1 // in site inow DeltaE=variacaoE(v0,v1,inow,sociedade, issue,N,L,P,DELTA,graph,neighbors); E_new=E_old+DeltaE; //WL: accepts in [EMIN,EMAX] if ((E_new>EMIN) && (E_new<EMAX)) { gsl_histogram_find(logG,E_old,&i_old); logG_old=gsl_histogram_get(logG,i_old); gsl_histogram_find(logG,E_new,&i_new); logG_new=gsl_histogram_get(logG,i_new); wE = GSL_MIN(exp(logG_old-logG_new),1); if (gsl_rng_uniform(r)<wE){ E_old=E_new; gsl_matrix_set_row(sociedade,inow,v1); } } //WL: update histograms gsl_histogram_increment(HE,E_old); gsl_histogram_accumulate(logG,E_old,lf); igraph_vector_destroy(&neighbors); } sweep++; icont++; } gsl_histogram_fprintf(wlsrange,HE,"%g","%g"); double maxH=gsl_histogram_max_val(HE); //printf("ok\n"); Ex=0; hvalue=maxH; while((hvalue>TOL*maxH)&&(Ex>EMIN)){ gsl_histogram_find(HE,Ex,&i0); hvalue=gsl_histogram_get(HE,i0); Ex-=1; if(Ex<=EMAX)TMAX+=10000; } EMIN=Ex; Ex=0; hvalue=maxH; while((hvalue>TOL*maxH)&&(Ex<EMAX)) { gsl_histogram_find(HE,Ex,&i0); hvalue=gsl_histogram_get(HE,i0); Ex+=1; if(Ex>=EMAX)TMAX+=10000; } EMAX=Ex; EMAX=GSL_MIN(10.0,Ex); if (SHOWFLAG==1) printf("# the sampling interval is [%3.0f,%3.0f] found in %d sweeps \n\n" ,EMIN,EMAX,sweep); fprintf(logfile, "# the sampling interval is [%3.0f,%3.0f] found in %d sweeps \n\n" ,EMIN,EMAX,sweep); gsl_histogram_set_ranges_uniform (HE,EMIN-1,EMAX+1); gsl_histogram_set_ranges_uniform (logG,EMIN-1,EMAX+1); gsl_histogram_set_ranges_uniform (LG,EMIN-1,EMAX+1); //********************************************************************** // WLS //********************************************************************** int iE,itera=0; double endpoints[NBINS]; double w = WINDOW; //(EMAX-EMIN)/10.0; //printf("W=%f\n",w); lf=1; //RESOLUTION ----> <------RESOLUTION***** do{ int iverify=0,iborda=0,flat=0; sweep=0; Ex=EMAX; EW=EMAX; E_old=EMAX+1; iE=0; endpoints[iE]=EMAX; iE++; gsl_histogram_reset(LG); //WINDOWS --> <--WINDOWS******* while((Ex>EMIN)&&(sweep<MAXSWEEPS)){ //initial config gera_config(Z,sociedade,SIZE,L,r,0); E_old = hamiltoneana(sociedade,issue,SIZE,L,P,DELTA,graph); while( (E_old<EMIN+1)||(E_old>Ex) ){ //printf("%d %3.1f\n",E_old); do{ inow=gsl_rng_uniform_int(r,SIZE); }while((inow<0)||(inow>=SIZE)); gsl_matrix_get_row(v0,sociedade,inow); gera_vetor(v1,L,r); gsl_matrix_set_row(sociedade,inow,v1); E_old = hamiltoneana(sociedade,issue,SIZE,L,P,DELTA,graph); if (E_old>Ex){ gsl_matrix_set_row(sociedade,inow,v0); E_old = hamiltoneana(sociedade,issue,SIZE,L,P,DELTA,graph); } //printf("%3.1f %3.1f %3.1f\n",EMIN+1,E_old, Ex); } if (SHOWFLAG==1){ printf("# sampling [%f,%f]\n",EMIN,Ex); printf("# walking from E=%3.0f\n",E_old); } fprintf(logfile,"# sampling [%f,%f]\n",EMIN,Ex); fprintf(logfile,"# walking from E=%3.0f\n",E_old); do{ //FLAT WINDOW------> <------FLAT WINDOW***** //MC sweep ----> <------MC sweep******** for(it=0;it<SIZE;it++){ igraph_vector_init(&neighbors,SIZE); //escolhe sÃtio aleatoriamente do{ inow=gsl_rng_uniform_int(r,SIZE); }while((inow<0)||(inow>=SIZE)); gsl_matrix_get_row(v1,sociedade,inow); igraph_neighbors(&graph,&neighbors,inow,IGRAPH_OUT); //gera vetor aleatorio v1 gsl_vector_memcpy(v0,v1); gera_vetor(v1,L,r); //calculates energy change when //v0->v1 in site inow DeltaE=variacaoE(v0,v1,inow,sociedade,issue, N,L,P,DELTA,graph,neighbors); E_new=E_old+DeltaE; //WL: accepts in [EMIN,Ex] if ((E_new>EMIN) && (E_new<Ex)) { gsl_histogram_find(logG,E_old,&i_old); logG_old=gsl_histogram_get(logG,i_old); gsl_histogram_find(logG,E_new,&i_new); logG_new=gsl_histogram_get(logG,i_new); wE = GSL_MIN(exp(logG_old-logG_new),1); if (gsl_rng_uniform(r)<wE){ E_old=E_new; gsl_matrix_set_row(sociedade,inow,v1); } } //WL: updates histograms gsl_histogram_increment(HE,E_old); gsl_histogram_accumulate(logG,E_old,lf); itera++; igraph_vector_destroy(&neighbors); } //MC sweep ----> <--------MC sweep**** sweep++; iverify++; if( (EMAX-EMIN)<NDE*DE ) { EW=EMIN; }else{ EW=GSL_MAX(Ex-w,EMIN); } if (iverify==CHECK){//Verify flatness if (SHOWFLAG==1) printf(" #verificando flatness em [%f,%f]\n",EW,Ex); fprintf(logfile," #verificando flatness em [%f,%f]\n" ,EW,Ex); iverify=0; flat=flatness(HE,EW,Ex,TOL,itera,meanhist,hvalue); if (SHOWFLAG==1) printf("#minH= %8.0f\t k<H>=%8.0f\t %d sweeps\t ", hvalue,TOL*meanhist,sweep,flat); fprintf(logfile, "#minH= %8.0f\t k<H>=%8.0f\t %d sweeps\t ", hvalue,TOL*meanhist,sweep,flat); } }while(flat==0);// <------FLAT WINDOW****** flat=0; //Find ER //printf("# EMAX=%f EMIN = %f Ex =%f\n",EMAX, EMIN, Ex); if( (EMAX-EMIN)<NDE*DE ) { Ex=EMIN; endpoints[iE]=EMIN; } else { if (EW>EMIN){ ER=flatwindow(HE,EW,TOL,meanhist); if (SHOWFLAG==1) printf("# extending flatness to[%f,%f]\n",ER,Ex); fprintf(logfile, "# extending flatness to [%f,%f]\n",ER,Ex); if((ER-EMIN)<1){ ER=EMIN; Ex=EMIN; endpoints[iE]=EMIN; }else{ endpoints[iE]=GSL_MIN(ER+DE,EMAX); Ex=GSL_MIN(ER+2*DE,EMAX); } } else{ endpoints[iE]=EMIN; Ex=EMIN; ER=EMIN; } } if (SHOWFLAG==1) printf("# window %d [%3.0f,%3.0f] is flat after %d sweeps \n", iE,endpoints[iE],endpoints[iE-1],sweep); fprintf(logfile,"# window %d [%3.0f,%3.0f] is flat after %d sweeps\n", iE,endpoints[iE],endpoints[iE-1],sweep); //saves histogram if (iE==1){ gsl_histogram_find(logG,endpoints[iE],&i1); gsl_histogram_find(logG,endpoints[iE-1],&i2); for(i0=i1;i0<=i2;i0++){ lGv=gsl_histogram_get(logG,i0); gsl_histogram_get_range(logG,i0,&lower,&upper); E=0.5*(upper+lower); gsl_histogram_accumulate(LG,E,lGv); } }else{ gsl_histogram_find(logG,endpoints[iE],&i1); gsl_histogram_find(logG,endpoints[iE-1],&i2); lGv=gsl_histogram_get(logG,i2); lGvR=gsl_histogram_get(LG,i2); DlG=lGvR-lGv; //printf("i1=%d i2=%d lGv=%f lGvR=%f DlG=%f\n",i1,i2,lGv,lGvR,DlG); for(i0=i1;i0<i2;i0++){ lGv=gsl_histogram_get(logG,i0); lGv=lGv+DlG; gsl_histogram_get_range(logG,i0,&lower,&upper); E=(upper+lower)*0.5; //printf("i0=%d E=%f lGv=%f\n",i0,E,lGv); gsl_histogram_accumulate(LG,E,lGv); } } //printf("#########################################\n"); //gsl_histogram_fprintf(stdout,LG,"%g","%g"); //printf("#########################################\n"); iE++; if((Ex-EMIN)>NDE*DE) { if (SHOWFLAG==1) printf("# random walk is now restricted to [%3.0f,%3.0f]\n" ,EMIN,Ex); fprintf(logfile,"# random walk is now restricted to [%3.0f,%3.0f]\n" ,EMIN,Ex); } gsl_histogram_reset(HE); } //WINDOWS --> if(sweep<MAXSWEEPS){ if (SHOWFLAG==1) printf("# log(f)=%f converged within %d sweeps\n\n",lf,sweep); fprintf(logfile,"# log(f)=%f converged within %d sweeps\n\n",lf,sweep); lf=lf/2.0; gsl_histogram_reset(HE); gsl_histogram_memcpy(logG,LG); }else { if (SHOWFLAG==1) printf("# FAILED: no convergence has been attained."); fprintf(logfile, "# FAILED: no convergence has been attained. Simulation ABANDONED."); return(1); } }while(lf>MINLOGF); //RESOLUTION --> <-----RESOLUTION**** //***************************************************************** //Density of states //***************************************************************** double minlogG=gsl_histogram_min_val(logG); gsl_histogram_shift(logG,-minlogG); gsl_histogram_fprintf(dos,logG,"%g","%g"); //***************************************************************** //Thermodynamics //***************************************************************** double beta,A,wT,Zmin_beta; double lGvalue,maxA,betaC,CTMAX=0; double Z_beta,U,U2,CT,F,S; for (beta=0.01;beta<=30;beta+=0.01) { //****************************************************************** //Energy, free-energy, entropy, specific heat and Tc //****************************************************************** maxA=0; for (ia2=0; ia2<NBINS;ia2++) { lGvalue=gsl_histogram_get(logG,ia2); gsl_histogram_get_range(logG,ia2,&lower,&upper); E=(lower+upper)/2; A=lGvalue-beta*E; if (A>maxA) maxA=A; } gsl_histogram_find(logG,EMIN,&i0); Z_beta=0;U=0;U2=0; for (ia2=0; ia2<NBINS;ia2++) { lGvalue=gsl_histogram_get(logG,ia2); gsl_histogram_get_range(logG,ia2,&lower,&upper); E=(lower+upper)/2; A=lGvalue-beta*E-maxA; Z_beta+=exp(A); U+=E*exp(A); U2+=E*E*exp(A); if(ia2==i0) Zmin_beta=exp(A); } wT=Zmin_beta/Z_beta; F=-log(Z_beta)/beta - maxA/beta; U=U/Z_beta; S= (U-F)*beta; U2=U2/Z_beta; CT=(U2-U*U)*beta*beta; if(CT>CTMAX){ CTMAX=CT; betaC=beta; } fprintf(thermodynamics,"%f %f %f %f %f %f %f \n" ,beta,1/beta,F/(double)(SIZE),S/(double)(SIZE), U/(double)(SIZE),CT/(double)(SIZE),wT); } if (SHOWFLAG==1) printf("# BETAc: %f Tc:%f \n",betaC,1/betaC); fprintf(logfile,"# BETAc: %f Tc:%f \n",betaC,1/betaC); //****************************************************************** //canonical distribuition at Tc //****************************************************************** beta=betaC; double distr_canonica; maxA=0; for (ia2=0; ia2<NBINS;ia2++) { lGvalue=gsl_histogram_get(logG,ia2); gsl_histogram_get_range(logG,ia2,&lower,&upper); E=(lower+upper)/2; A=lGvalue-beta*E; if (A>maxA) maxA=A; } for (ia2=0; ia2<NBINS;ia2++) { lGvalue=gsl_histogram_get(logG,ia2); gsl_histogram_get_range(logG,ia2,&lower,&upper); E=(lower+upper)/2; A=lGvalue-beta*E-maxA; distr_canonica=exp(A); fprintf(canonical,"%f %f %f\n", E/(double)(SIZE),distr_canonica,A); } //***************************************************************** // Finalization //***************************************************************** igraph_destroy(&graph); igraph_vector_destroy(&neighbors); igraph_vector_destroy(&result); gsl_matrix_free(issue); gsl_vector_free(current_issue); gsl_vector_free(v1); gsl_vector_free(v0); gsl_matrix_free(sociedade); gsl_rng_free(r); fclose(wlsrange); fclose(dos); fclose(thermodynamics); fclose(canonical); fclose(logfile); return(0); }
CAMLprim value ml_gsl_histogram_max_val(value vh) { gsl_histogram h; histo_of_val(&h, vh); return copy_double(gsl_histogram_max_val(&h)); }