void BackwardEulerIvpOdeSolver::CalculateNextYValue(AbstractOdeSystem* pAbstractOdeSystem,
                                                    double timeStep,
                                                    double time,
                                                    std::vector<double>& rCurrentYValues,
                                                    std::vector<double>& rNextYValues)
{
    // Check the size of the ODE system matches the solvers expected
    assert(mSizeOfOdeSystem == pAbstractOdeSystem->GetNumberOfStateVariables());

    unsigned counter = 0;
//        const double eps = 1e-6 * rCurrentGuess[0]; // Our tolerance (should use min(guess) perhaps?)
    const double eps = 1e-6; // JonW tolerance
    double norm = 2*eps;

    std::vector<double> current_guess(mSizeOfOdeSystem);
    current_guess.assign(rCurrentYValues.begin(), rCurrentYValues.end());

    while (norm > eps)
    {
        // Calculate Jacobian and mResidual for current guess
        ComputeResidual(pAbstractOdeSystem, timeStep, time, rCurrentYValues, current_guess);
        ComputeJacobian(pAbstractOdeSystem, timeStep, time, rCurrentYValues, current_guess);
//            // Update norm (our style)
//            norm = ComputeNorm(mResidual);

        // Solve Newton linear system
        SolveLinearSystem();

        // Update norm (JonW style)
        norm = ComputeNorm(mUpdate);

        // Update current guess
        for (unsigned i=0; i<mSizeOfOdeSystem; i++)
        {
            current_guess[i] -= mUpdate[i];
        }

        counter++;
        assert(counter < 20); // avoid infinite loops
    }
    rNextYValues.assign(current_guess.begin(), current_guess.end());
}
Beispiel #2
0
void crank_nicholson(double current_time, double time_step,
                     int    state_size,   double *state,
                     double *new_state,   struct sim_parms *parms,
                     tensor (*rhs)(double time, const tensor &state,
                                   struct sim_parms *parms))
{
    tensor prev_state(1,state_size);
    tensor last_guess(1,state_size);
    tensor current_guess(1,state_size);
    tensor temp(1,state_size);

    double delta;
    double time_step_2 = time_step/2.0;
    int i, counter;

    for( i = 0; i < state_size; i++ ) prev_state.Set(state[i],i);

    last_guess <= prev_state;
    current_guess <= prev_state;
    delta = 1e200;
    counter = 0;

    while( delta > CN_TOL && counter <= CN_MAX_ITERATES)
     {
       temp <= time_step_2*( rhs(current_time, prev_state, parms) +
                             rhs(current_time + time_step, last_guess, parms));
       current_guess <= prev_state + temp;
       temp <= current_guess - last_guess;
       delta = temp.max();
       last_guess <= current_guess;
       counter++;
     }

