Example #1
0
void mergePartition(std::vector<int>& V, int start, int mid, int end){
    int itr1 = start;
    int itr2 = mid+1;
    int itr3 = 0;

    std::vector<int> Vout(end-start+1);
    while( itr1 <= mid && itr2 <= end){
        if(V[itr1] <= V[itr2]){
            Vout[itr3++] = V[itr1++];
        }else{
            Vout[itr3++] = V[itr2++];
        }
    }
    if(itr1 > mid){
        for(int i=itr2; i <= end; ++i)
            Vout[itr3++] = V[i];
    } else {
        for(int i=itr1; i <= mid; ++i)
            Vout[itr3++] = V[i];
    }

    std::copy(Vout.begin(), Vout.end(), V.begin()+start);
}
Example #2
0
//' @title Master Wrapper for the GMWM Estimator
//' @description This function generates WV, GMWM Estimator, and an initial test estimate.
//' @param data A \code{vec} containing the data.
//' @param theta A \code{vec} with dimensions N x 1 that contains user-supplied initial values for parameters
//' @param desc A \code{vector<string>} indicating the models that should be considered.
//' @param objdesc A \code{field<vec>} containing a list of parameters (e.g. AR(1) = c(1,1), ARMA(p,q) = c(p,q,1))
//' @param model_type A \code{string} that represents the model transformation
//' @param starting A \code{bool} that indicates whether the supplied values are guessed (T) or are user-based (F).
//' @param alpha A \code{double} that handles the alpha level of the confidence interval (1-alpha)*100
//' @param compute_v A \code{string} that describes what kind of covariance matrix should be computed.
//' @param K An \code{int} that controls how many times theta is updated.
//' @param H An \code{int} that controls how many bootstrap replications are done.
//' @param G An \code{int} that controls how many guesses at different parameters are made.
//' @param robust A \code{bool} that indicates whether the estimation should be robust or not.
//' @param eff A \code{double} that specifies the amount of efficiency required by the robust estimator.
//' @return A \code{field<mat>} that contains a list of ever-changing estimates...
//' @author JJB
//' @references Wavelet variance based estimation for composite stochastic processes, S. Guerrier and Robust Inference for Time Series Models: a Wavelet-Based Framework, S. Guerrier
//' @keywords internal
//' @export
//' @backref src/gmwm_logic.cpp
//' @backref src/gmwm_logic.h
// [[Rcpp::export]]
arma::field<arma::mat> gmwm_master_cpp(arma::vec& data, 
                                      arma::vec theta,
                                      const std::vector<std::string>& desc, const arma::field<arma::vec>& objdesc, 
                                      std::string model_type, bool starting,
                                      double alpha, 
                                      std::string compute_v, unsigned int K, unsigned int H,
                                      unsigned int G, 
                                      bool robust, double eff){
  
  // Obtain counts of the different models we need to work with
  std::map<std::string, int> models = count_models(desc);
  
  // HACK METHOD (todo: formalize it)
  // Determine if we need to difference
  if(models["SARIMA"] > 0){
    
    // Note: s, i, si are 6,7,8 => 5,6,7
    for(unsigned int i = 0; i < desc.size(); i ++){
      if(objdesc(i).n_elem > 3){
        arma::vec sarima_desc = objdesc(i);
        // Do we need to difference? 
        if(sarima_desc(6) > 0 || sarima_desc(7) > 0){
          // Perform differencing in specific order...
          // First non-seasonal and then seasonal.
          
          if(sarima_desc(6) > 0){
            // Lag is always 1, number of differences is (i)
            data = diff_cpp(data, 1, sarima_desc(6));
          }
          
          if(sarima_desc(7) > 0){
            // Lag is always seasonality (s) and differences is (si).
            data = diff_cpp(data, sarima_desc(5), sarima_desc(7));
          }
          
          // Kill loop. We only handle the tsmodel object with the first difference.
          break;
        }
      }
    }
  }
  
  // ------ Variable Declarations
  
  // Length of the Time Series
  unsigned int N = data.n_elem;
  
  // Number of Scales (J)
  unsigned int nlevels = floor(log2(N));
  
  // Number of parameters
  unsigned int np = theta.n_elem;
  
  // Take the mean of the first difference
  double expect_diff = mean_diff(data);
  
  // Guessed values of Theta (user supplied or generated)
  arma::vec guessed_theta = theta;
  
  // MODWT decomp
  arma::field<arma::vec> modwt_decomp = modwt_cpp(data, "haar", nlevels, "periodic", true);
  
  // Obtain WV and confidence intervals
  arma::mat wvar = wvar_cpp(modwt_decomp, robust, eff, alpha, "eta3");
  
  // Extract
  arma::vec wv_empir = wvar.col(0);
  arma::vec ci_lo = wvar.col(1);
  arma::vec ci_hi = wvar.col(2);
  
  //-------------------------
  // Obtain Covariance Matrix
  //-------------------------
  
  arma::mat V;
  
  // compute_cov_cpp is the hard core function. It can only be improved by using parallelization.
  if(compute_v == "diag" || compute_v == "full"){
    arma::field<arma::mat> Vout = compute_cov_cpp(modwt_decomp, nlevels, compute_v, robust, eff);
    if(robust){
      V = Vout(1);
    }else{
      V = Vout(0);
    }
  }else{
     V = fast_cov_cpp(wvar.col(2), wvar.col(1));
  }

  // Obtain the Omega matrix
  arma::mat omega = arma::inv(diagmat(V));
  
  // Store the original V matrix (in case of bootstrapping) for use in the update function
  arma::mat orgV = V;
  
  // Calculate the values of the Scales 
  arma::vec scales = scales_cpp(nlevels);
  
  // Min-Max / N
  double ranged = dr_slope(data);
  
  // Guess starting values for the theta parameters
  if(starting){
    
    // Always run guessing algorithm
    theta = guess_initial(desc, objdesc, model_type, np, expect_diff, N, wvar, scales, ranged, G);
    
    // If under ARMA case and only ARMA is in the model, 
    // then see how well these values are.
    if(desc.size() == 1 && (desc[0] == "SARIMA" || desc[0] == "ARMA11") && N <= 1000){
      
      // Use R's ARIMA function to estimate parameter space
      arma::vec theta2 = Rcpp_ARIMA(data, objdesc(0)); // Only 1 objdesc in the available.
      
      // Obtain the obj function under omega with these initial guesses
      // DO >>NOT<< USE Yannick's to optimize starting values!!!!
      double mle_css_obj = getObjFun(theta2, desc, objdesc,  model_type, omega, wv_empir, scales); 
      
      // Obtain the objective function under Yannick's starting algorithm
      double init_guess_obj = getObjFunStarting(theta, desc, objdesc,  model_type, wv_empir, scales);
      
      // What performs better? 
      if(mle_css_obj < init_guess_obj){
        // Disable starting value optimization if using MLE. 
        theta = theta2;
        starting = false;
      }

    }
    
    guessed_theta = theta;
  }
  
  // Obtain the GMWM estimator's estimates.
  theta = gmwm_engine(theta, desc, objdesc, model_type, 
                      wv_empir, omega, scales, starting);
  
  // Optim may return a very small value. In this case, instead of saying its zero (yielding a transform issue), make it EPSILON.
  theta = code_zero(theta);
  
  // Enable bootstrapping
  if(compute_v == "bootstrap"){
    for(unsigned int k = 0; k < K; k++){
        // Create the full V matrix
        V = cov_bootstrapper(theta, desc, objdesc, N, robust, eff, H, false);
      
        // Update the omega matrix
        omega = arma::inv(diagmat(V));
        
        // The theta update in this case MUST not use Yannick's starting algorithm. Hence, the false value.
        theta = gmwm_engine(theta, desc, objdesc, model_type, wv_empir, omega, scales, false);
        
        // Optim may return a very small value. In this case, instead of saying its zero (yielding a transform issue), make it EPSILON.
        theta = code_zero(theta);
    }
  }

  
  if(desc[0] == "SARIMA" && desc.size() == 1){
    
    arma::vec temp = objdesc(0);
    unsigned int p = temp(0);
    if(p != 0 && invert_check(arma::join_cols(arma::ones<arma::vec>(1), -theta.rows(0, p - 1))) == false){
      Rcpp::Rcout << "WARNING: This ARMA model contains AR coefficients that are NON-STATIONARY!" << std::endl;
    }
  } 
  
  // Order AR1s / GM so largest phi is first!
   if(models["AR1"] > 1 || models["GM"] > 1){
     theta = order_AR1s(theta, desc, objdesc);
   }

  // Obtain the objective value function
  arma::vec obj_value(1);
  obj_value(0) = getObjFun(theta, desc, objdesc,  model_type, omega, wv_empir, scales); 
  
  arma::vec dr_s(1);
  dr_s(0) = ranged;
  
  // Decomposition of the WV.
  arma::mat decomp_theo = decomp_theoretical_wv(theta, desc, objdesc, scales);
  arma::vec theo = decomp_to_theo_wv(decomp_theo);

  // Export information back
  arma::field<arma::mat> out(13);
  out(0) = theta;
  out(1) = guessed_theta;
  out(2) = wv_empir;
  out(3) = ci_lo;
  out(4) = ci_hi;
  out(5) = V;
  out(6) = orgV;
  out(7) = expect_diff;
  out(8) = theo;
  out(9) = decomp_theo;
  out(10) = obj_value;
  out(11) = omega;
  out(12) = dr_s;
  return out;
}
Example #3
0
int main()
{
	char powerfile[]="Power.txt";
	GetPower(powerfile);
	/*
	 * 声明核中的变量
	 */
	std::vector<double> Vcore;
	std::vector<double> Rcore;
	//std::vector<double> ecore;//核的热容中的电流源部分
	//std::vector<double> rcore;//核的热容中的热阻部分
	//std::vector<double> Ipoint;

	/*
	 * 声明基底中的变量
	 */
	double Vbase(Tamb);
	double Ibase;
	double Rbase((r_conduct+r_fan)/A);//初始化基底的热阻,/@param A表示从密度换算
	double ebase(0);
	double rbase(h/(2*(c_conduct*A)));//初始化基底的热容中的热阻部分=@param h/2@param c,*@param A表示从密度换算

	/*
	 * 初始化基底中的@param Vbase和@param ebase
	 */
	for(int i=0;i<CoreNumber;i++)
	{
		Rcore.push_back(r_bulk/Acore.at(i));//初始化核中的热阻,/@param Acore表示从密度换算
	}

	/*
	 * 初始化核中的@param Vcore和@param ecore
	 */
	for(int i=0;i<CoreNumber;i++)
	{
		Vcore.push_back(Tamb);
		//rcore.push_back(h/(2*(c_bulk*Acore.at(i))));//初始化@param rcore=@param h/2@param c,*@param Acore表示从密度换算
		//ecore.push_back(0);
	}

	/*
	 * 二级等效电路中,计算热阻和热容热阻部分的等效值
	 */
	std::vector<double> r;
	for(int i=0;i<CoreNumber;i++)
	{
		r.push_back(Rcore.at(i));//计算等效值
	}
	double rtmp=r.at(0);//用来计算@param Vbase的临时变量,是所有@param rcore的并联值
	double Itmp(0);
	/*
	 * 计算@param Vbase时用到的热阻并联和
	 */
	for(int i=0;i<CoreNumber-1;i++)
	{
		rtmp=Pararlle(rtmp,r.at(i+1));//计算并联值
	}
	rtmp=Pararlle(rtmp,Pararlle(Rbase,rbase));//与@param Rbase并联


	/*
	 * @brief 打开输出文件,并相应的打印表头
	 * 主要的输出内容:@param Vore、@param Pcore、@param Vbase、@param compareVbase
	 */
	std::ofstream Vout("Vcore.txt");
	std::ofstream Pout("Pcore.txt");
	std::ofstream Bout("Base.txt");
	if(not Vout)
		std::perror("Vcore.txt");
	if(not Bout)
		std::perror("Pcore.txt");
	if(not Pout)
		std::perror("Base.txt");

	Vout.precision(SetPrecision);
	Bout.precision(SetPrecision);
	Pout.precision(SetPrecision);

	for(int i=0;i<CoreNumber;i++)
		Pout<<std::setw(SetWidth)<<std::right<<"Pcore("<<i+1<<")";
	Pout<<"\n";

	for(int i=0;i<CoreNumber;i++)
		Vout<<std::setw(SetWidth)<<std::right<<"Vcore("<<i+1<<")";
	Vout<<std::endl;

	Bout<<std::setw(SetWidth)<<"R(bc)Cb="<<Pararlle(Rbase,Rcore[0])*c_conduct<<"\n";
	Bout<<std::setw(SetWidth)<<"VBase";
	Bout<<std::setw(SetWidth)<<"Charge"<<"\n";


	std::vector<double> Vref;
	std::vector<double> newPower;
	for(int i=0;i<CoreNumber;i++)
	{
		Vref.push_back(Vcore.at(i));
		newPower.push_back(CorePower.at(i));
	}
	double eps(1);
	double compareVbase(0);

	do
	{
		for(std::vector<double>::iterator i=Vcore.begin();i!=Vcore.end();i++)
			Vout<<std::setw(SetWidth)<<*i+amb<<"\t";
		Vout<<std::endl;

		for(std::vector<double>::iterator i=newPower.begin();i!=newPower.end();i++)
			Pout<<std::setw(SetWidth)<<*i;
		Pout<<"\n";

		Bout<<std::setw(SetWidth)<<Vbase;
		Bout<<std::setw(SetWidth)<<compareVbase<<"\n";

		for(int i=0;i<CoreNumber;i++)
		{
			Vref.at(i)=Vcore.at(i);
		}
		/*
		* 刷新@param Vbase以及@param ebase
		*/
		Itmp=0;//用来计算@param Vbase的临时变量,是所有核内电流的和
		for(int j=0;j<CoreNumber;j++)
		{
			newPower.at(j)=CorePower.at(j)+LeakagePower(Vcore.at(j));//刷新实际的功耗值(密度)=源功耗+漏电流功耗
			//Ipoint.at(j)=(newPower.at(j)*rcore.at(j)/r.at(j));
			Itmp+=newPower.at(j);//计算@param Itmp,需要每次刷新
		}

		Itmp+=ebase;

		/*
		* 刷新@param Vcore,@param Vbase的值
		*/
		Vbase=rtmp*Itmp;

		double SumNewPower=0;//计算所有核的实际功耗总值,用以计算稳定@param Vcore以及充电曲线中的@param Vbase
		for(int i=0;i<CoreNumber;i++)
		{
			SumNewPower+=newPower.at(i);
		}
		compareVbase=ChargeLine(SumNewPower,Rbase,c_conduct*A,IterNumber++);//注意:@param Cbase=@param c_conduct*@param A
		for(int i=0;i<CoreNumber;i++)
		{
			Vcore.at(i)=Vbase+newPower.at(i)*Rcore.at(i);
		}

		/*
		* 刷新@param Ibase,@param ebase的值
		*/
		Ibase=0;
		for(int i=0;i<CoreNumber;i++)
		{
			Ibase+=(Vcore.at(i)-Vbase)/Rcore.at(i);
		}
		Ibase+=-Vbase/Rbase;
		ebase=Vbase/rbase+Ibase;//计算@param ebase,需要每次刷新

		/*
		 * 根据@param eps(@param Icore的前后迭代差)判断迭代的收敛情况
		 */
		eps=0;
		for(int i=0;i<CoreNumber;i++)
		{
			Vref.at(i)=std::fabs(Vref.at(i)-Vcore.at(i));
			eps=std::max(Vref.at(i),eps);
		}

	}while(std::fabs(eps)>0.000001);

	std::vector<double> Vstable=StableVcore(newPower,Rcore,Rbase);//@param Vstable看作是理论稳定温度 注意:计算中用的是新的稳定后的功耗向量
	char charVstable[]="Vstable";
	DisplayVector(Vstable,charVstable);//输出稳定温度值用来对比而已(打开Vstable.txt)

	Vout.close();
	Bout.close();
	Pout.close();
	return 0;

}