void Triangles::BoundAnisotropy(Real8 anisomax) { if (verbosity > 1) cout << " -- BoundAnisotropy by " << anisomax << endl; Real8 h1=1.e30,h2=1e-30,rx=0; Real8 coef = 1./(anisomax*anisomax); Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30; for (Int4 i=0;i<nbv;i++) { MatVVP2x2 Vp(vertices[i]); h1=Min(h1,Vp.lmin()); h2=Max(h2,Vp.lmax()); rx = Max(rx,Vp.Aniso2()); Vp.BoundAniso2(coef); hn1=Min(hn1,Vp.lmin()); hn2=Max(hn2,Vp.lmax()); rnx = Max(rnx,Vp.Aniso2()); vertices[i].m = Vp; } if (verbosity>2) { cout << " input : Hmin = " << sqrt(1/h2) << " Hmax = " << sqrt(1/h1) << " factor of anisotropy max = " << sqrt(rx) << endl; cout << " output: Hmin = " << sqrt(1/hn2) << " Hmax = " << sqrt(1/hn1) << " factor of anisotropy max = " << sqrt(rnx) << endl; } }
Real Generalized_HullWhite::discountBondOption(Option::Type type, Real strike, Time maturity, Time bondMaturity) const { Real _a = a(); Real v; v = std::sqrt(Vp(0, maturity, bondMaturity)); Real f = termStructure()->discount(bondMaturity); Real k = termStructure()->discount(maturity)*strike; return blackFormula(type, k, f, v); }
void Triangles::IntersectGeomMetric(const Real8 err=1,const int iso=0) { if(verbosity>1) cout << " -- IntersectGeomMetric geometric err=" << err << (iso ? " iso " : " aniso " ) << endl; Real8 ss[2]={0.00001,0.99999}; Real8 errC = 2*sqrt(2*err); Real8 hmax = Gh.MaximalHmax(); Real8 hmin = Gh.MinimalHmin(); Real8 maxaniso = 1e6; assert(hmax>0); SetVertexFieldOn(); if (errC > 1) errC = 1; for (Int4 i=0;i<nbe;i++) for (int j=0;j<2;j++) { Vertex V; VertexOnGeom GV; // cerr << Number(edges[i]) << " " << ss[j] << endl; Gh.ProjectOnCurve(edges[i],ss[j],V,GV); { GeometricalEdge * eg = GV; Real8 s = GV; R2 tg; // cerr << i << " " << j << " " << Number(V) << " on = " // << Gh.Number(eg) << " at s = " << s << " " << endl; Real8 R1= eg->R1tg(s,tg); // cerr << " R = " << 1/Max(R1,1e-20) << tg << " on x " // << V.r << errC/ Max(R1,1e-20) << " hold=" <<V.m(tg) << " " << endl; Real8 ht = hmax; if (R1>1.0e-20) { // err relative to the length of the edge ht = Min(Max(errC/R1,hmin),hmax); } Real8 hn = iso? ht : Min(hmax,ht*maxaniso); //cerr << ht << " " << hn << "m=" << edges[i][j].m << endl; assert(ht>0 && hn>0); MatVVP2x2 Vp(1/(ht*ht),1/(hn*hn),tg); //cerr << " : " ; Metric MVp(Vp); // cerr << " : " << MVp << endl; edges[i][j].m.IntersectWith(MVp); //cerr << " . " << endl; } } // the problem is for the vertex on vertex }
int main(){ LHDlib::RhoTable rhoTable; // rhoTable.read("C:\\Users\\KeisukeFujii\\Dropbox\\visual_studio\\LHDdata\\flx\\lhd-r375q100b000a8020.flx"); rhoTable.read("C:\\Users\\KeisukeFujii\\Dropbox\\visual_studio\\LHDdata\\flx\\lhd-r390q100g120b000a8020.flx"); size_t size = 100; std::vector<double> R_10(size), Z_10(size); std::vector<double> R_11(size), Z_11(size); std::vector<double> R_12(size), Z_12(size); for (size_t i = 0; i < size; ++i){ double theta = 2.0*myconst::pi / size*i; rhoTable.getRZfromRhoThetaPhi(1.0, theta, myconst::pi/10.0, R_10[i], Z_10[i]); rhoTable.getRZfromRhoThetaPhi(1.1, theta, myconst::pi/10.0, R_11[i], Z_11[i]); rhoTable.getRZfromRhoThetaPhi(1.2, theta, myconst::pi/10.0, R_12[i], Z_12[i]); } IGORdata::write_itx(R_10, Z_10, "RZ_10.itx", "RR_10", "ZZ_10"); IGORdata::write_itx(R_11, Z_11, "RZ_11.itx", "RR_11", "ZZ_11"); IGORdata::write_itx(R_12, Z_12, "RZ_12.itx", "RR_12", "ZZ_12"); size = 48; std::vector<double> rho(size), Vp(size), dVpdrho(size), dVdrho(size); for (size_t i = 0; i < size; ++i){ rho[i] = 1.2 / size*i; Vp[i] = rhoTable.get_Vp(0.0, rho[i]); dVpdrho[i] = rhoTable.get_dVpdrho(rho[i]); dVdrho[i] = rhoTable.get_dVdrho(rho[i]); } IGORdata::write_itx(rho, Vp, "rho_Vp.itx", "rho", "Vp"); IGORdata::write_itx(dVpdrho, dVdrho, "dVdrho.itx", "dVpdrho", "dVdrho"); size_t xsize = 100, ysize(101); std::vector<double> xaxis(xsize), yaxis(ysize); std::vector<std::vector<double>> rhoM(xsize), theta(xsize), drhodx(xsize), drhody(xsize), drhodz(xsize); for (size_t i = 0; i < xsize; ++i) xaxis[i] = 2.5 + 2.5 / xsize * i; for (size_t i = 0; i < ysize; ++i) yaxis[i] = -1.0 + 2.0 / ysize * i; for (size_t i = 0; i < xsize; ++i){ for (size_t j = 0; j < ysize; ++j){ double rho_, theta_; double drhodx_[3]; rhoTable.get_rho_drho(xaxis[i], yaxis[j], myconst::pi*0.1, &rho_, &theta_, drhodx_); rhoM[i].push_back(rho_); theta[i].push_back(theta_); drhodx[i].push_back(drhodx_[0]); drhody[i].push_back(drhodx_[1]); drhodz[i].push_back(drhodx_[2]); } } IGORdata::write_edgeVector(xaxis, "xaxis.itx", "xaxis"); IGORdata::write_edgeVector(yaxis, "yaxis.itx", "yaxis"); IGORdata::write_itx(rhoM, "rhoMatrix.itx", "rhoMatrix"); IGORdata::write_itx(theta, "theta.itx", "theta"); IGORdata::write_itx(drhodx, "drhodx.itx", "drhodx"); IGORdata::write_itx(drhody, "drhody.itx", "drhody"); IGORdata::write_itx(drhodz, "drhodz.itx", "drhodz"); return 0; }
void Triangles::IntersectConsMetric(const double * s,const Int4 nbsol,const int * typsols, const Real8 hmin1,const Real8 hmax1,const Real8 coef, const Real8 anisomax ,const Real8 CutOff,const int NbJacobi, const int DoNormalisation,const int choice) { // the array of solution s is store // sol0,sol1,...,soln on vertex 0 // sol0,sol1,...,soln on vertex 1 // etc. const int dim = 2; int sizeoftype[] = { 1, dim ,dim * (dim+1) / 2, dim * dim } ; // computation of the nb of field Int4 ntmp = 0; if (typsols) { for (Int4 i=0;i<nbsol;i++) ntmp += sizeoftype[typsols[i]]; } else ntmp = nbsol; // n is the total number of fields const Int4 n = ntmp; Int4 i,k,iA,iB,iC,iv; R2 O(0,0); int RelativeMetric = CutOff>1e-30; Real8 hmin = Max(hmin1,MinimalHmin()); Real8 hmax = Min(hmax1,MaximalHmax()); Real8 coef2 = 1/(coef*coef); if(verbosity>1) { cout << " -- Construction of Metric: Nb of sol. " << n << " nbt = " << nbt << " nbv= " << nbv << " coef = " << coef << endl << " hmin = " << hmin << " hmax=" << hmax << " anisomax = " << anisomax << " Nb Jacobi " << NbJacobi ; if (RelativeMetric) cout << " RelativeErr with CutOff= " << CutOff << endl; else cout << " Absolute Err" <<endl; } double *ss=(double*)s, *ssiii = ss; double sA,sB,sC; Real8 *detT = new Real8[nbt]; Real8 *Mmass= new Real8[nbv]; Real8 *Mmassxx= new Real8[nbv]; Real8 *dxdx= new Real8[nbv]; Real8 *dxdy= new Real8[nbv]; Real8 *dydy= new Real8[nbv]; Real8 *workT= new Real8[nbt]; Real8 *workV= new Real8[nbv]; int *OnBoundary = new int[nbv]; for (iv=0;iv<nbv;iv++) { Mmass[iv]=0; OnBoundary[iv]=0; Mmassxx[iv]=0; } for (i=0;i<nbt;i++) if(triangles[i].link) // the real triangles { const Triangle &t=triangles[i]; // coor of 3 vertices R2 A=t[0]; R2 B=t[1]; R2 C=t[2]; // number of the 3 vertices iA = Number(t[0]); iB = Number(t[1]); iC = Number(t[2]); Real8 dett = ::Area2(A,B,C); detT[i]=dett; dett /= 6; // construction of on boundary int nbb =0; for(int j=0;j<3;j++) { Triangle *ta=t.Adj(j); if ( ! ta || !ta->link) // no adj triangle => edge on boundary OnBoundary[Number(t[VerticesOfTriangularEdge[j][0]])]=1, OnBoundary[Number(t[VerticesOfTriangularEdge[j][1]])]=1, nbb++; } workT[i] = nbb; Mmass[iA] += dett; Mmass[iB] += dett; Mmass[iC] += dett; if((nbb==0)|| !choice) { Mmassxx[iA] += dett; Mmassxx[iB] += dett; Mmassxx[iC] += dett; } } else workT[i]=-1; for (Int4 kcount=0;kcount<n;kcount++,ss++) { //for all solution Real8 smin=ss[0],smax=ss[0]; Real8 h1=1.e30,h2=1e-30,rx=0; Real8 coef = 1./(anisomax*anisomax); Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30; for ( iv=0,k=0; iv<nbv; iv++,k+=n ) { dxdx[iv]=dxdy[iv]=dydy[iv]=0; smin=Min(smin,ss[k]); smax=Max(smax,ss[k]); } Real8 sdelta = smax-smin; Real8 absmax=Max(Abs(smin),Abs(smax)); Real8 cnorm = DoNormalisation ? coef2/sdelta : coef2; if(verbosity>2) cout << " Solution " << kcount << " Min = " << smin << " Max = " << smax << " Delta =" << sdelta << " cnorm = " << cnorm << endl; if ( sdelta < 1.0e-10*Max(absmax,1e-20) ) { if (verbosity>2) cout << " Solution " << kcount << " is constant. We skip. " << " Min = " << smin << " Max = " << smax << endl; continue; } for (i=0;i<nbt;i++) if(triangles[i].link) {// for real all triangles // coor of 3 vertices R2 A=triangles[i][0]; R2 B=triangles[i][1]; R2 C=triangles[i][2]; // warning the normal is internal and the // size is the length of the edge R2 nAB = Orthogonal(B-A); R2 nBC = Orthogonal(C-B); R2 nCA = Orthogonal(A-C); // remark : nAB + nBC + nCA == 0 // number of the 3 vertices iA = Number(triangles[i][0]); iB = Number(triangles[i][1]); iC = Number(triangles[i][2]); // for the test of boundary edge // the 3 adj triangles Triangle *tBC = triangles[i].TriangleAdj(OppositeEdge[0]); Triangle *tCA = triangles[i].TriangleAdj(OppositeEdge[1]); Triangle *tAB = triangles[i].TriangleAdj(OppositeEdge[2]); // value of the P1 fonction on 3 vertices sA = ss[iA*n]; sB = ss[iB*n]; sC = ss[iC*n]; R2 Grads = (nAB * sC + nBC * sA + nCA * sB ) /detT[i] ; if(choice) { int nbb = 0; Real8 dd = detT[i]; Real8 lla,llb,llc,llf; Real8 taa[3][3],bb[3]; // construction of the trans of lin system for (int j=0;j<3;j++) { int ie = OppositeEdge[j]; TriangleAdjacent ta = triangles[i].Adj(ie); Triangle *tt = ta; if (tt && tt->link) { Vertex &v = *ta.OppositeVertex(); R2 V = v; Int4 iV = Number(v); Real8 lA = ::Area2(V,B,C)/dd; Real8 lB = ::Area2(A,V,C)/dd; Real8 lC = ::Area2(A,B,V)/dd; taa[0][j] = lB*lC; taa[1][j] = lC*lA; taa[2][j] = lA*lB; Real8 xx = V.x-V.y; Real8 yy = V.x + V.y; //cout << " iv " << ss[iV*n] << " == " << (8*xx*xx+yy*yy) // << " l = " << lA << " " << lB << " " << lC // << " = " << lA+lB+lC << " " << V << " == " << A*lA+B*lB+C*lC << endl; lla = lA,llb=lB,llc=lC,llf=ss[iV*n] ; bb[j] = ss[iV*n] - ( sA*lA + sB*lB + sC*lC ) ; } else { nbb++; taa[0][j]=0; taa[1][j]=0; taa[2][j]=0; taa[j][j]=1; bb[j]=0; } } // resolution of 3x3 lineaire system transpose Real8 det33 = det3x3(taa[0],taa[1],taa[2]); Real8 cBC = det3x3(bb,taa[1],taa[2]); Real8 cCA = det3x3(taa[0],bb,taa[2]); Real8 cAB = det3x3(taa[0],taa[1],bb); assert(det33); // det33=1; // verif // cout << " " << (taa[0][0]*cBC + taa[1][0]*cCA + taa[2][0] * cAB)/det33 << " == " << bb[0] ; // cout << " " << (taa[0][1]*cBC + taa[1][1]*cCA + taa[2][1] * cAB)/det33 << " == " << bb[1]; // cout << " " << (taa[0][2]*cBC + taa[1][2]*cCA + taa[2][2] * cAB)/det33 << " == " << bb[2] // << " -- " ; //cout << lla*sA + llb*sB+llc*sC+ (lla*llb* cAB + llb*llc* cBC + llc*lla*cCA)/det33 // << " == " << llf << endl; // computation of the gradient in the element // H( li*lj) = grad li grad lj + grad lj grad lj // grad li = njk / detT ; with i j k ={A,B,C) Real8 Hxx = cAB * ( nBC.x*nCA.x) + cBC * ( nCA.x*nAB.x) + cCA * (nAB.x*nBC.x); Real8 Hyy = cAB * ( nBC.y*nCA.y) + cBC * ( nCA.y*nAB.y) + cCA * (nAB.y*nBC.y); Real8 Hxy = cAB * ( nBC.y*nCA.x) + cBC * ( nCA.y*nAB.x) + cCA * (nAB.y*nBC.x) + cAB * ( nBC.x*nCA.y) + cBC * ( nCA.x*nAB.y) + cCA * (nAB.x*nBC.y); Real8 coef = 1.0/(3*dd*det33); Real8 coef2 = 2*coef; // cout << " H = " << Hxx << " " << Hyy << " " << Hxy/2 << " coef2 = " << coef2 << endl; Hxx *= coef2; Hyy *= coef2; Hxy *= coef2; //cout << i << " H = " << 3*Hxx/dd << " " << 3*Hyy/dd << " " << 3*Hxy/(dd*2) << " nbb = " << nbb << endl; if(nbb==0) { dxdx[iA] += Hxx; dydy[iA] += Hyy; dxdy[iA] += Hxy; dxdx[iB] += Hxx; dydy[iB] += Hyy; dxdy[iB] += Hxy; dxdx[iC] += Hxx; dydy[iC] += Hyy; dxdy[iC] += Hxy; } } else { // if edge on boundary no contribution => normal = 0 if ( ! tBC || ! tBC->link ) nBC = O; if ( ! tCA || ! tCA->link ) nCA = O; if ( ! tAB || ! tAB->link ) nAB = O; // remark we forgot a 1/2 because // \int_{edge} w_i = 1/2 if i is in edge // 0 if not // if we don't take the boundary // dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x; dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x; dxdx[iB] += ( nAB.x + nBC.x ) *Grads.x; dxdx[iC] += ( nBC.x + nCA.x ) *Grads.x; // warning optimization (1) the divide by 2 is done on the metrix construction dxdy[iA] += (( nCA.y + nAB.y ) *Grads.x + ( nCA.x + nAB.x ) *Grads.y) ; dxdy[iB] += (( nAB.y + nBC.y ) *Grads.x + ( nAB.x + nBC.x ) *Grads.y) ; dxdy[iC] += (( nBC.y + nCA.y ) *Grads.x + ( nBC.x + nCA.x ) *Grads.y) ; dydy[iA] += ( nCA.y + nAB.y ) *Grads.y; dydy[iB] += ( nAB.y + nBC.y ) *Grads.y; dydy[iC] += ( nBC.y + nCA.y ) *Grads.y; } } // for real all triangles Int4 kk=0; for ( iv=0,k=0 ; iv<nbv; iv++,k+=n ) if(Mmassxx[iv]>0) { dxdx[iv] /= 2*Mmassxx[iv]; // warning optimization (1) on term dxdy[iv]*ci/2 dxdy[iv] /= 4*Mmassxx[iv]; dydy[iv] /= 2*Mmassxx[iv]; // Compute the matrix with abs(eigen value) Metric M(dxdx[iv], dxdy[iv], dydy[iv]); MatVVP2x2 Vp(M); //cout <<iv << " M = " << M << " aniso= " << Vp.Aniso() ; Vp.Abs(); M = Vp; dxdx[iv] = M.a11; dxdy[iv] = M.a21; dydy[iv] = M.a22; // cout << " (abs) iv M = " << M << " aniso= " << Vp.Aniso() <<endl; } else kk++; // correction of second derivate // by a laplacien Real8 *d2[3] = { dxdx, dxdy, dydy}; Real8 *dd; for (int xy = 0;xy<3;xy++) { dd = d2[xy]; // do leat 2 iteration for boundary problem for (int ijacobi=0;ijacobi<Max(NbJacobi,2);ijacobi++) { for (i=0;i<nbt;i++) if(triangles[i].link) // the real triangles { // number of the 3 vertices iA = Number(triangles[i][0]); iB = Number(triangles[i][1]); iC = Number(triangles[i][2]); Real8 cc=3; if(ijacobi==0) cc = Max((Real8) ((Mmassxx[iA]>0)+(Mmassxx[iB]>0)+(Mmassxx[iC]>0)),1.); workT[i] = (dd[iA]+dd[iB]+dd[iC])/cc; } for (iv=0;iv<nbv;iv++) workV[iv]=0; for (i=0;i<nbt;i++) if(triangles[i].link) // the real triangles { // number of the 3 vertices iA = Number(triangles[i][0]); iB = Number(triangles[i][1]); iC = Number(triangles[i][2]); Real8 cc = workT[i]*detT[i]; workV[iA] += cc; workV[iB] += cc; workV[iC] += cc; } for (iv=0;iv<nbv;iv++) if( ijacobi<NbJacobi || OnBoundary[iv]) dd[iv] = workV[iv]/(Mmass[iv]*6); } } // constuction of the metrix from the Hessian dxdx. dxdy,dydy Real8 rCutOff=CutOff*absmax;// relative cut off for ( iv=0,k=0 ; iv<nbv; iv++,k+=n ) { // for all vertices //{ //Metric M(dxdx[iv], dxdy[iv], dydy[iv]); // MatVVP2x2 Vp(M); //cout << " iv M="<< M << " Vp = " << Vp << " aniso " << Vp.Aniso() << endl; //} MetricIso Miso; Real8 ci = RelativeMetric ? coef2/(Max(Abs(ss[k]),rCutOff)) : cnorm ; Metric Miv(dxdx[iv]*ci, dxdy[iv]*ci, dydy[iv]*ci); MatVVP2x2 Vp(Miv); Vp.Abs(); h1=Min(h1,Vp.lmin()); h2=Max(h2,Vp.lmax()); Vp.Maxh(hmin); Vp.Minh(hmax); rx = Max(rx,Vp.Aniso2()); Vp.BoundAniso2(coef); hn1=Min(hn1,Vp.lmin()); hn2=Max(hn2,Vp.lmax()); rnx = Max(rnx,Vp.Aniso2()); Metric MVp(Vp); vertices[iv].m.IntersectWith(MVp); }// for all vertices if (verbosity>2) { cout << " Solution " << kcount << endl; cout << " before bounding : Hmin = " << sqrt(1/h2) << " Hmax = " << sqrt(1/h1) << " factor of anisotropy max = " << sqrt(rx) << endl; cout << " after bounding : Hmin = " << sqrt(1/hn2) << " Hmax = " << sqrt(1/hn1) << " factor of anisotropy max = " << sqrt(rnx) << endl; } }// end for all solution delete [] detT; delete [] Mmass; delete [] dxdx; delete [] dxdy; delete [] dydy; delete [] workT; delete [] workV; delete [] Mmassxx; delete [] OnBoundary; }