    for( i = 0; i < state_size; i++ )
      new_state[i] =  current_guess.Val(i);

}
FusionResults RegistrationRandom::getTransform(Eigen::MatrixXd guess) {

    unsigned int s_nr_data = src->data.cols();//std::min(int(src->data.cols()),int(500000));
    unsigned int d_nr_data = dst->data.cols();
    refinement->allow_regularization = true;
    //printf("s_nr_data: %i d_nr_data: %i\n",s_nr_data,d_nr_data);

    int stepy = std::max(1,int(d_nr_data)/100000);

    Eigen::Matrix<double, 3, Eigen::Dynamic> Y;
    Eigen::Matrix<double, 3, Eigen::Dynamic> N;
    Y.resize(Eigen::NoChange,d_nr_data/stepy);
    N.resize(Eigen::NoChange,d_nr_data/stepy);
    unsigned int ycols = Y.cols();

    for(unsigned int i = 0; i < d_nr_data/stepy; i++) {
        Y(0,i)	= dst->data(0,i*stepy);
        Y(1,i)	= dst->data(1,i*stepy);
        Y(2,i)	= dst->data(2,i*stepy);
        N(0,i)	= dst->normals(0,i*stepy);
        N(1,i)	= dst->normals(1,i*stepy);
        N(2,i)	= dst->normals(2,i*stepy);
    }

    /// Build kd-tree
    //nanoflann::KDTreeAdaptor<Eigen::Matrix3Xd, 3, nanoflann::metric_L2_Simple>                  kdtree(Y);

    Eigen::VectorXd DST_INORMATION = Eigen::VectorXd::Zero(Y.cols());
    for(unsigned int i = 0; i < d_nr_data/stepy; i++) {
        DST_INORMATION(i) = dst->information(0,i*stepy);
    }

    double s_mean_x = 0;
    double s_mean_y = 0;
    double s_mean_z = 0;
    for(unsigned int i = 0; i < s_nr_data; i++) {
        s_mean_x += src->data(0,i);
        s_mean_y += src->data(1,i);
        s_mean_z += src->data(2,i);
    }
    s_mean_x /= double(s_nr_data);
    s_mean_y /= double(s_nr_data);
    s_mean_z /= double(s_nr_data);

    double d_mean_x = 0;
    double d_mean_y = 0;
    double d_mean_z = 0;
    for(unsigned int i = 0; i < d_nr_data; i++) {
        d_mean_x += dst->data(0,i);
        d_mean_y += dst->data(1,i);
        d_mean_z += dst->data(2,i);
    }
    d_mean_x /= double(d_nr_data);
    d_mean_y /= double(d_nr_data);
    d_mean_z /= double(d_nr_data);

    double stop		= 0.00001;

    Eigen::Affine3d Ymean = Eigen::Affine3d::Identity();
    Ymean(0,3) = d_mean_x;
    Ymean(1,3) = d_mean_y;
    Ymean(2,3) = d_mean_z;

    Eigen::Affine3d Xmean = Eigen::Affine3d::Identity();
    Xmean(0,3) = s_mean_x;
    Xmean(1,3) = s_mean_y;
    Xmean(2,3) = s_mean_z;

    std::vector< Eigen::Matrix<double, 3, Eigen::Dynamic> > all_X;
    std::vector< Eigen::Affine3d > all_res;
    std::vector< int > count_X;
    std::vector< float > score_X;
    std::vector< std::vector< Eigen::VectorXd > > all_starts;
    int stepxsmall = std::max(1,int(s_nr_data)/250);
    Eigen::VectorXd Wsmall (s_nr_data/stepxsmall);
    for(unsigned int i = 0; i < s_nr_data/stepxsmall; i++) {
        Wsmall(i) = src->information(0,i*stepxsmall);
    }


    double sumtime = 0;
    double sumtimeSum = 0;
    double sumtimeOK = 0;
    int r = 0;

    refinement->viewer = viewer;
    refinement->visualizationLvl = 0;
    //for(int r = 0; r < 1000; r++){
//	while(true){
//		double rx = 2.0*M_PI*0.0001*double(rand()%10000);
//		double ry = 2.0*M_PI*0.0001*double(rand()%10000);
//		double rz = 2.0*M_PI*0.0001*double(rand()%10000);
    //double stop = 0;
    double step = 0.1+2.0*M_PI/5;
    for(double rx = 0; rx < 2.0*M_PI; rx += step) {
        for(double ry = 0; ry < 2.0*M_PI; ry += step)
            for(double rz = 0; rz < 2.0*M_PI; rz += step) {
                printf("rx: %f ry: %f rz: %f\n",rx,ry,rz);

                double start = getTime();

                double meantime = 999999999999;
                if(r != 0) {
                    meantime = sumtimeSum/double(sumtimeOK+1.0);
                }
                refinement->maxtime = std::min(0.5,3*meantime);

                Eigen::VectorXd startparam = Eigen::VectorXd(3);
                startparam(0) = rx;
                startparam(1) = ry;
                startparam(2) = rz;

                Eigen::Affine3d randomrot = Eigen::Affine3d::Identity();

                randomrot =	Eigen::AngleAxisd(rx, Eigen::Vector3d::UnitX()) *
                            Eigen::AngleAxisd(ry, Eigen::Vector3d::UnitY()) *
                            Eigen::AngleAxisd(rz, Eigen::Vector3d::UnitZ());

                Eigen::Affine3d current_guess = Ymean*randomrot*Xmean.inverse();//*Ymean;
                refinement->target_points = 250;
                FusionResults fr = refinement->getTransform(current_guess.matrix());
//fr.timeout = timestopped;
                double stoptime = getTime();
                sumtime += stoptime-start;

                if(!fr.timeout) {
                    sumtimeSum += stoptime-start;
                    sumtimeOK++;
                }

                //printf("sumtime: %f\n",sumtime);
                stop = fr.score;
                Eigen::Matrix4d m = fr.guess;
                current_guess = m;//fr.guess;
                float m00 = current_guess(0,0);
                float m01 = current_guess(0,1);
                float m02 = current_guess(0,2);
                float m03 = current_guess(0,3);
                float m10 = current_guess(1,0);
                float m11 = current_guess(1,1);
                float m12 = current_guess(1,2);
                float m13 = current_guess(1,3);
                float m20 = current_guess(2,0);
                float m21 = current_guess(2,1);
                float m22 = current_guess(2,2);
                float m23 = current_guess(2,3);

                Eigen::Matrix<double, 3, Eigen::Dynamic> Xsmall;
                Xsmall.resize(Eigen::NoChange,s_nr_data/stepxsmall);
                for(unsigned int i = 0; i < s_nr_data/stepxsmall; i++) {
                    float x		= src->data(0,i*stepxsmall);
                    float y		= src->data(1,i*stepxsmall);
                    float z		= src->data(2,i*stepxsmall);
                    Xsmall(0,i)	= m00*x + m01*y + m02*z + m03;
                    Xsmall(1,i)	= m10*x + m11*y + m12*z + m13;
                    Xsmall(2,i)	= m20*x + m21*y + m22*z + m23;
                }

                bool exists = false;
                for(unsigned int ax = 0; ax < all_X.size(); ax++) {
                    Eigen::Matrix<double, 3, Eigen::Dynamic> axX = all_X[ax];
                    Eigen::Affine3d axT = all_res[ax];
                    double diff = (Xsmall-axX).colwise().norm().mean();
                    if(diff < 20*stop) {
                        count_X[ax]++;
                        all_starts[ax].push_back(startparam);
                        int count = count_X[ax];
                        float score = score_X[ax];
                        std::vector< Eigen::VectorXd > starts = all_starts[ax];
                        for(int bx = ax-1; bx >= 0; bx--) {
                            if(count_X[bx] < count_X[bx+1]) {
                                count_X[bx+1]		= count_X[bx];
                                score_X[bx+1]		= score_X[bx];
                                all_X[bx+1]			= all_X[bx];
                                all_starts[bx+1]	= all_starts[bx];
                                all_res[bx+1]		= all_res[bx];


                                all_X[bx] = axX;
                                count_X[bx] = count;
                                score_X[bx] = score;
                                all_starts[bx] = starts;
                                all_res[bx] = axT;
                            } else {
                                break;
                            }
                        }
                        exists = true;
                        break;
                    }
                }



                if(!exists) {
                    all_X.push_back(Xsmall);
                    count_X.push_back(1);
                    score_X.push_back(stop);
                    all_starts.push_back(std::vector< Eigen::VectorXd >());
                    all_starts.back().push_back(startparam);
                    all_res.push_back(current_guess);
                }
                r++;
            }
    }


    FusionResults fr = FusionResults();
    refinement->allow_regularization = false;

    int tpbef = refinement->target_points;
    refinement->target_points = 2000;
    for(unsigned int ax = 0; ax < all_X.size(); ax++) {
        Eigen::Matrix4d np = all_res[ax].matrix();
        refinement->visualizationLvl = visualizationLvl;
        if(ax < 25) {
            double start = getTime();
            FusionResults fr1 = refinement->getTransform(np);
            double stop = getTime();
            np = fr1.guess;
        }
        refinement->visualizationLvl = 0;
        fr.candidates.push_back(np);
        fr.counts.push_back(count_X[ax]);
        fr.scores.push_back(1.0/score_X[ax]);
    }
    refinement->target_points = tpbef;
    return fr;
}