void Do() { int Fst = 1; double uinter = 0, dinter = 0, pinter = 0, linter = L, rinter = Ro; Result::Ufr = 0; Result::Uto = U2; Result::Discr = 100; clc.Init(Fst ? Mat1 : Mat2, Fst ? U2 : 0, 0, uinter, dinter, pinter, rinter, Fst); Result::Clc(&Mat1Result, dinter, pinter, uinter, rinter, PressureMat); Fst = !Fst; clc.Init(Fst ? Mat1 : Mat2, Fst ? U2 : 0, 0, uinter, dinter, pinter, rinter, Fst); Result::Clc(&Mat2Result, dinter, pinter, uinter, rinter, PressureMat); Fst = !Fst; for(int k = 0; k < Times.SetDim(); k++) { dinter = linter / Times[k]; cout << " Found U " << uinter << " P " << pinter << " Ro " << rinter << " L " << linter << " D " << dinter << "\n"; clc.Init( Fst ? Mat1 : Mat2, Fst ? U2 : 0, 0, uinter, dinter, pinter, rinter, Fst); Result::Clc(&(U_P[k]), dinter, pinter, uinter, rinter, PressureInter); uinter = U2 / 2; if(!Fzero(MisP, 0, U2, uinter, 1e-6, 1e-6, 1000)) cout << "Fzero error\n"; clc.GetPar(uinter, pinter, rinter); Result::Fin(&(U_P[k]), pinter, uinter, rinter); linter = L * Ro / rinter; Fst = !Fst; } cout << " Found U " << uinter << " P " << pinter << " Ro " << rinter << " L " << linter << " D " << 0 << "\n"; OutputRes(); }
map<Stroka, double> MatterStable::TwoPhaseBoundary::MakeBndPnt() { VecCl V, D, P; int SpinIndMin, SpinIndMax; map<Stroka, double> ret; ret["T"] = T; ret["DSr_T"] = 0; ret["DSl_T"] = 0; ret["Dr_T"] = 0; ret["Dl_T"] = 0; ret["P_T"] = 0; ret["E_T"] = 0; ret["dPdT_T"] = 0; if(!SetDP(V, D, P, SpinIndMin, SpinIndMax)) return ret; ret["T"] = T; TwoPhaseBoundary *OldPtr = TwoPhaseBoundaryStaticPtr; PrepareStatic(P, V); double PT_From, PT_To; FindMinMax(V, SpinIndMax, ZeroFunc_Spl_Vmin, PT_From, 1); ret["DSr_T"] = 1 / ZeroFunc_Spl_Vmin; FindMinMax(V, SpinIndMin, ZeroFunc_Spl_Vmax, PT_To, 0); ret["DSl_T"] = 1 / ZeroFunc_Spl_Vmax; IntegralFunc_Negative = 0; double PT_est = IntegralFunc_PV_Int_Static((ZeroFunc_Spl_Vmin + ZeroFunc_Spl_Vmax) * 0.5); Fzero( ZeroFunc_PV_Int_Static, max<double>(PT_From, sqrt(MathZer)), max<double>(PT_To, sqrt(MathZer)), PT_est, Mis * 0.1, Mis * 0.1, 100); //Fzero(ZeroFunc_PV_Int_Static, PT_From, PT_To, PT_est, Mis*0.1, Mis*0.1, 100); ZeroFunc_PV_Int_Static(PT_est); //ret["P_T"] = PT_est; ret["Dl_T"] = 1 / ZeroFunc_SplRes_Bmax; ret["Dr_T"] = 1 / ZeroFunc_SplRes_Bmin; ret["P_T"] = 0.5 * (Mat->Pressure(ret["Dr_T"], T) + Mat->Pressure(ret["Dl_T"], T)); ret["E_T"] = Mat->Energy(ret["Dr_T"], T); double E0 = ret["E_T"]; //,P0=Mat->Pressure(ret["Dr_T"],T); double E1 = Mat->Energy(ret["Dl_T"], T); ret["dPdT_T"] = -(E0 - E1) / (1 / ret["Dr_T"] - 1 / ret["Dl_T"]); ret["Pr_T"] = Mat->Pressure(ret["Dr_T"], T); ret["Pl_T"] = Mat->Pressure(ret["Dl_T"], T); ret["PSr_T"] = Mat->Pressure(ret["DSr_T"], T); ret["PSl_T"] = Mat->Pressure(ret["DSl_T"], T); //if (fabs(ret["Pr_T"]-ret["Pl_T"])>Mis) cout<<" BinodalBndPres l "<<ret["PSl_T"]<<" r "<<ret["PSr_T"]<<"\n"; TwoPhaseBoundaryStaticPtr = OldPtr; return ret; }
main() { int i; float x, Fzero(),Fone(); for( i=0; i< 100; i++) { x = i; printf("%f %f %f\n",x,Fzero(x*x),Fone(x*x)); } }
void Hug2(Int_Par &P1, Int_Par &P2, Int_Par &Pr1, double &Dr1, Int_Par &Pr2, double &Dr2, MatterIO *Mat1, MatterIO *Mat2) { double Pest; //,Delta; MatterAdiabat = Mat1; P1.Pres = PressurePorous(P1.Dens, P1.Ener); MatterAdiabat = Mat2; if(!GetInitialPressure) P2.Pres = PressurePorous(P2.Dens, P2.Ener); else P2.Pres = 0.0001; if(Norm(P1 - P2) < StndErr) { Pr1 = P1; Pr2 = P2; Dr1 = Mat1->Sound(P1.Dens, P1.Ener) + P1.Velo; Dr2 = Dr1; return; } double A1 = max<double>(0.1, P1.Dens * Mat1->Sound(P1.Dens, P1.Ener)); double A2 = max<double>(0.1, P2.Dens * Mat2->Sound(P2.Dens, P2.Ener)); Pest = (P2.Pres * A1 + P1.Pres * A2 + A1 * A2 * (P1.Velo - P2.Velo)) / (A1 + A2); S_Par1 = P1; S_Par2 = P2; S_Mat1 = Mat1; S_Mat2 = Mat2; #ifdef FZERO_HUGONIO_SEARCH //int Fzero(X_func f,double From,double To,double &Guess,double ErrorAbs,double ErrorRel, // int MaxIter); Fzero(MisU, 1e6, M_Eps2, Pest, StndErr, StndErr, 200); // if (3<Fzero(MisU,-1e6,1e6,Pest,StndErr,StndErr,200)); //{ cout <<" Error, could not find Hug2 ZeroFzeroIt\n";} //int ZeroNewtonIt(X_func Func,double &CurPnt,double Tol,int MaxIter, // double Up,double Down,double MaxStp,double BegStp) #else #ifdef NEWTON_HUGONIO_SEARCH if(!ZeroNewtonIt(MisU, Pest, StndErr, 100, 1e6, -1e6, 5 * fabs(Pest))) { double Ctrl = MisU(Pest); cout << " Error, could not find Hug2"; } #else if(!FindZeroPos(MisU, Pest, Delta, StndErr, 0.5 * Pest)) cout << " Error, could not find Hug2"; #endif #endif Pr1 = S_Res1; Pr2 = S_Res2; Dr1 = -S_ResD1 + S_Par1.Velo; Dr2 = -S_ResD2 + S_Par2.Velo; Pr2.Velo = -Pr2.Velo + 2 * P2.Velo; Pr1.Pres = Pest; Pr2.Pres = Pest; };
double MatterStable::TwoPhaseBoundary::ZeroFunc_PV_Int(double pres) { double Vmin, Vmax, Smin = ZeroFunc_Spl_Vmin, Smax = ZeroFunc_Spl_Vmax, Ds = Smax - Smin; //,PresInt,ResErr Vmin = Smin - Ds / 2; Vmax = Smax + Ds / 2; IntegralFunc_Negative = 0; IntegralFunc_Add = -pres; //cout<<" pres "<<pres<<" Vmin "<<1/Dmax<<" pmin "<<Mat->Pressure(Dmax,T)<<" spl "<<IntegralSpline_P_V.Evaluate(1/Dmax)<<" vmax "<<Smin<<" pmax "<<Mat->Pressure(1/Smin,T)<<"\n"; Fzero( IntegralFunc_PV_Int_Static, 1 / Dmax, Smin, Vmin, ZeroFunc_Misf * 0.1, ZeroFunc_Misf * 0.1, 100); Fzero( IntegralFunc_PV_Int_Static, Smax, 1 / Dmin, Vmax, ZeroFunc_Misf * 0.1, ZeroFunc_Misf * 0.1, 100); //Fzero(IntegralFunc_PV_Int_Static,Smin-Ds,Smin,Vmin,ZeroFunc_Misf*0.1,ZeroFunc_Misf*0.1,100); //Fzero(IntegralFunc_PV_Int_Static,Smax,Smax+10000*Ds,Vmax,ZeroFunc_Misf*0.1,ZeroFunc_Misf*0.1,100); ZeroFunc_SplRes_Bmin = Vmin; ZeroFunc_SplRes_Bmax = Vmax; //double MisPmin=fabs(Mat->Pressure(1/Vmin,T)-pres), // MisPmax=fabs(Mat->Pressure(1/Vmax,T)-pres); //if (MisPmin+MisPmax>ZeroFunc_Misf) //cout<<" P "<<pres<<"\nmax V "<<Vmax<<" P "<<Mat->Pressure(1/Vmax,T)<<" spl "<<IntegralSpline_P_V.Evaluate(Vmax)<< //"\nmin V " <<Vmin<<" Pmin "<<Mat->Pressure(1/Vmin,T)<<" spl "<<IntegralSpline_P_V.Evaluate(Vmin)<<"\n"; return Mat->FreeE(1 / Vmin, T) - Mat->FreeE(1 / Vmax, T) + pres * (Vmin - Vmax); }
double MatterFreeE::TemperatureFind(double En,double Den,double Low,double Up, double Start,double Err,int NumIt) { Current=this; E=En;D=Den; double T0=Start; int err; #ifdef FZERO_TEMPERATURE_ITERATION if (4<(err=Fzero(DeltaFree,Low,Up,T0,Err,Err,100)) ) {cout<<" Bad ZeroFzeroFreeE in MatterFreeE::TemperatureFind Not Zero\nfound T " <<T0<<" Mis "<<DeltaFree(T0)<<" err "<<err<<"\n";T0=Zero_Temp;} #else #ifdef FZERO_LOGTEMPERATURE_ITERATION // ln(50)=3.91 ln(1e6)=13.8 ln(100)=4.6 T0=log(Start);Low=log(Low);Up=log(Up);Err=0.1*Err; if (4<(err=Fzero(DeltaFreeLog,Low,Up,T0,Err,Err,100)) ) { cout<<" Bad ZeroFzeroFreeE in MatterFreeE::Temperature Not Zero\nfound T " <<exp(T0)<<" Mis "<<DeltaFreeLog(T0)<<" err "<<err<<"\n"; T0 = MinimTmin; } else T0=exp(T0); #else MinFind1DClass *min1d=new MinFind1DClass(1,NULL); double MinError=Err,FoundEMis; int Cont=1,MaxIt=7,NumT=MaxIt,it; VecCl TmpPar(1),TmpStp(1);TmpPar[1]=L_T;TmpStp[1]=500; T0=Start; #ifdef MULTIDIM_TEMPERATURE_ITERATION Derive2DStd *D2=new Derive2DStd(new DeriveStaticFunc(DeltaFree)); MinFindNDimClass MinNd(D2,min1d,1e-10,1e-8,MinError); for (it=1;((it<=NumT)&&(Cont));it++) Cont=MinNd.Execute(TmpPar,TmpStp,1,FoundEMis); if (it>MaxIt) if (4<(err=Fzero(DeltaFree,Low,Up,T0,Err,Err,100)) ) {cout<<" Bad ZeroFzeroFreeE in MatterFreeE::TemperatureFind Not Zero\nfound T " <<T0<<" Mis "<<DeltaFree(T0)<<" err "<<err<<"\n";T0=Zero_Temp;} else T0=TmpPar[1]; #else T0=log(Start);Low=log(Low);Up=log(Up);Err=0.1*Err; TmpPar[1]=log(TmpPar[1]);TmpStp[1]=log(TmpStp[1]); Derive2DStd *D2=new Derive2DStd(new DeriveStaticFunc(DeltaFreeLog)); MinFindNDimClass MinNd(D2,min1d,1e-10,1e-8,MinError); for (it=1;((it<=NumT)&&(Cont));it++) Cont=MinNd.Execute(TmpPar,TmpStp,1,FoundEMis); if (it>MaxIt) if (4<(err=Fzero(DeltaFreeLog,Low,Up,T0,Err,Err,100)) ) {cout<<" Bad ZeroFzeroFreeE in MatterFreeE::Temperature Not Zero\nfound T " <<exp(T0)<<" Mis "<<DeltaFreeLog(T0)<<" err "<<err<<"\n";T0=Zero_Temp;} else T0=exp(T0); else T0=exp(TmpPar[1]); #endif #endif #endif //#ifdef FZERO_TEMPERATURE_ITERATION //// if (!ZeroNewtonIt(DeltaFree,T0,StndErr*0.1,100,1e6,Zero_Temp,0.8*T0,0.01)) ////int Fzero(X_func f,double From,double To,double &Guess,double ErrorAbs,double ErrorRel, //// int MaxIter) // if (4<(err=Fzero(DeltaFree,50,1e6,T0,StndErr*0.1,StndErr*0.1,100)) ) // {cout<<" Bad ZeroFzeroFreeE in MatterFreeE::Temperature Not Zero\nfound T " // <<T0<<" Mis "<<DeltaFree(T0)<<" err "<<err<<"\n";T0=Zero_Temp;} ////if (err!=0) cout<<" Mis E "<<DeltaFree(T0)<<" T "<<T0<<" err "<<err<<"\n"; return T0; }
int coarsepitch( Float *xw, Float *xwdm, Float *dfm, /* (i/o) ellipse low pass filter memory */ int cpplast) { Float xwd[LXD]; Float cor[MAXPPD1], cor2[MAXPPD1], energy[MAXPPD1]; Float cor2i[HMAXPPD], energyi[HMAXPPD], mplth; Float tmp[DFO+FRSZ], threshold; Float *fp0, *fp1, *fp2, *fp3, s, t, a, b, c, deltae; Float cor2max, energymax, cor2m, energym, ci, eni; int i, j, k, n, npeaks, imax, im, idx[HMAXPPD], plag[HMAXPPD]; int cpp, maxdev, flag, mpflag; /* reset local buffers */ Fzero(cor, MAXPPD1); Fzero(energy, MAXPPD1); /* LOWPASS FILTER xw() TO 800 Hz; SHIFT & OUTPUT INTO xwd() */ /* copy xwd[] from memory to buffer */ Fcopy(xwd, xwdm, XDOFF); /* copy memory to temp buffer */ Fcopy(tmp, dfm, DFO); /* AP and AZ filtering and decimation */ fp0 = xwd + XDOFF; fp1 = tmp + DFO; fp3 = xw; for (i=0;i<FRSZD;i++) { for (k=0;k<DECF;k++) { t = *fp3++; fp2 = fp1-1; for (j=0;j<DFO;j++) t -= adf[j+1]*(*fp2--); *fp1++ = t; } fp2 = fp1-1; t = bdf[0] * (*fp2--); for (j=0;j<DFO;j++) t += bdf[j+1] * (*fp2--); *fp0++ = t; } /* copy temp buffer to memory */ fp1 -= DFO; for (i=0;i<DFO;i++) dfm[i] = *fp1++; /* update xwd() memory */ Fcopy(xwdm, xwd+FRSZD, XDOFF); /* COMPUTE CORRELATION & ENERGY OF PREDICTION BASIS VECTOR */ fp0 = xwd+MAXPPD1; fp1 = xwd+MAXPPD1-M1; s = t = 0.; for (i=0;i<(LXD-MAXPPD1);i++) { s += (*fp1) * (*fp1); t += (*fp0++)*(*fp1++); } energy[M1-1] = s; cor[M1-1] = t; if (t > 0.0F) cor2[M1-1] = t*t; else cor2[M1-1] = -t*t; fp2 = xwd+LXD-M1-1; fp3 = xwd+MAXPPD1-M1-1; for (i=M1;i<M2;i++) { fp0 = xwd+MAXPPD1; fp1 = xwd+MAXPPD1-i-1; t = 0.; for (j=0;j<(LXD-MAXPPD1);j++) t += (*fp0++) * (*fp1++); cor[i] = t; if (t > 0.0F) cor2[i] = t*t; else cor2[i] = -t*t; s = s - (*fp2)*(*fp2) + (*fp3)*(*fp3); fp2--; fp3--; energy[i] = s; } /* FIND POSITIVE COR*COR/ENERGY PEAKS */ npeaks = 0; n = MINPPD-1; while ((n<MAXPPD) && (npeaks<MAX_NPEAKS)) { if ((cor2[n]*energy[n-1]>cor2[n-1]*energy[n]) && (cor2[n]*energy[n+1]>cor2[n+1]*energy[n]) && (cor2[n]>0)) { idx[npeaks] = n; npeaks++; } n++; } /* RETURN EARLY IF THERE IS NO PEAK OR ONLY ONE PEAK */ if (npeaks == 0) /* if there are no positive peak, */ return MINPPD*cpp_scale; /* minimum pitch period in decimated domain */ if (npeaks == 1) /* if there is exactly one peak, */ return (idx[0]+1)*cpp_scale; /* the time lag for this single peak */ /* IF PROGRAM PROCEEDS TO HERE, THERE ARE 2 OR MORE PEAKS */ cor2max=-1e30; energymax=1.0F; imax=0; for (i=0; i < npeaks; i++) { /* USE QUADRATIC INTERPOLATION TO FIND THE INTERPOLATED cor[] AND energy[] CORRESPONDING TO INTERPOLATED PEAK OF cor2[]/energy[] */ /* first calculate coefficients of y(x)=ax^2+bx+c; */ n=idx[i]; a=0.5F*(cor[n+1] + cor[n-1]) - cor[n]; b=0.5F*(cor[n+1] - cor[n-1]); c=cor[n]; /* INITIALIZE VARIABLES BEFORE SEARCHING FOR INTERPOLATED PEAK */ im=0; cor2m=cor2[n]; energym=energy[n]; eni=energy[n]; /* DERTERMINE WHICH SIDE THE INTERPOLATED PEAK FALLS IN, THEN DO THE SEARCH IN THE APPROPRIATE RANGE */ if (cor2[n+1]*energy[n-1] > cor2[n-1]*energy[n+1]) { /* if right side */ deltae=(energy[n+1] - eni) * INVDECF; /*increment for linear interp.*/ for (k = 0; k < HDECF; k++) { ci = a*x2[k] + b*x[k] + c; /* quadratically interpolated cor[] */ eni += deltae; /* linearly interpolated energy[] */ if (ci*ci*energym > cor2m*eni) { im = k+1; cor2m=ci*ci; energym=eni; } } } else { /* if interpolated peak is on the left side */ deltae=(energy[n-1] - eni) * INVDECF; /*increment for linear interp.*/ for (k = 0; k < HDECF; k++) { ci = a*x2[k] - b*x[k] + c; eni += deltae; if (ci*ci*energym > cor2m*eni) { im = -k-1; cor2m=ci*ci; energym=eni; } } } /* SEARCH DONE; ASSIGN cor2[] AND energy[] CORRESPONDING TO INTERPOLATED PEAK */ plag[i]=(idx[i]+1)*cpp_scale + im; /* lag of interp. peak */ cor2i[i]=cor2m; /* interpolated cor2[] of i-th interpolated peak */ energyi[i]=energym; /* interpolated energy[] of i-th interpolated peak */ /* SEARCH FOR GLOBAL MAXIMUM OF INTERPOLATED cor2[]/energy[] peak */ if (cor2m*energymax > cor2max*energym) { imax=i; cor2max=cor2m; energymax=energym; } } cpp=plag[imax]; /* first candidate for coarse pitch period */ mplth=plag[npeaks-1]*1./DECF; /* plag[] is Q2 */ /* FIND THE LARGEST PEAK (IF THERE IS ANY) AROUND THE LAST PITCH */ maxdev=(int) (DEVTH*cpplast); /* maximum deviation from last pitch */ im = -1; cor2m = -1e30; energym = 1.0F; for (i=0;i<npeaks;i++) { /* loop thru the peaks before the largest peak */ if (abs(plag[i]-cpplast) <= maxdev) { if (cor2i[i]*energym > cor2m*energyi[i]) { im=i; cor2m=cor2i[i]; energym=energyi[i]; } } } /* if there is no peaks around last pitch, then im is still -1 */ /* NOW SEE IF WE SHOULD PICK ANY ALTERNATICE PEAK */ /* FIRST, SEARCH FIRST HALF OF PITCH RANGE, SEE IF ANY QUALIFIED PEAK HAS LARGE ENOUGH PEAKS AT EVERY MULTIPLE OF ITS LAG */ i=0; while (plag[i] < 0.5*mplth*DECF) { /* DETERMINE THE APPROPRIATE THRESHOLD FOR THIS PEAK */ if (i != im) { /* if not around last pitch, */ threshold = TH1; /* use a higher threshold */ } else { /* if around last pitch */ threshold = TH2; /* use a lower threshold */ } /* IF THRESHOLD EXCEEDED, TEST PEAKS AT MULTIPLES OF THIS LAG */ if (cor2i[i]*energymax > threshold*cor2max*energyi[i]) { flag=1; j=i+1; k=0; s=2.0F*plag[i]; /* initialize t to twice the current lag */ while (s<=mplth*DECF) { /* loop thru all multiple lag <= mplth */ mpflag=0; /* initialize multiple pitch flag to 0 */ a=MPR1*s; /* multiple pitch range lower bound */ b=MPR2*s; /* multiple pitch range upper bound */ while (j < npeaks) { /* loop thru peaks with larger lags */ if (plag[j] > b) { /* if range exceeded, */ break; /* break the innermost while loop */ } /* if didn't break, then plag[j] <= b */ if (plag[j] > a) { /* if current peak lag within range, */ /* then check if peak value large enough */ if (k < 4) { c = MPTH[k]; } else { c = MPTH4; } if (cor2i[j]*energymax > c*cor2max*energyi[j]) { mpflag=1; /* if peak large enough, set mpflag, */ break; /* and break the innermost while loop */ } } j++; } /* if no qualified peak found at this multiple lag */ if (mpflag == 0) { flag=0; /* disqualify the lag plag[i] */ break; /* and break the while (s<=mplth) loop */ } k++; s += plag[i]; /* update s to the next multiple pitch lag */ } /* if there is a qualified peak at every multiple of plag[i], */ if (flag == 1) { return plag[i]; /* and return to calling function */ } } i++; if (i == npeaks) break; /* to avoid out of array bound error */ } /* IF PROGRAM PROCEEDS TO HERE, NONE OF THE PEAKS WITH LAGS < 0.5*mplth QUALIFIES AS THE FINAL PITCH. IN THIS CASE, CHECK IF THERE IS ANY PEAK LARGE ENOUGH AROUND LAST PITCH. IF SO, USE ITS LAG AS THE FINAL PITCH. */ if (im != -1) { /* if there is at least one peak around last pitch */ if (im == imax) { /* if this peak is also the global maximum, */ return cpp; /* return first pitch candidate at global max */ } if (im < imax) { /* if lag of this peak < lag of global max, */ if (cor2m*energymax > LPTH2*cor2max*energym) { if (plag[im] > HMAXPPD*cpp_scale) { return plag[im]; } for (k=2; k<=5;k++) { /* check if current candidate pitch */ s=plag[imax]/(float)(k); /* is a sub-multiple of */ a=SMDTH1*s; /* the time lag of */ b=SMDTH2*s; /* the global maximum peak */ if (plag[im]>a && plag[im]<b) { /* if so, */ return plag[im]; /* and return as pitch */ } } } } else { /* if lag of this peak > lag of global max, */ if (cor2m*energymax > LPTH1*cor2max*energym) { return plag[im]; /* accept its lag */ } } } /* IF PROGRAM PROCEEDS TO HERE, WE HAVE NO CHOICE BUT TO ACCEPT THE LAG OF THE GLOBAL MAXIMUM */ return cpp; }