Пример #1
0
/* finds the desired result, given y, the primes to be killed, the denominators,
   the full set of initial primes, and the density of relative primes */
extern BigNum find_M(BigNum * guess, BigNum * y, struct BIGNUM_ARRAY_TYPE left_to_kill,
		     struct BIGNUM_ARRAY_TYPE denom, struct BIGNUM_ARRAY_TYPE initial_primes,
		     BigRat *magic)
{
  BigNum temp, temp2, current_mu;

#if 0
  Mu(&current_mu, guess, left_to_kill, denom); 
  temp = y - current_mu;
  temp2 = b_abs(temp);

  while (b_cmp(temp2, LINEAR_SEARCH_LIMIT) > 0) {
    temp2 = guess_mu_inverse(&temp, magic);
    (*guess) = (*guess) + temp2;

    Mu(&current_mu, guess, left_to_kill, denom);

    temp = y - current_mu;
    temp2 = b_abs(temp);
  }

  temp = b_clear();
  temp2 = b_clear();

#else

  *guess = "11";
  current_mu = "1";
#endif
  return(linear_find(y, &current_mu, guess, initial_primes));
} 
Пример #2
0
yarp::sig::Matrix idynChainGetMoments_usingKDL(iCub::iDyn::iDynChain & idynChain,yarp::sig::Vector & ddp0)
{
    KDL::Wrenches f_i;
    int nj = idynChain.getN();

    yarp::sig::Vector mu(3),f(3);
    yarp::sig::Matrix Mu(3,nj);
    
    Mu.zero();
    
    f_i =  idynChainGet_usingKDL_aux(idynChain,ddp0);
    //Debug
    /*
    std::cout << "f_i without sensor " << std::endl;
    for(int p=0;p<f_i.size();p++)
    {
        std::cout << f_i[p] << std::endl;
    }
    */
    
    for(int i=0; i < nj; i++ ) {
      if( i != nj -1 ) {  
        to_iDyn(f_i[i+1].force,f);
        f = (idynChain[i+1]).getR()*f;
        to_iDyn(f_i[i+1].torque,mu);
        yarp::sig::Vector r_n = ((idynChain)[i+1]).getH().subcol(0,3,3);
        mu = ((idynChain)[i+1]).getR()*mu+cross(r_n,f);
      } else {
        mu.zero();
      }
      Mu.setCol(i,mu);
    }
    return Mu;
}
Пример #3
0
/* Efficient caluculation of mu */
extern void Mu(BigNum * result, BigNum * x, struct BIGNUM_ARRAY_TYPE left_to_kill, struct BIGNUM_ARRAY_TYPE the_final_denom)
{
  BigNum subout, first, second;
  struct BIGNUM_ARRAY_TYPE new_kill;

  if (left_to_kill.size <= 0) {
    mu_eval(result, x, the_final_denom);
  }
  else {
    subout = (*x) / left_to_kill.list[0];
    new_kill.size = left_to_kill.size - 1;
    new_kill.list = &(left_to_kill.list[1]);
    Mu(&first, x, new_kill, the_final_denom);
    Mu(&second, &subout, new_kill, the_final_denom);
    *result = first - second;
    first.b_clear();
    second.b_clear();
    subout.b_clear();
  }
}
int main()
{
	// Set all ranges
	Range<double> X(Xfrom,Xto);
	Range<double> T(Yfrom,Yto);
	
	// Declare all TwoVarDFunctions
	TwoVarDFunction<double,double,double> Sigma(*sigma);
	TwoVarDFunction<double,double,double> Mu(*mu);
	TwoVarDFunction<double,double,double> Forcing(*forcing);
	TwoVarDFunction<double,double,double> B(*b);
	
	// Declare all AtomicDFunctions
	AtomicDFunction<double,double> Ic(*IC); // Change from Call<->Put
//	AtomicDFunction<double,double> Bcr(*BCR_Topper_p11);
	AtomicDFunction<double,double> Bcr(*BCR);// Change from Call<->Put
	AtomicDFunction<double,double> Bcl(*BCL);// Change from Call<->Put
	
	// Declare the pde
	ParabolicPDE<double,double,double> pde(X,T,Sigma,Mu,B,Forcing,Ic,Bcl,Bcr);

	// Declare the finite difference scheme
//	ParabolicFDM<double,double,double> FDM(pde,XINTERVALS,YINTERVALS,THETA); // V1
	int choice = 3;
	cout << "1) Explicit Euler 2) Implicit Euler 3) Crank Nicolson ";
	cin >> choice;

	//OptionType type = AmericanCallType;
	OptionType type = EuropeanCallType;

	ParabolicFDM<double,double,double> FDM(pde,XINTERVALS,YINTERVALS,choice,
											type);

	// compute option prices
	FDM.start();
	
	// Retrieve and store option prices
	Vector <double,long> result = FDM.line(); // Does include ENDS!!


///////////////////////////////////////////////////////////

	Vector<double, long> xArr = FDM.xarr();
	Vector<double, long> tArr = FDM.tarr();

	double h = xArr[2] - xArr[1];
	double k = tArr[2] - tArr[1];

	cout << "h " << h << endl;

	// Create and fill Delta vector
	Vector <double,long> DeltaMesh(xArr.Size()-2, xArr.MinIndex());
	for (long kk = DeltaMesh.MinIndex(); kk <= DeltaMesh.MaxIndex(); kk++)
	{
		DeltaMesh[kk] = xArr[kk+1];
	}

	Vector <double,long> Delta(result.Size()-2,result.MinIndex());
	for (long i = Delta.MinIndex(); i <= Delta.MaxIndex(); i++)
	{
		Delta[i] = (result[i+1] - result[i])/(h);
	}
	print(result);
	print(Delta);

	// Create and fill Gamma vector
	Vector <double,long> GammaMesh(DeltaMesh.Size()-2, DeltaMesh.MinIndex());
	for (long p = GammaMesh.MinIndex(); p <= GammaMesh.MaxIndex(); p++)
	{
		GammaMesh[p] = DeltaMesh[p+1];
	}

	Vector <double,long> Gamma(Delta.Size()-2, Delta.MinIndex());
	for (long n = Gamma.MinIndex(); n <= Gamma.MaxIndex(); n++)
	{
		Gamma[n] = (Delta[n+1] - Delta[n])/(h);
	}

	/*// Create and fill Theta vector
	Vector <double,long> ThetaMesh(tArr.Size()-1, tArr.MinIndex());
	for (long m = ThetaMesh.MinIndex(); m <= ThetaMesh.MaxIndex(); m++)
	{
		ThetaMesh[m] = tArr[m+1];
	}*/

	long NP1 = FDM.result().MaxRowIndex();
	long NP = FDM.result().MaxRowIndex() -1;

	Vector <double,long> Theta(result.Size(), result.MinIndex());
	for (long ii = Theta.MinIndex(); ii <= Theta.MaxIndex(); ii++)
	{
		Theta[ii] = -(FDM.result()(NP1, ii) -FDM.result()(NP, ii) )/k;
	}

	try
	{
		printOneExcel(FDM.xarr(), result, string("Price"));
		printOneExcel(DeltaMesh, Delta, string("Delta"));
		printOneExcel(GammaMesh, Gamma, string("Gamma"));
		printOneExcel(FDM.xarr(), Theta, string("Theta"));

	}
	catch(DatasimException& e)
	{
		e.print();

		ExcelDriver& excel = ExcelDriver::Instance();
		excel.MakeVisible(true);	

		long y = 1;
		excel.printStringInExcel(e.Message(), y, y, string("Err"));

		list<string> dump;
		dump.push_back(e.MessageDump()[0]);
		dump.push_back(e.MessageDump()[1]);
		dump.push_back(e.MessageDump()[2]);

		excel.printStringInExcel(dump, 1, 1, string("Err"));

		return 0;
	}

	return 0;
}
Пример #5
0
int main(int argc, char** argv){

    ros::init(argc, argv, "wkmeans_test");
    ros::NodeHandle node;
    ros::Rate rate(100);

    std::size_t K = 10;

    arma::vec pi = arma::randu<arma::vec>(3);
              pi = arma::normalise(pi);
    std::vector<arma::vec> Mu(K);
    std::vector<arma::mat> Sigma(K);


    float a = -2;
    float b =  2;

    for(std::size_t k = 0; k < K;k++){
        Mu[k] = (b - a) * arma::randu<arma::vec>(3) + a;
        Sigma[k].zeros(3,3);
        arma::vec tmp = 0.3 * arma::randu<arma::vec>(3) + 0.2;
        Sigma[k](0,0) =tmp(0);
        Sigma[k](1,1) =tmp(1);
        Sigma[k](2,2) =tmp(2);
    }


      GMM gmm;
      gmm.setParam(pi,Mu,Sigma);
      std::size_t nb_samples = 10000;
      arma::colvec weights;
      arma::mat X(nb_samples,3);
      gmm.sample(X);
      arma::vec L(nb_samples);
      gmm.P(X,L);

      L = L / arma::max(L);

     // L.elem(q1).zeros();

      unsigned char                           rgb[3];
      std::vector<std::array<float,3> >       colors(nb_samples);


      for(std::size_t i = 0 ; i < L.n_elem;i++){
          ColorMap::jetColorMap(rgb,L(i),0,1);
          colors[i][0]    = ((float)rgb[0])/255;
          colors[i][1]    = ((float)rgb[1])/255;
          colors[i][2]    = ((float)rgb[2])/255;
      }


        arma::uvec q1 = arma::find(L > 0.6*arma::max(L));

        std::vector<std::array<float,3> >  colors2(q1.n_elem);
        arma::mat X_W(q1.n_elem,3);
        for(std::size_t i = 0; i < q1.n_elem;i++){
            assert(q1(i) < colors.size());
            assert(q1(i) < X.n_rows);
            colors2[i]  = colors[q1(i)];
            X_W.row(i)  = X.row(q1(i));
        }




      Weighted_Kmeans<double> weighted_kmeans;

      weighted_kmeans.cluster(X_W.st(),L);
      weighted_kmeans.centroids.print("centroids");

      opti_rviz::Vis_points points(node,"centroids");
      points.scale = 0.1;
      points.r = 1;
      points.b = 1;
      arma::fmat c = arma::conv_to<arma::fmat>::from(weighted_kmeans.centroids.st());
      points.initialise("world",c);

      opti_rviz::Vis_point_cloud vis_point(node,"samples");
      vis_point.set_display_type(opti_rviz::Vis_point_cloud::DEFAULT);
      vis_point.initialise("world",X_W);



    opti_rviz::Vis_gmm vis_gmm(node,"gmm");
    vis_gmm.initialise("world",pi,Mu,Sigma);


    while(node.ok()){


        vis_gmm.update(pi,Mu,Sigma);
        vis_gmm.publish();

        vis_point.update(X_W,colors2,weights);
        vis_point.publish();

        points.update(c);
        points.publish();

        ros::spinOnce();
        rate.sleep();
    }



}
Пример #6
0
yarp::sig::Matrix idynChainGetMoments_usingKDL(iCub::iDyn::iDynChain & idynChain,iCub::iDyn::iDynInvSensor & idynSensor,yarp::sig::Vector & ddp0)
{
    KDL::Wrenches f_i;
    int nj = idynChain.getN();
    
    int ns = nj+1;
    int sensor_link = idynSensor.getSensorLink();

    yarp::sig::Vector mu(3),f(3);
    yarp::sig::Matrix Mu(3,nj);
    
    Mu.zero();

    f_i =  idynChainGet_usingKDL_aux(idynChain,idynSensor,ddp0);
    
    //Debug
    /*
    std::cout << "f_i with sensor " << std::endl;
    for(int p=0;p<f_i.size();p++)
    {
        std::cout << f_i[p] << std::endl;
    }
    */
    
    int i,j;
    for(i=0,j=0; i < ns; i++) {
        mu.zero();
        if( i < sensor_link-1 ) {
            assert(i != ns -1);
            to_iDyn(f_i[i+1].force,f);
            f = ((idynChain)[i+1]).getR()*f;
            to_iDyn(f_i[i+1].torque,mu);
            yarp::sig::Vector r_n = ((idynChain)[i+1]).getH().subcol(0,3,3);
            mu = ((idynChain)[i+1]).getR()*mu+cross(r_n,f);
        }
        if( i == sensor_link-1 )
        {
            assert(i != ns -1);
            //pay attention to this, for KDL the wrench is referred to the sensor reference frame
            iCub::iKin::iKinLink link_sensor = idynChain[sensor_link];
            //double angSensorLink = link_sensor.getAng();
            yarp::sig::Matrix  H_sensor_link = (link_sensor.getH());
            //link_sensor.setAng(angSensorLink);
            yarp::sig::Matrix H_0 = H_sensor_link  * (idynSensor.getH());
            
            to_iDyn(f_i[i+1].force,f);
            f = H_0.submatrix(0,2,0,2)*f;
            to_iDyn(f_i[i+1].torque,mu);
            yarp::sig::Vector r_n = H_0.subcol(0,3,3);
            mu =  H_0.submatrix(0,2,0,2)*mu+cross(r_n,f);
        }
        if( i > sensor_link-1 ) 
        {
            if( i != ns-1 ) {
                to_iDyn(f_i[i+1].force,f);
                f = ((idynChain)[i]).getR()*f;
                to_iDyn(f_i[i+1].torque,mu);
                yarp::sig::Vector r_n = ((idynChain)[i]).getH().subcol(0,3,3);
                mu = ((idynChain)[i]).getR()*mu+yarp::math::cross(r_n,f);
            } else {
                mu.zero();
            }
            
        }
        if(i!=sensor_link) {
            Mu.setCol(j,mu);
            j++;
        }
    }
    
    /*for(int i=0; i < nj; i++ ) {
      if( i != nj -1 ) {  
        to_iDyn(f_i[i+1].force,f);
        f = (idynChain[i+1]).getR()*f;
        to_iDyn(f_i[i+1].torque,mu);
        Vector r_n = ((idynChain)[i+1]).getH().subcol(0,3,3);
        mu = ((idynChain)[i+1]).getR()*mu+cross(r_n,f);
      } else {
        mu.zero();
      }*/
    return Mu;
}
Пример #7
0
SEXP MADBayes( SEXP _b, SEXP _clusterLabels, SEXP _Theta, SEXP _Mu, SEXP _D,
	       SEXP _Gamma, SEXP _Y, SEXP _lambdap, SEXP _lambdaw, SEXP _lambda) {

	// The following values are 1updated in MCMC iterations
	IntegerVector b(_b); // length I
	IntegerVector clusterLabels(_clusterLabels); // length I
	IntegerMatrix Theta(_Theta); // K by I
	//NumericMatrix W(_W); // KS by I + 1
	//NumericMatrix P(_P); // I by S
	NumericMatrix Mu(_Mu); // N by S
	IntegerVector D(_D); // Length N, valued in {0, 1, ..., K-1}
	double lambda = as<double>(_lambda);

	// The following values are piror parameters and are fixed
	double lambdap = as<double>(_lambdap);
	double lambdaw = as<double>(_lambdaw);

	// The following is the external information.
	NumericMatrix Gamma(_Gamma); // N*S by I
	NumericMatrix Y(_Y); // N by I

	// extract the dimensions
	int I = b.size();
	int S = Mu.ncol();
	int K = Theta.nrow();
	int N = D.size();

	// The following will be computed
	NumericMatrix W(K * S, I + 1);
	NumericMatrix P(I, S);

	// iterators
	int i, j, k = 0, s = 0, n, i1;//, likid;
	double loss;

	double _LOW = 1e-10;

	int ClusterSize[I + 1];

	for(i = 0; i < I + 1; i ++) {
		ClusterSize[i] = 0;
	}

	// Compute J

	int J = 0;
	for(i = 0; i < I; i ++) {
		if(J < clusterLabels[i]) {
			J = clusterLabels[i];
		}
		ClusterSize[clusterLabels[i]] ++;
	}
	J ++;

	// Update W
	for(j = 0; j < J; j ++) {
		for(k = 0; k < K; k ++) {
			double tmp[S + 1];
			tmp[S] = 0;
			for(s = 0; s < S; s ++) {
				tmp[s] = _LOW;
				tmp[S] += tmp[s];
				W(s * K + k, j) = 0;
			}
			for(i = 0; i < I; i ++) {
				if(b[i] == 0 && clusterLabels[i] == j) {
					tmp[Theta(k, i)] ++;
					tmp[S] ++;
				}
			}
			for(s = 0; s < S; s ++) {
				W(s * K + k, j) = tmp[s] / tmp[S];
			}
		}
	}

	// update P
	for(i = 0; i < I; i ++) {
		double tmp[S + 1];
		tmp[S] = 0;
		for(s = 0; s < S; s++) {
			tmp[s] = _LOW;
			tmp[S] += _LOW;
			P(i, s) = 0;
		}
		for(k = 0; k < K; k ++) {
			tmp[Theta(k, i)] ++;
			tmp[S] ++;
		}
		for(s = 0; s < S; s ++) {
			P(i, s) = tmp[s] / tmp[S];
		}
	}

	// update b
	for(i = 0; i < I; i ++) {
		double tmp = 0;
		for(k = 0; k < K; k ++) {
			tmp += 2 * lambdap * (1 - P(i, Theta(k, i)));
		}

		for(k = 0; k < K; k ++) {
			tmp -= 2 * lambdaw * (1 - W(Theta(k, i) * K + k, clusterLabels[i]));
		}
		    
		if(tmp < 0)
			b[i] = 1;
		else
			b[i] = 0;
	}

	loss = 0;
	for(i = 0; i < I; i ++) {
		for(n = 0; n < N; n ++) {
			k = D[n];
			s = Theta(k, i);
			loss += (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)) *
				(Y(n, i) - Mu(n, s) * Gamma(s * N + n, i));
		}

		if(b[i] == 1) {
			for(k = 0; k < K; k ++) {
				loss += 2 * lambdap * (1 - P(i, Theta(k, i)));
			}
		} else {
			for(k = 0; k < K; k ++) {
				loss += 2 * (1 - W(Theta(k, i) * K + k, clusterLabels[i])) * lambdaw;
			}
		}
	}
	loss += lambda * (J - 1);

	//printf("b, Loss function = %3.3f, number of clusters = %d\n", loss, J);

	// update Theta
	for(i = 0; i < I; i ++) {
		for(k = 0; k < K; k ++) {
			double tmp[S];
			for(s = 0; s < S; s ++) {
				// initialize
				tmp[s] = 0;
				//
				for(n = 0; n < N; n ++) {
					if(D[n] == k) {
						tmp[s] += (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)) * (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i));
					}
				}
				if(b[i] == 1) {
					tmp[s] += 2 * lambdap * (1 - P(i, s));
				} else {
					tmp[s] += 2 * lambdaw * (1 - W(s * K + k, clusterLabels[i]));
				}
			}
			// Assign new values
			Theta(k, i) = 0;
			for(s = 1; s < S; s ++) {
				if(tmp[s] < tmp[Theta(k, i)])
					Theta(k, i) = s;
			}
		}
	}

	loss = 0;
	for(i = 0; i < I; i ++) {
		for(n = 0; n < N; n ++) {
			k = D[n];
			s = Theta(k, i);
			loss += (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)) *
				(Y(n, i) - Mu(n, s) * Gamma(s * N + n, i));
		}

		if(b[i] == 1) {
			for(k = 0; k < K; k ++) {
				loss += 2 * lambdap * (1 - P(i, Theta(k, i)));
			}
		} else {
			for(k = 0; k < K; k ++) {
				loss += 2 * (1 - W(Theta(k, i) * K + k, clusterLabels[i])) * lambdaw;
			}
		}
	}
	loss += lambda * (J - 1);

	//printf("theta, Loss function = %3.3f, number of clusters = %d\n", loss, J);

	//update clusters
	for(i = 0; i < I; i ++) {
		// do not update cluster if this is a singleton
		if(b[i] == 1)
			continue;

		int oldState = clusterLabels[i];
		ClusterSize[clusterLabels[i]] --;
		double tmp[J];
		double mintmp = lambda;// cost of starting a new cluster
		int newState = J;
		for(j = 0; j < J; j ++) {
			tmp[j] = 0;
			for(k = 0; k < K; k ++) {
				tmp[j] += 2 * (1 - W(Theta(k, i) * K + k, j)) * lambdaw;
			}
			// assign the minimum cost
			if(tmp[j] < mintmp) {
				mintmp = tmp[j];
				newState = j;
			}
		}

		clusterLabels[i] = newState;
		ClusterSize[newState] ++;
		if(mintmp >= lambda) {
			// a new cluster is formed
			if(J != newState) {
				printf("Error: new state is not J = %d.", J);
				exit(1);
			}
			for(s = 0; s < S; s ++) {
				for(k = 0; k < K; k ++) {
					if(Theta(k, i) != s) {
						W(s * K + k, J) = _LOW;
					} else {
						W(s * K + k, J) = 1 - (S - 1) * _LOW;
					}
				}
			}
			J ++;
		}
		if(ClusterSize[oldState] == 0) {
			// an old cluster should be removed
			W(_, oldState) = W(_, J - 1);
			for(k = 0; k < K * S; k ++) {
				W(k, J - 1) = 0;
			}
			for(i1 = 0; i1 < I; i1 ++) {
				if(clusterLabels[i1] == J - 1)
					clusterLabels[i1] = oldState;
			}
			ClusterSize[oldState] = ClusterSize[J - 1];
			ClusterSize[J - 1] = 0;
			J --;
		}
	}

	loss = 0;
	for(i = 0; i < I; i ++) {
		for(n = 0; n < N; n ++) {
			k = D[n];
			s = Theta(k, i);
			loss += (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)) *
				(Y(n, i) - Mu(n, s) * Gamma(s * N + n, i));
		}

		if(b[i] == 1) {
			for(k = 0; k < K; k ++) {
				loss += 2 * lambdap * (1 - P(i, Theta(k, i)));
			}
		} else {
			for(k = 0; k < K; k ++) {
				loss += 2 * (1 - W(Theta(k, i) * K + k, clusterLabels[i])) * lambdaw;
			}
		}
	}
	loss += lambda * (J - 1);

	//printf("z, Loss function = %3.3f, number of clusters = %d\n", loss, J);

	// update mu
	for(n = 0; n < N; n ++) {
		double denom = 0, numer = 0;
		for(i = 0; i < I; i ++) {
			denom += Gamma(n + s * N, i);
			numer += Y(n, i);
		}
		for(s = 0; s < S; s ++) {
			Mu(n, s) = numer / denom;
		}
		for(s = 0; s < S; s ++) {
			denom = 0;
			numer = 0;
			for(i = 0; i < I; i ++) {
				if(Theta(D[n], i) == s) {
					numer += Y(n, i);
					denom += Gamma(n + s * N, i);
				}
			}
			if(denom > 0) {
				Mu(n, s) = numer / denom;
			}
		}
	}

	// calculate the loss function

	loss = 0;
	for(i = 0; i < I; i ++) {
		for(n = 0; n < N; n ++) {
			k = D[n];
			s = Theta(k, i);
			loss += (Y(n, i) - Mu(n, s) * Gamma(s * N + n, i)) *
				(Y(n, i) - Mu(n, s) * Gamma(s * N + n, i));
		}

		if(b[i] == 1) {
			for(k = 0; k < K; k ++) {
				loss += 2 * lambdap * (1 - P(i, Theta(k, i)));
			}
		} else {
			for(k = 0; k < K; k ++) {
				loss += 2 * (1 - W(Theta(k, i) * K + k, clusterLabels[i])) * lambdaw;
			}
		}
	}
	loss += lambda * (J - 1);

	//printf("Loss function = %3.3f, number of clusters = %d\n", loss, J);

	Rcpp::List ret = Rcpp::List::create(
					    Rcpp::Named("Theta") = Theta,
					    Rcpp::Named("clusterLabels") = clusterLabels,
					    Rcpp::Named("b") = b,
					    Rcpp::Named("W") = W,
					    Rcpp::Named("P") = P,
					    Rcpp::Named("Mu") = Mu,
					    Rcpp::Named("loss") = loss
					    //,Rcpp::Named("oldlik") = oldlik
					    );
	return( ret );

}
Пример #8
0
/*
   Hyperparameters - vector of length 7 (if of length 6, then default value of 1.0 is used for Hyperparameters(3))
   
   Sets prior_X and prior_Y
*/
void SBVAR_symmetric::SimsZhaDummyObservations(const TDenseVector &Hyperparameters, double PeriodsPerYear, double VarianceScale)
{
  // check hyperparameters
  TDenseVector Mu(7);
  if (Hyperparameters.dim == 6) 
    {
      for (int i=0; i < 7; i++)
	if (i < 3)
	  Mu(i)=Hyperparameters(i);
	else if (i == 3)
	  Mu(i)=1.0;
	else
	  Mu(i)=Hyperparameters(i-1);
    }
  else if (Hyperparameters.dim == 7)
    Mu=Hyperparameters;
  else
    throw dw_exception("Sims-Zha prior requires seven hyperparameters");
  
  if (PeriodsPerYear <= 0)
    throw dw_exception("Periods per year must be positive");

  if (VarianceScale <= 0)
    throw dw_exception("variance scale must be positive");

  for (int i=6; i >= 0; i--)
    if (Mu(i) <= 0) throw dw_exception("Sims-Zha hyperparameters must be positive");

  // data info
  int n_obs=NumberObservations();
  TDenseMatrix Y=Data();
  TDenseMatrix X=PredeterminedData();

  // compute mean of initial data contained in the first observaton of the predetermined data
  TDenseVector m(n_vars,0.0);
  if (n_lags > 0)
    {
      for (int i=n_lags-1; i >= 0; i--)
	for (int j=n_vars-1; j >= 0; j--)
	  m(j)+=X(0,i*n_vars+j);
      m=(1.0/(double)n_lags)*m;
    }

  // compute variance of univariate AR residuals
  TDenseVector s(n_vars,0.0), y(n_obs), e(n_obs);
  TDenseMatrix Q, R, M(n_obs,n_lags+1);
  for (int i=n_vars-1; i >= 0; i--)
    {
      for (int j=n_lags-1; j >= 0; j--)
	M.Insert(0,j,X,0,n_obs-1,j*n_vars+i,j*n_vars+i);
      M.Insert(0,n_lags,X,0,n_obs-1,n_predetermined-1,n_predetermined-1);
      QR(Q,R,M);
      y.ColumnVector(Y,i);
      e=y - Q*(Transpose(Q)*y);
      s(i)=Norm(e)/sqrt((double)n_obs);
    }

  // dummy observations
  prior_Y.Zeros(2+n_vars*(n_lags+2),n_vars);
  prior_X.Zeros(2+n_vars*(n_lags+2),n_predetermined);

  // prior on a(k,i): dummy observations of the form
  //   y=s(i)/mu(1) * e(i,n_vars)
  //   x=0
  int row=0;
  for (int i=0; i < n_vars; i++)
    prior_Y(row+i,i)=s(i)/Mu(0);
  row+=n_vars;

  // prior on constant: dummy observation of the form
  //   y=0
  //   x=1.0/(mu(1)*mu(3)) * e(n_predermined,n_predetermined)
  prior_X(row,n_predetermined-1)=1.0/(Mu(0)*Mu(2));
  row+=1;

  if (n_lags > 0)
    {
      // random walk prior: dummy observations of the form
      //   y=s(i)/(mu(2)*mu(1)) * e(i,n_vars)
      //   x=s(i)/(mu(2)*mu(1)) * e(i,n_predetermined)
      for (int i=0; i < n_vars; i++)
	{
          prior_Y(row+i,i)=s(i)/(Mu(0)*Mu(1));
          prior_X(row+i,i)=s(i)/(Mu(0)*Mu(1));
	}
      row+=n_vars;
        
      // lag decay prior: dummy observations of the form
      //   y=0
      //   x=s(i)*(4*j/PeriodsPerYear+1)^mu(4)/(mu(1)*mu(2)) * e(j)*nvars+i,n_pred)
      for (int j=1; j < n_lags; j++)
	{
	  for (int i=0; i < n_vars; i++)
	    prior_X(row+i,j*n_vars+i)=s(i)*pow(4.0*Mu(3)*(double)j/PeriodsPerYear+1.0,Mu(4))/(Mu(0)*Mu(1));
	  row+=n_vars;
	}
    
      // sums-of-coefficients prior: dummy observations of the form
      //   y=mu(5)*m(i) * e(i,n_vars)
      //   x=sum_j { mu(5)*m(i) * e((j-1)*n_vars+i,n_pred) }
      for (int i=0; i < n_vars; i++)
	{
	  prior_Y(row+i,i)=Mu(5)*m(i);
	  for (int j=0; j < n_lags; j++)
	    prior_X(row+i,j*n_vars+i)=Mu(5)*m(i);
	}
      row+=n_vars;
    
      // co-persistence prior: dummy observation of the form
      //   y=sum_i { mu(6)*m(i) * e(i,n_vars) }
      //   x=sum_i,j { mu(6)*m(i) * e((j-1)*n_vars+i,n_pred) } + mu(6) * e(n_pred,n_pred)
      for (int i=0; i < n_vars; i++)
	{
	  prior_Y(row,i)=Mu(6)*m(i);
	  for (int j=0; j < n_lags; j++)
	    prior_X(row,j*n_vars+i)=Mu(6)*m(i);
	}
      prior_X(row,n_predetermined-1)=Mu(6);
    }

  // variance scale
  prior_Y=sqrt(1.0/VarianceScale)*prior_Y;
  prior_X=sqrt(1.0/VarianceScale)*prior_X;
}