//------------------------------------------------------------------------------ void MfLowRankApproximation::initialize() { double dx; double constValue; double endValue; double constEnd; double epsilon; dx = grid.DX; try { nOrbitals = cfg->lookup("spatialDiscretization.nSpatialOrbitals"); constEnd = cfg->lookup("meanFieldIntegrator.lowRankApproximation.constEnd"); constValue = cfg->lookup("meanFieldIntegrator.lowRankApproximation.constValue"); endValue = cfg->lookup("meanFieldIntegrator.lowRankApproximation.endValue"); epsilon = cfg->lookup("meanFieldIntegrator.lowRankApproximation.epsilon"); } catch (const SettingNotFoundException &nfex) { cerr << "MfLowRankApproximation::Error reading entry from config object." << endl; exit(EXIT_FAILURE); } int nConst = constEnd/dx; int constCenter = nGrid/2; Vxy = zeros(nGrid, nGrid); for(uint p=0; p<potential.size(); p++) { for(int i=0; i<nGrid; i++) { for(int j=0; j<nGrid; j++) { Vxy(i, j) += potential[p]->evaluate(i, j); } } } // Using a simple discretization equal to the discretization of // the system. mat h = hExactSpatial(); // mat h = hPiecewiseLinear(); mat Q = eye(nGrid,nGrid); // Using a consant weight in the center of the potential // and a linear decrease from the center. vec g = gLinear(nGrid, constCenter, nConst, constValue, endValue); mat C = cMatrix(g, h, dx); vec lambda; mat eigvec; eig_sym(lambda, eigvec, inv(C.t())*Vxy*inv(C)); mat Ut = C.t()*eigvec; mat QU = inv(Q)*Ut; // Sorting the eigenvalues by absoulte value and finding the number // of eigenvalues with abs(eigenval(i)) > epsilon uvec indices = sort_index(abs(lambda), 1); M = -1; for(uint m=0; m <lambda.n_rows; m++) { cout << abs(lambda(indices(m))) << endl; if(abs(lambda(indices(m))) < epsilon) { M = m; break; } } // cout << min(abs(lambda)) << endl; // cout << "hei" << endl; // cout << lambda << endl; // M = 63; if(M < 0) { cerr << "MfLowRankApproximation:: no eigenvalues < epsilon found." << " Try setting epsilon to a higher number" << endl; exit(EXIT_FAILURE); } eigenval = zeros(M); for(int m=0; m <M; m++) { eigenval(m) = lambda(indices(m)); } // Calculating the U matrix U = zeros(nGrid, M); for(int m=0; m < M; m++) { for(uint j=0; j<h.n_rows; j++) { U(j,m) = 0; for(uint i=0; i<h.n_cols; i++) { U(j,m) += h(j,i)*QU(i,indices(m)); } } } cout << "MfLowRankApproximation:: Trunction of eigenvalues at M = " << M << endl; #if 1 // For testing the low rank approximation's accuracy mat appV = zeros(nGrid, nGrid); for(int i=0; i<nGrid; i++) { for(int j=0; j<nGrid; j++) { appV(i,j) = 0; for(int m=0; m<M; m++) { appV(i,j) += eigenval(m)*U(i,m)*U(j,m); } } } mat diffV = abs(Vxy - appV); cout << "max_err = " << max(max(abs(Vxy - appV))) << endl; diffV.save("../DATA/diffV.mat"); appV.save("../DATA/Vapp.mat"); Vxy.save("../DATA/Vex.mat"); cout << nGrid << endl; // exit(EXIT_SUCCESS); #endif cout << "test" << endl; Vm = zeros<cx_vec>(M); Vqr = zeros<cx_vec>(nGrid); }
void VideoFluids::trackVelocity(Matrix& Zn1,Matrix& Zn,Matrix& U,Matrix& V) { Matrix Zx(height,width),Zy(height,width),ZZx(height,width),ZZy(height,width),Zt(height,width),ZZt(height,width),ZZtx(height,width),ZZty(height,width); Matrix Au1(height,width),Au2(height,width),Av1(height,width),Av2(height,width); Matrix Z2x(height,width),Z2y(height,width),Z2(height,width); Matrix Cu(height,width),Cv(height,width); Matrix tmp(height,width),tmp1(height,width); Matrix U_old(height,width),V_old(height,width),Ux(height,width),Uy(height,width),Vx(height,width),Vy(height,width),Uax(height,width),Uay(height,width),Vax(height,width),Vay(height,width),Uxy(height,width),Vxy(height,width); Matrix Coe(height,width); Zt = Zn; Zt -= Zn1; DotMul(Zn,Zt,ZZt); Zn.output("Zn.txt"); Zn1.output("Zn1.txt"); Zt.output("Zt.txt"); Partial(ZZt,ZZtx,AXIS_X); Partial(ZZt,ZZty,AXIS_Y); Partial(Zn,Zx,AXIS_X); Partial(Zn,Zy,AXIS_Y); DotMul(Zn,Zx,ZZx); DotMul(Zn,Zy,ZZy); DotMul(Zx,Zx,Au1); Partial(ZZx,tmp,AXIS_X); Au1-=tmp; DotMul(Zn,Zn,tmp); Au1+=tmp; Au1+=2*alpha*alpha; DotMul(Zx,Zy,Au2); Partial(ZZy,tmp,AXIS_X); Au2-=tmp; DotMul(Zx,Zy,Av1); Partial(ZZx,tmp,AXIS_Y); Av1-=tmp; DotMul(Zy,Zy,Av2); Partial(ZZy,tmp,AXIS_Y); Av2-=tmp; DotMul(Zn,Zn,tmp); Av2+=tmp; Av2+=2*alpha*alpha; DotMul(Zn,Zn,Z2); Partial(Z2,Z2x,AXIS_X); Partial(Z2,Z2y,AXIS_Y); for (int i = 0;i<height;i++) for (int j = 0;j<width;j++) Coe[i][j] = 1.0/(Au1[i][j]*Av2[i][j]-Au2[i][j]*Av1[i][j]); U = 0.0; V = 0.0; for (int iter_time = 0;iter_time<iterationTime;iter_time++) { V_old = V; U_old = U; Partial(U,Ux,AXIS_X); Partial(U,Uy,AXIS_Y); Partial(V,Vx,AXIS_X); Partial(V,Vy,AXIS_Y); Partial(Vx,Vxy,AXIS_Y); Partial(Ux,Uxy,AXIS_Y); Average(U,Uax,AXIS_X); Average(U,Uay,AXIS_Y); Average(V,Vax,AXIS_X); Average(V,Vay,AXIS_Y); DotMul(Z2x,Ux,Cu); DotMul(ZZy,Vx,tmp); Cu += tmp; tmp = ZZx*-1; tmp+=Z2x; DotMul(tmp,Vy,tmp1); Cu+=tmp1; tmp = Z2; tmp+=alpha*alpha; DotMul(tmp,Uax,tmp1); Cu+=tmp1; tmp1=Uay; tmp1*=alpha*alpha; Cu+=tmp1; DotMul(Z2,Vxy,tmp1); Cu+=tmp1; DotMul(Zx,Zt,tmp); Cu-=tmp; Cu+=ZZtx; DotMul(Z2y,Vy,Cv); DotMul(ZZx,Uy,tmp); Cv += tmp; tmp = ZZy; tmp*=-1; tmp+=Z2y; DotMul(tmp,Ux,tmp1); Cv+=tmp1; tmp = Z2; tmp+=alpha*alpha; DotMul(tmp,Vay,tmp1); Cv+=tmp1; tmp1=Vax; tmp1*=alpha*alpha; Cv+=tmp1; DotMul(Z2,Uxy,tmp1); Cv+=tmp1; DotMul(Zy,Zt,tmp); Cv-=tmp; Cv+=ZZty; for (int i = 0;i<height;i++) for (int j = 0;j<width;j++) { U[i][j] = Coe[i][j]*(Av2[i][j]*Cu[i][j]-Au2[i][j]*Cv[i][j]); V[i][j] = Coe[i][j]*(-Av1[i][j]*Cu[i][j]+Au1[i][j]*Cv[i][j]); } for (int i = 0;i<height;i++) { U[i][0] = U[i][1]; U[i][width-1] = U[i][width-2]; V[i][0] = V[i][1]; V[i][width-1] =V[i][width-2]; } for (int i = 0;i<width;i++) { U[0][i] = U[1][i]; U[height-1][i] = U[height-2][i]; V[0][i] = V[1][i]; V[height-1][i] =V[height-2][i]; } FILE* fp; // Au1.output("Au1.txt"); // Au2.output("Au2.txt"); // Av1.output("Av1.txt"); // Av2.output("Av2.txt"); // Cu.output("Cu.txt"); // Cv.output("Cv.txt"); float d1 = Difference(U,U_old); float d2 = Difference(V,V_old); // U.output("U.txt"); // U_old.output("U_old.txt"); // V.output("V.txt"); cout<<d1<<' '<<d2<<endl; if (d1<iterationTorlerance && d2<iterationTorlerance) break; } U.output("U.txt"); cv::Mat showV(height,width,CV_8UC3); float lowv=10000000,lowu=10000000,highu=-10000000,highv=-1000000; for(int j=0;j<height;j++){ for(int k=0;k<width;k++){ if(U[j][k]>highu) highu=U[j][k]; if(U[j][k]<lowu) lowu=U[j][k]; if(V[j][k]>highv) highv=V[j][k]; if(V[j][k]<lowv) lowv=V[j][k]; } } for(int j=0;j<height;j++){ for(int k=0;k<width;k++){ //printf("%d %d\n",j,k); //if(sfs_list[i][j][k]<low) // showH.at<uchar>(j,k)=0; //else float u=(U[j][k]-lowu)/(highu-lowu); float v=(V[j][k]-lowv)/(highv-lowv); if(u>0.5) showV.at<cv::Vec3b>(j,k)[2]=255; else showV.at<cv::Vec3b>(j,k)[2]=255*u; if(v>0.5){ showV.at<cv::Vec3b>(j,k)[0]=255; showV.at<cv::Vec3b>(j,k)[1]=255*(1-v); } else{ showV.at<cv::Vec3b>(j,k)[1]=255; showV.at<cv::Vec3b>(j,k)[0]=255*v; } } } cv::imwrite("testV.bmp",showV); printf("show you"); }