コード例 #1
0
ファイル: equations.c プロジェクト: ZJLi2013/HPC1
PetscErrorCode equation(SNES snes, Vec soln_vec, Vec fun_vec, void* ptr)
{
	//data structure will be contained in ptr
	Data* data = (Data*) ptr;
	Params P = data->P;
	DA da = data->da;

	DALocalInfo info;
	PetscFunctionBegin;

	DAGetLocalInfo(da, &info);
	Vec sv_local; //need local vector containing ghost point information

	DACreateLocalVector(da, &sv_local);
	DAGlobalToLocalBegin(da, soln_vec, INSERT_VALUES, sv_local);
	DAGlobalToLocalEnd(da, soln_vec, INSERT_VALUES, sv_local);

	//to evaluate fuction, the sv_local soln_vec need to be converted into Field arrays
	Field **X;
	Field **F;

	DAVecGetArray(da, sv_local, &X);
	DAVecGetArray(da, fun_vec, &F);
	//since sv_local is local vector, X will have access to ghost points
	
	PetscInt i, j, Ny = P.Ny;
	PetscScalar hx = P.hx; hy = P.hy; x, y;

	for(i=info.xs; i<info.xs + info.xm; i++){
		for(j=info.ys; j<info.ys+info.ym; j++){
			x = i *hx;
			y = j *hy;

			if(j==0) {
				F[j][i].u = X[j][i].u - 0.5*(sin(2*PETSC_PI*x) + 1);
				F[j][i].v = X[j][i].v ;
			}
			else if (j== Ny-1){
				F[j][i].u = X[j][i].u;
				F[j][i].v = X[j][i].v - 0.5*(sin(2*PETSC_PI*x) + 1);
			}
			else {
				F[j][i].u = lap(u) + X[j][i].u * X[j][i].v ;
				F[j][i].v = lap(v) - X[j][i].u * X[j][i].v ;
			}
		}
	}

	DAVecRestoreArray(da, fun_vec, &F);
	DAVecRestoreArray(da, sv_local, &X);

	VecDestory(sv_local);

	PetscFuntionReturn(0);
}
コード例 #2
0
void CNDCGRankLoss::find_permutation(int size, int offset, vector<double> a, 
				     vector<double> b, vector<double> c, 
				     Scalar *f, int *input_pi){
  /* setting up C_ij */
  double **C = (double **)malloc(sizeof(double*)*size);
  for (int i=0;i<size;i++){
    C[i] = (double *)malloc(sizeof(double)*size);
  }
  //cout << "before inner loop\n";
  //cout << "size = "<< size << "\n";
  //cout << "a.size = "<< a.size() <<"\n";
  //cout << "b.size = "<< b.size() << "\n";
  //cout << "c.size = "<< c.size() << "\n";
  for (int i=0;i<size;i++){
    for (int j=0;j<size;j++){
      C[i][j] = -c[i]*get(f, offset, j) + b[j]*a[i];
    }
  }
  //cout << "after inner loop\n";
  int *row = (int *)malloc(sizeof(int)*size);
  
  //cout << "before lap\n";
  lap(size,C,input_pi,row);  
  //cout << "after lap\n";

  free(row);
  for (int i=0;i<size;i++){
    free(C[i]);
  }
  free(C);
}
コード例 #3
0
ファイル: fiedler.C プロジェクト: chrinide/Block
std::vector<int> fiedler_reorder(const SymmetricMatrix& m)
{
  SymmetricMatrix absm=m;
  const int nrows=m.Nrows();
  for (int i=0;i<nrows;++i) {
    for (int j=0;j<=i;++j){
       //absolute value
       absm.element(i,j)=std::fabs(absm.element(i,j));
    }
  }

  //laplacian
  SymmetricMatrix lap(nrows);
  lap=0.;
  for (int i=0;i<nrows;++i)
    lap.element(i,i)=absm.Row(i+1).Sum();
  lap-=absm;

  DiagonalMatrix eigs; 
  Matrix vecs;
  
  EigenValues(lap,eigs,vecs);

  ColumnVector fvec=vecs.Column(2);
  std::vector<double> fvec_stl(nrows);
  //copies over fvec to fvec_stl
  std::copy(&fvec.element(0),&fvec.element(0)+nrows,fvec_stl.begin());
  std::vector<int> findices;
  //sorts the data by eigenvalue in ascending order
  sort_data_to_indices(fvec_stl,findices);
  
  return findices;
  /* BLOCK works with findices*/

}
コード例 #4
0
ファイル: tcxparser.cpp プロジェクト: tumic0/GPXSee
void TCXParser::activity(TrackData &track)
{
	while (_reader.readNextStartElement()) {
		if (_reader.name() == "Lap")
			lap(track);
		else
			_reader.skipCurrentElement();
	}
}
コード例 #5
0
void Stopwatch::onLap()
{
    qint64 lapTime = 0;

    lapTime += accumulator;

    if (elapsedTimer.isValid()) {
        lapTime += elapsedTimer.elapsed();
    }

    emit lap(zero.addMSecs(lapTime));
}
コード例 #6
0
ファイル: Prediction.cpp プロジェクト: mit-gfx/ImageStack
bool SeamlessClone::test() {
    // This op is a trivial use of inpaint. If inpaint works so does
    // this. Let's just make sure it doesn't crash.


    // A circular mask
    Image mask(99, 97, 1, 1);
    Expr::X x; Expr::Y y;
    mask.set(Select((x-50)*(x-50) + (y-50)*(y-50) < 30*30, 0, 1));

    // The background is a smooth ramp
    Image background(99, 97, 1, 3);
    background.set((x + 2*y)/300);

    // The foreground to paste on is noise
    Image foreground(99, 97, 1, 3);
    Noise::apply(foreground, 0, 1);

    Image im = background.copy();
    SeamlessClone::apply(im, foreground, mask);

    // The laplacian of the result should be as if you just pasted the
    // laplacian of the foreground on top of the background.
    Image lap(3, 3, 1, 1);
    lap(1, 0) = lap(0, 1) = lap(2, 1) = lap(1, 2) = 1;
    lap(1, 1) = -4;
    Image lapFg = Convolve::apply(foreground, lap, Convolve::Clamp);
    Image lapBg = Convolve::apply(background, lap, Convolve::Clamp);
    Image lapIm = Convolve::apply(im, lap, Convolve::Clamp);
    Composite::apply(lapBg, lapFg, 1-mask);
    return nearlyEqual(lapIm, lapBg);
}
コード例 #7
0
int main( int argc, char** argv )
{
    LibMeshInit init (argc, argv);

    Mesh mesh(init.comm());

    MeshTools::Generation::build_square (mesh,
                                         4, 4,
                                         0.0, 1.0,
                                         0.0, 1.0,
                                         QUAD4);

//    XdrIO mesh_io(mesh);
//    mesh_io.read("one_tri.xda");

    mesh.print_info();

    EquationSystems es (mesh);

    LinearImplicitSystem& system = es.add_system<LinearImplicitSystem>("lap");

    uint u_var = system.add_variable("u", FIRST, LAGRANGE);

    Laplacian lap(es);

    system.attach_assemble_object(lap);

    std::set<boundary_id_type> bd_ids;
    bd_ids.insert(1);
    bd_ids.insert(3);

    std::vector<uint> vars(1,u_var);

    ZeroFunction<Real> zero;

    DirichletBoundary dirichlet_bc(bd_ids, vars, &zero);

    system.get_dof_map().add_dirichlet_boundary(dirichlet_bc);

    es.init();

    es.print_info();

    system.solve();

    VTKIO(mesh).write_equation_systems("lap.pvtu",es);

    return 0;
}
コード例 #8
0
ファイル: dplap.c プロジェクト: raunakkr/DS_Algorithms
 int lap(int j,int k){
	 int maxt=0,i;
	  if(j<1 || k<2)
		 return 0;

		for(i=j-1;i>=0;i--){
	 if(a[i]+a[k]==2*a[j])
		  maxt=max(maxt,1+lap(i,j));

	  else if(a[i]+a[k]<2*a[j])
				  break;

				  }
			return maxt;
}
コード例 #9
0
ファイル: dplap.c プロジェクト: raunakkr/DS_Algorithms
int lap_util(){
  int k,j,maxt=0;
	if(n<=2)
	  return n;

for(k=n-1;k>=0;k--){
  for(j=k-1;j>=1;j--){
	maxt=max(maxt,lap(j,k));
 printf("%d>>>\n",maxt);
 }

 }
  return maxt+2;

}
コード例 #10
0
ファイル: Maximize_method.cpp プロジェクト: nliko/mainline
 double dfunc(double * _p, double * _g) {
     update_positions(_p);
     wf->updateLap(wfdata,sample);
     int count=0;
     int nelec=sample->electronSize();
     Wf_return lap(1,5);
     wf->getVal(wfdata,0,lap);
     _g[count++]=-lap.amp(0,0);
     for(int e=0; e< nelec; e++) {
         wf->getLap(wfdata,e,lap);
         for(int d=0; d< 3; d++) {
             _g[count++]=-lap.amp(0,d+1);
         }
     }
     return _g[0];
 }
