 		h_theta = theta;
 		d_theta = h_theta;
 	}
-	hvector GetTheta() {
-		return h_theta;
-	}
+	hvector GetHostTheta() {return h_theta;}
+	dvector GetDevTheta() {return d_theta;}
+	double* GetDevThetaPtr() {thrust::raw_pointer_cast(&d_theta[0])}
+
+
 
 protected:
 	// the value of the population parameter


	// adapt the covariance matrix of the proposals for the characteristics
	__device__ __host__ virtual void AdaptProp(double* cholfact, double* snorm_deviate, double* scaled_proposal,
			double metro_ratio, int pchi)
	{
		double unit_norm = 0.0;
		for (int j=0; j<pchi; j++) {
			unit_norm += snorm_deviate[j] * snorm_deviate[j];
		}
		unit_norm = sqrt(unit_norm);
		double decay_sequence = 1.0 / pow((double) current_iter, decay_rate);
		double scaled_coef = sqrt(decay_sequence * fabs(metro_ratio - target_rate)) / unit_norm;
		for (int j=0; j<pchi; j++) {
			scaled_proposal[j] *= scaled_coef;
		}
		bool downdate = (metro_ratio < target_rate);
		// do rank-1 cholesky update to update the proposal covariance matrix
		CholUpdateR1(cholfact, scaled_proposal, pchi, downdate);
	}

	// decide whether to accept or reject the proposal based on the metropolist-hasting ratio


	// calculate initial value of characteristics
	template <class ChiType> __global__
	void virtual InitialValue(double* chi, double* meas, double* meas_unc, double* cholfact, double* logdens_meas)
	{
		int idata = blockDim.x * blockIdx.x + threadIdx.x;
		if (idata < c_ndata)
		{
			for (int j = 0; j < c_pchi; ++j) {
				chi[idata + j * c_ndata] = 0.0; // initialize chi values to zero
			}

			// set initial covariance matrix of the chi proposals as the identity matrix
			int diag_index = 0;
			for (int j=0; j<c_pchi; j++) {
				cholfact[idata + c_ndata * diag_index] = 1.0;
				diag_index += j + 2;
			}
		}
		// TODO: calculate initial log-posteriors
		curandState localState;
		ChiType Chi(&localState, 1);
		logdens_meas[idata] = Chi.logdensity_meas(chi, meas, meas_unc);
	}

	// Initialize the parallel random number generator state on the device
