public Result estimate(ONDEParameter initial_params, double[] data){
		log.info("BF method estimation process started.");
		// initialization
		log.info("BF method initialization process started.");
		int N = data.length;
		double initial_alpha_bound[][] = new double[initial_params.initial_sigma_bound.length+initial_params.initial_lambda_bound.length-1][];
		for(int i=0;i<initial_alpha_bound.length;i++){
			initial_alpha_bound[i] = new double[2];
			for(int j=0;j<2;j++) initial_alpha_bound[i][j] = j;
		}
		double initial_omega_bound[][] = new double[initial_params.offset.length-1][];
		for(int i=0;i<initial_omega_bound.length;i++){
			initial_omega_bound[i] = new double[2];
			for(int j=0;j<2;j++) initial_omega_bound[i][j] = j;
		}
		double logLiklihood_pre = Double.NEGATIVE_INFINITY;
		Increment incre = new Increment(initial_params.D, initial_params.offset,initial_omega_bound,initial_alpha_bound, initial_params.initial_sigma_bound, initial_params.initial_lambda_bound);
		log.info("BF method initialization process finished.");
		boolean flag = true;
		do{
			incre.print();
			log.info("BF increment process started.");
			double maxlogLiklihood = Double.NEGATIVE_INFINITY;
			Increment next_incre = null;
			do{
				double logLiklihood = logLiklihood(incre.getCurrent(),data);
				if(logLiklihood > maxlogLiklihood){
					maxlogLiklihood = logLiklihood;
					next_incre = incre.getNewIncrement();
				}
			}
			while(incre.increment());
			// Stopping condition 
			if(Math.abs(maxlogLiklihood - logLiklihood_pre) < logLiklihood_threshold/N) flag = false;
			else{
				incre = next_incre;
			}
			logLiklihood_pre = maxlogLiklihood;
		}while(flag);
		Result res = new Result();
		res.param = incre.getCurrent();
		res.logLiklihood = logLiklihood_pre;
		log.info("BF method estimation process finished.");
		return res;
	}