コード例 #11
0
ファイル: cbap.c プロジェクト: johnlarusic/arrow
int
arrow_cbap_lap(arrow_problem *problem, double *result)
{
    int ret = ARROW_SUCCESS;
    int n = problem->size * 2;
    int *x, *y, *pi, *d, *pred, *label;
    arrow_heap heap;
    
    if(!init_data(n, &x, &y, &pi, &d, &pred, &label, &heap))
    {
        ret = ARROW_FAILURE;
        goto CLEANUP;
    }
    
    *result = lap(problem, INT_MAX, x, y, pi, d, pred, label, &heap);

CLEANUP:
    destruct_data(&x, &y, &pi, &d, &pred, &label, &heap);
    return ret;
}
コード例 #12
0
ファイル: standalone-1d.cpp プロジェクト: nushio3/formura
int main () {
  const int n_thre = omp_get_max_threads();

  fill_initial_condition();

#pragma omp parallel
  {
    int tid=2*omp_get_thread_num();
    for(int x=0;x<SX;++x) {
      for(int y=0;y<SY;++y) {
        for(int z=0;z<SZ;++z) {
          double u,v; get_solution_at(0,x,y,z, u,v);
          ats(sU0,tid,x,y,z)=u;
	  ats(sV0,tid,x,y,z)=v;
        }
      }
    }
  }

  std::cerr << "Setting up wall values..." << std::endl;
  for(int t = 0;t<T_MAX;++t){
    /*
#pragma omp parallel
    {
      int tid=2*omp_get_thread_num();
      for(int x=SX-2;x<SX;++x) {
        for(int y=0;y<SY;++y) {
          for(int z=0;z<SZ;++z) {
            double u,v; get_solution_at(t,x+t,y+t,z+t, u,v);
            Uwx[tid][t][x-(SX-2)][y][z] = u;
            Vwx[tid][t][x-(SX-2)][y][z] = v;
          }
        }
      }
      for(int x=0;x<SX;++x) {
        for(int y=SY-2;y<SY;++y) {
          for(int z=0;z<SZ;++z) {
            double u,v; get_solution_at(t,x+t,y+t,z+t, u,v);
            Uwy[tid][t][x][y-(SY-2)][z] = u;
            Vwy[tid][t][x][y-(SY-2)][z] = v;
          }
        }
      }
      for(int x=0;x<SX;++x) {
        for(int y=0;y<SY;++y) {
          for(int z=SZ-2;z<SZ;++z) {
            double u,v; get_solution_at(t,x+t,y+t,z+t, u,v);
            Uwz[tid][t][x][y][z-(SZ-2)] = u;
            Vwz[tid][t][x][y][z-(SZ-2)] = v;
          }
        }
      }
    */
  }

  for(int trial=0;trial<10;++trial) {
    std::cerr << "Carrying out simulation..." << std::endl;
    // set initial condition
#pragma omp parallel
    {
      const int tid=2*omp_get_thread_num();
      for(int x=0;x<SX;++x) {
        for(int y=0;y<SY;++y) {
          for(int z=0;z<SZ;++z) {
            ats(sU,tid,x,y,z)=ats(sU0,tid,x,y,z);
            ats(sV,tid,x,y,z)=ats(sV0,tid,x,y,z);
          }
        }
      }
    }
    double time_comp=0, time_comm=0, time_begin, time_end;

    //for(int heating=0;heating<10;++heating) {
      time_begin = wctime();
#pragma omp parallel 
      for (int tid=0;tid<n_thre;++tid) {
        //const int tid=2*omp_get_thread_num();
        for(int t = 0; t < T_MAX; ++t){

          // destructively update the state
          /*
          const auto lap = [](Real ar[SX][SY][SZ],int x, int y, int z) {
            auto ret = ar[x][y+1][z+1] + ar[x+2][y+1][z+1]
            + ar[x+1][y][z+1] + ar[x+1][y+2][z+1]
            + ar[x+1][y+1][z] + ar[x+1][y+1][z+2]
            - 6*ar[x+1][y+1][z+1];
            return ret / dx / dx;
            };*/

#define lap(ar,b,x,y,z)			       \
          (ats(ar,b,x,y+1,z+1) + ats(ar,b,x+2,y+1,z+1) \
            + ats(ar,b,x+1,y,z+1) + ats(ar,b,x+1,y+2,z+1) \
            + ats(ar,b,x+1,y+1,z) + ats(ar,b,x+1,y+1,z+2) \
              - 6*ats(ar,b,x+1,y+1,z+1)) / dx / dx


#pragma omp for collapse(2)
          for(int x=0;x<SX-2;++x) {
            for(int y=0;y<SY-2;++y) {
#pragma omp simd
              for(int z=0;z<SZ-2;++z) {
                Real u=ats(sU,tid,x+1,y+1,z+1) ;
                Real v=ats(sV,tid,x+1,y+1,z+1) ;

                auto du_dt = -Fe * u*v*v + Fu*(1-u) + Du * lap(sU,tid,x,y,z);
		auto dv_dt =  Fe * u*v*v - Fv*v     + Dv * lap(sV,tid,x,y,z);
                ats(sU,tid,x,y,z) = u+dt*du_dt;
		ats(sV,tid,x,y,z) = v+dt*dv_dt;
              }
            }
          }
        }
      }
      time_end = wctime();
      //}

    double flop = 29.0 * (SX-2)*(SY-2)*(SZ-2) *T_MAX * n_thre;
    double bw_gb= 8.0 * 2 * 7 * (SX-2)*(SY-2)*(SZ-2) *T_MAX * n_thre;
    double time_elapse = time_end-time_begin;

    {
      const int t = T_MAX;
      double num[BANK]={0},den[BANK]={0};
#pragma omp parallel
      {
        int tid=2*omp_get_thread_num();

        for(int x=0;x<SX-2;++x) {
          for(int y=0;y<SY-2;++y) {
            for(int z=0;z<SZ-2;++z) {
              double u,v; get_solution_at(t,x+t,y+t,z+t, u,v);
              num[tid] += std::abs(u-ats(sU,tid,x,y,z));
              den[tid] += 1;
            }
          }
        }
      }
      double sum_num = 0, sum_den = 0;
      for(int i=0;i<BANK;++i){
        sum_num += num[i];
        sum_den += den[i];
      }

      std::ostringstream msg;
      msg << n_thre << "  " << SX << " " << SY << " " << SZ << " " << T_MAX << " "
          << " t: " << time_elapse << " " << time_comm << " " << time_comp << " GFlops: " << flop/time_elapse/1e9<<  " GBps: " << bw_gb/time_elapse/1e9<< " error: " << (sum_num/sum_den);
      std::ofstream log_file("benchmark-standalone.txt", std::ios::app);
      std::cout << msg.str() << std::endl;
      log_file << msg.str() << std::endl;
    }
  }
}
コード例 #13
0
ファイル: cbap.c プロジェクト: johnlarusic/arrow
/****************************************************************************
 * Private function implementations
 ****************************************************************************/
