Beispiel #1
0
//Mixed boundary problem
double structureM(double x, double y, int n)
{
    return 	structure1(x,y,n)-omega(x,y)*omega2(x,y)/(omega(x,y)+omega2(x,y))*
            ((omega2(x+diff_step,y)-omega2(x-diff_step,y))*(structure1(x+diff_step,y,n)-structure1(x-diff_step,y,n))
             +(omega2(x,y+diff_step)-omega2(x,y-diff_step))*(structure1(x,y+diff_step,n)-structure1(x,y-diff_step,n)))*
            glob_delta*glob_delta*0.25;
}
Beispiel #2
0
// [[Rcpp::interfaces(cpp)]]
double pr(int choice,int m,int chg,double add0,double add1,double* mGam,double* mOm1,double* mOm2,int* mRnew,int* mR,int mg){
arma::icolvec R(mR,mg,false);
arma::icolvec Rnew(mRnew,mg,false);
arma::colvec gamma(mGam,m,false);
arma::colvec omega1(mOm1,m,false);
arma::colvec omega2(mOm2,m,false);

double out=0;
double add=((R[chg+choice]==0)?add0:add1);
double addnew=((Rnew[chg+choice]==0)?add0:add1);
	if(choice==0){
		out=out+pRedge(gamma[choice],omega2[choice],Rnew[chg+choice],Rnew[chg+choice+1],addnew);
		out=out-pRedge(gamma[choice],omega2[choice],R[chg+choice],R[chg+choice+1],add);
	}
	if(choice==(m-1)){
		out=out+pRedge(gamma[choice],omega1[choice],Rnew[chg+choice],Rnew[chg+choice-1],addnew);
		out=out-pRedge(gamma[choice],omega1[choice],R[chg+choice],R[chg+choice-1],add);
	}
	if(choice>0 && choice<(m-1)){
		out=out+pRmiddle(gamma[choice],omega1[choice],omega2[choice],Rnew[chg+choice],Rnew[chg+choice-1],Rnew[chg+choice+1],addnew);
		out=out-pRmiddle(gamma[choice],omega1[choice],omega2[choice],R[chg+choice],R[chg+choice-1],R[chg+choice+1],add);
	}
return out;
}
void FBBaseFunction< Dimension, Scalar >::compute(
			const Vector& x, const Vector& y, Vector& fb,
			Matrix& dFb_dx, Matrix& dFb_dy )
{
	const unsigned d = x.rows() ;

	// see [Daviet et al 2011], Appendix A.1

	Vector z2(d) ;

	z2[0] = x.squaredNorm() + y.squaredNorm() ;
	Traits::tp( z2 ) = x[0] * Traits::tp( x ) + y[0] * Traits::tp( y ) ;
	const Scalar nz2t = Traits::tp( z2 ).norm() ;

	Vector omega1(d), omega2(d) ;
	omega1[0] = omega2[0] = .5 ;

	if( NumTraits< Scalar >::isZero( nz2t ) )
	{
		Traits::tp( omega1 ).setZero() ;
		omega1[1] = -.5 ;
		Traits::tp( omega2 ).setZero() ;
		omega2[1] =  .5 ;
	} else {
		Traits::tp( omega1 ) = -.5* Traits::tp( z2 ) / nz2t ;
		Traits::tp( omega2 ) =  .5* Traits::tp( z2 ) / nz2t ;
	}

	const Scalar rlambda1 = std::sqrt( std::max( (Scalar) 0, z2[0] - 2*nz2t ) ) ;
	const Scalar rlambda2 = std::sqrt( z2[0] + 2*nz2t ) ;

	const Vector z = rlambda1 * omega1 + rlambda2 * omega2 ;
	fb = x + y - z ;

	if( JacobianAsWell )
	{
		const Matrix Id( Matrix::Identity( d, d ) ) ;

		if( NumTraits< Scalar >::isZero( rlambda2 ) )
		{
			// x = y = 0
			dFb_dx.setZero( d,d ) ;
			dFb_dy.setZero( d,d ) ;
		} else {
			if( NumTraits< Scalar >::isZero( rlambda1 ) )
			{
				const Scalar izn = 1. / ( x[0]*x[0] + y[0]*y[0] ) ;
				dFb_dx = ( 1. - x[0]*izn ) * Id ;
				dFb_dy = ( 1. - y[0]*izn ) * Id ;
			} else {
				const Scalar det = rlambda1 * rlambda2 ;

				Matrix L, invLz(d,d) ;

				invLz(0, 0) = z[0] ;
				Traits::ntb( invLz ) = -Traits::tp( z ).transpose() ;
				Traits::tnb( invLz ) = -Traits::tp( z ) ;
				Traits::ttb( invLz ) =
					( det * Traits::TgMatrix::Identity( d-1, d-1 ) +
					  Traits::tp( z ) * Traits::tp( z ).transpose() ) / z[0] ;
				invLz /= det ;

				L = x[0] * Id ;
				Traits::ntb( L ) = Traits::tp( x ).transpose() ;
				Traits::tnb( L ) = Traits::tp( x ) ;
				dFb_dx.setIdentity( d,d ) ;
				dFb_dx.noalias() -= invLz * L ;

				L = y[0] * Id ;
				Traits::ntb( L ) = Traits::tp( y ).transpose() ;
				Traits::tnb( L ) = Traits::tp( y ) ;
				dFb_dy.setIdentity( d,d ) ;
				dFb_dy.noalias() -= invLz * L ;

			}
		}

	}

}
  // 2. 四次方程中所调用的三次方程
  double  cubic_equation(double a3,double b3,double c3,double d3)
  {
    double p,q,delta;
    double M,N;
    double y0;

    complex<double> temp1,temp2;
    complex<double> x1,x2,x3;
    complex<double> y1,y2;

    if(a3==0)
    {
      quadratic_equation(b3,c3,d3,y1,y2);

      x1 = y1;
      x2 = y2;
      x3 = 0;
    } else {
      p = -1.0/3*pow((b3*1.0/a3),2.0)+c3*1.0/a3;
      q = 2.0/27*pow((b3*1.0/a3),3.0)-1.0/3*b3*c3/(a3*a3)+d3*1.0/a3;

      // p = -1/3*(b3/a3)^2+c3/a3;
      // q = 2/27*(b3/a3)^3-1/3*b3*c3/(a3*a3)+d3/a3;
      //化成 y^3+p*y+q=0 形式;

      delta = pow((q/2.0),2.0)+pow((p/3.0),3.0);

      //判别式 delta = (q/2)^2+(p/3)^3;

      //cout<<" delta>0, 有一个实根和两个复根;delta=0,有三个实根;delta<0,有三个不等的实根"<<endl; 
      //cout<<" delta = " << delta << endl;
      //cout="">& lt;<" please output the discriminant  delta="<<& lt;endl; delta="">0,有一个实根和两个复根;  
      //delta=0,有三个实根;
      ////delta<0,有三个不等的实根。

      complex<double>  omega1(-1.0/2, sqrt(3.0)/2.0);
      complex<double>  omega2(-1.0/2, -sqrt(3.0)/2.0);

      complex<double>  yy(b3/(3.0*a3),0.0);

      M = -q/2.0;

      if(delta<0)
      {
        N = sqrt(fabs(delta));
        complex<double>  s1(M,N);
        complex<double>  s2(M,-N);

        x1 = (pow(s1,(1.0/3))+pow(s2,(1.0/3)))-yy;
        x2 = (pow(s1,(1.0/3))*omega1+pow(s2,(1.0/3))*omega2)-yy;
        x3 = (pow(s1,(1.0/3))*omega2+pow(s2,(1.0/3))*omega1)-yy;
      } else {
        N = sqrt(delta);

        complex<double>  f1(M+N,0);
        complex<double>  f2(M-N,0);

        if(M+N >= 0)
          temp1 = pow((f1),1.0/3);
        else
          temp1 = -norm(pow(sqrt(f1),1.0/3));

        if(M-N >= 0)
          temp2 = pow((f2),1.0/3);
        else
          temp2 = -norm(pow(sqrt(f2),1.0/3));

        x1 = temp1+temp2-yy;
        x2 = omega1*temp1+omega2*temp2-yy;
        x3 = omega2*temp1+omega1*temp2-yy;
      }

    }

    y0 = real(x1);
    return y0;
    //y0 为所调用的三次方程的返回值;
  }