int
arrow_cbap_solve(arrow_problem *problem, arrow_problem_info *info, 
                 double max_length, arrow_bound_result *result)
{
    int ret = ARROW_SUCCESS;
    int n = problem->size * 2;
    int i, cost, max_cost;
    int low, high, median, delta;
    int *x, *y, *pi, *d, *pred, *label;
    double length;
    double start_time, end_time;
    arrow_heap heap;
    
    start_time = arrow_util_zeit();
    
    if(!init_data(n, &x, &y, &pi, &d, &pred, &label, &heap))
    {
        ret = ARROW_FAILURE;
        goto CLEANUP;
    }
    
    /* Initial LAP call */
    length = lap(problem, INT_MAX, x, y, pi, d, pred, label, &heap);
    if(length > max_length)
    {
        arrow_print_error("Given max_length is infeasible.\n");
        ret = ARROW_FAILURE;
        goto CLEANUP;
    }
    arrow_debug("Initial LAP solution: %.0f\n", length);
    
    /* Find the largest cost in the assignment.  It will be our
       upper bound for the binary search. */
    max_cost = INT_MIN;
    for(i = 0; i < problem->size; i++)
    {
        cost = problem->get_cost(problem, i, x[i]);
        if(cost > max_cost)
            max_cost = cost;
    }
    
    if(!arrow_util_binary_search(info->cost_list, info->cost_list_length,
                                max_cost, &high))
    {
        arrow_print_error("Could not find max_cost in cost_list");
        ret = ARROW_FAILURE;
        goto CLEANUP;
    }
    low = 0;
    
    while(low != high)
    {
        median = ((high - low) / 2) + low;
        delta = info->cost_list[median];
        
        length = lap(problem, delta, x, y, pi, d, pred, label, &heap);
        
        if(length <= max_length)
            high = median;
        else
            low = median + 1;
    }
    end_time = arrow_util_zeit();
    
    /* Return the cost we converged to as the answer */
    result->obj_value = info->cost_list[low];
    result->total_time = end_time - start_time;

CLEANUP:
    destruct_data(&x, &y, &pi, &d, &pred, &label, &heap);
    return ret;
}
コード例 #14
0
ファイル: timer.hpp プロジェクト: stephentu/community
 inline double
 lap_ms()
 {
   return lap() / 1000.0;
 }
コード例 #15
0
ファイル: timer.hpp プロジェクト: stephentu/community
 inline uint64_t
 lap_usec()
 {
   return lap();
 }
コード例 #16
0
ファイル: timer.hpp プロジェクト: stephentu/community
 timer(Mode m = T_CLK_GETTIMEOFDAY)
   : m_(m)
 {
   lap();
 }
コード例 #17
0
ファイル: laplace1b.cpp プロジェクト: kkholst/lava.nlin
RcppExport SEXP nsem3b(SEXP data,  
		      SEXP theta,
		      SEXP Sigma,
		      SEXP modelpar,
		    SEXP control
		    ) {   

  //  srand ( time(NULL) ); /* initialize random seed: */
  
  Rcpp::NumericVector Theta(theta);  
  Rcpp::NumericMatrix D(data);
  unsigned nobs = D.nrow(), k = D.ncol();
  mat Data(D.begin(), nobs, k, false); // Avoid copying
  Rcpp::NumericMatrix V(Sigma);  
  mat S(V.begin(), V.nrow(), V.ncol()); 
  S(0,0) = 1;
  mat iS = inv(S);
  double detS = det(S);
 

  Rcpp::List Modelpar(modelpar);
  // Rcpp::IntegerVector _nlatent = Modelpar["nlatent"]; unsigned nlatent = _nlatent[0];
  Rcpp::IntegerVector _ny0 = Modelpar["nvar0"]; unsigned ny0 = _ny0[0];
  Rcpp::IntegerVector _ny1 = Modelpar["nvar1"]; unsigned ny1 = _ny1[0];
  Rcpp::IntegerVector _ny2 = Modelpar["nvar2"]; unsigned ny2 = _ny2[0];
  Rcpp::IntegerVector _npred0 = Modelpar["npred0"]; unsigned npred0 = _npred0[0];
  Rcpp::IntegerVector _npred1 = Modelpar["npred1"]; unsigned npred1 = _npred1[0];
  Rcpp::IntegerVector _npred2 = Modelpar["npred2"]; unsigned npred2 = _npred2[0];
  Rcpp::List Control(control);   
  Rcpp::NumericVector _lambda = Control["lambda"]; double lambda = _lambda[0];
  Rcpp::NumericVector _niter = Control["niter"]; double niter = _niter[0];
  Rcpp::NumericVector _Dtol = Control["Dtol"]; double Dtol = _Dtol[0];


  rowvec mu0(ny0), lambda0(ny0);
  rowvec mu1(ny1), lambda1(ny1);
  rowvec mu2(ny2), lambda2(ny2);
  rowvec beta0(npred0); 
  rowvec beta1(npred1); 
  rowvec beta2(npred2);
  rowvec gamma(2);
  rowvec gamma2(2);  
  unsigned pos=0;
  for (unsigned i=0; i<ny0; i++) {
    mu0(i) = Theta[pos];
    pos++;
  }
  for (unsigned i=0; i<ny1; i++) {
    mu1(i) = Theta[pos];
    pos++;
  }
  for (unsigned i=0; i<ny2; i++) {
    mu2(i) = Theta[pos];
    pos++;
  }
  for (unsigned i=0; i<ny0; i++) {
    lambda0(i) = Theta[pos];
    pos++;
  }
  lambda1(0) = 1;
  for (unsigned i=1; i<ny1; i++) {
    lambda1(i) = Theta[pos];
    pos++;
  }
  lambda2(0) = 1;
  for (unsigned i=1; i<ny2; i++) {
    lambda2(i) = Theta[pos];
    pos++;
  }
  for (unsigned i=0; i<npred0; i++) {
    beta0(i) = Theta[pos];
    pos++;
  }
  for (unsigned i=0; i<npred1; i++) {
    beta1(i) = Theta[pos];
    pos++;
  }
  for (unsigned i=0; i<npred2; i++) {
    beta2(i) = Theta[pos];
    pos++;
  }
  gamma(0) = Theta[pos]; gamma(1) = Theta[pos+1];
  gamma2(0) = Theta[pos+2]; gamma2(1) = Theta[pos+3];

  // cerr << "mu0=" << mu0 << endl;
  // cerr << "mu1=" << mu1 << endl;
  // cerr << "mu2=" << mu2 << endl;
  // cerr << "lambda0=" << lambda0 << endl;
  // cerr << "lambda1=" << lambda1 << endl;
  // cerr << "lambda2=" << lambda2 << endl;
  // cerr << "beta0=" << beta0 << endl;
  // cerr << "beta1=" << beta1 << endl;
  // cerr << "beta2=" << beta2 << endl;
  // cerr << "gamma=" << gamma << endl;
  // cerr << "gamma2=" << gamma2 << endl;
  
  mat lap(nobs,4);
  for (unsigned i=0; i<nobs; i++) {
    rowvec newlap = laNRb(Data.row(i), iS, detS,
			  mu0, mu1, mu2, 
			  lambda0, lambda1, lambda2, 
			  beta0,beta1, beta2, gamma, gamma2,
			  Dtol,niter,lambda);
    lap.row(i) = newlap;
  }

  List  res;
  res["indiv"] = lap;
  res["logLik"] = sum(lap.col(0)) + (3-V.nrow())*log(2.0*datum::pi)*nobs/2;
  res["norm0"] = (3-V.nrow())*log(2*datum::pi)/2;
  return res;
}
コード例 #18
0
ファイル: main-fwi-enquist2d.cpp プロジェクト: conghui/swfwi
float cal_obj_derr_illum_grad(const FwiParams &params,
    float *derr,  /* output */
    float *illum, /* output */
    float *g1,    /* output */
    const float *wlt,
    const float *dobs,
    const EnquistAbc2d &fmMethod,
    const ShotPosition &allSrcPos,
    const ShotPosition &allGeoPos)
{
  int nt = params.nt;
  int nz = params.nz;
  int nx = params.nx;
  int ng = params.ng;
  int ns = params.ns;

  std::vector<float> bndr = fmMethod.initBndryVector(nt);
  std::vector<float> dcal(ng, 0); /* calculated/synthetic seismic data */

  std::vector<float> sp0(nz * nx); /* source wavefield p0 */
  std::vector<float> sp1(nz * nx); /* source wavefield p1 */
  std::vector<float> sp2(nz * nx); /* source wavefield p2 */
  std::vector<float> gp0(nz * nx); /* geophone/receiver wavefield p0 */
  std::vector<float> gp1(nz * nx); /* geophone/receiver wavefield p1 */
  std::vector<float> gp2(nz * nx); /* geophone/receiver wavefield p2 */
  std::vector<float> lap(nz * nx); /* laplace of the source wavefield */

  for (int is = 0; is < ns; is++) {
    std::fill(sp0.begin(), sp0.end(), 0);
    std::fill(sp1.begin(), sp1.end(), 0);

    ShotPosition curSrcPos = allSrcPos.clip(is);

    for (int it = 0; it < nt; it++) {
      fmMethod.addSource(&sp1[0], &wlt[it], curSrcPos);
      fmMethod.stepForward(&sp0[0], &sp1[0], &sp2[0]);

      // cycle swap
      cycleSwap(sp0, sp1, sp2);

      fmMethod.writeBndry(&bndr[0], &sp0[0], it);
      fmMethod.recordSeis(&dcal[0], &sp0[0], allGeoPos);

      cal_residuals(&dcal[0], &dobs[is * nt * ng + it * ng], &derr[is * ng * nt + it * ng], ng);
    }

    std::swap(sp0, sp1);

    std::fill(gp0.begin(), gp0.end(), 0);
    std::fill(gp1.begin(), gp1.end(), 0);

    for (int it = nt - 1; it > -1; it--) {
      /// backward propagate source wavefield
      fmMethod.readBndry(&bndr[0], &sp1[0], it);
      fmMethod.stepBackward(illum, &lap[0], &sp0[0], &sp1[0], &sp2[0]);
      fmMethod.subSource(&sp1[0], &wlt[it], curSrcPos);

      /// forward propagate geophone wavefield
      fmMethod.addSource(&gp1[0], &derr[is * ng * nt + it * ng], allGeoPos);
      fmMethod.stepForward(&gp0[0], &gp1[0], &gp2[0]);

      /// calculate gradient
      cal_gradient(&g1[0], &lap[0], &gp1[0], nz, nx);

      cycleSwap(sp0, sp1, sp2);
      cycleSwap(gp0, gp1, gp2);
    }

  } /// output: derr, g1, illum

  float obj = cal_objective(&derr[0], ng * nt * ns);

  return obj;
}