/// <summary> Constructor
		/// 
		/// </summary>
		/// <param name="numCondSymbols">the number of conditioning symbols 
		/// </param>
		/// <param name="precision">the  precision to which numeric values are given. For
		/// example, if the precision is stated to be 0.1, the values in the
		/// interval (0.25,0.35] are all treated as 0.3. 
		/// </param>
		public KDConditionalEstimator(int numCondSymbols, double precision)
		{
			
			m_Estimators = new KernelEstimator[numCondSymbols];
			for (int i = 0; i < numCondSymbols; i++)
			{
				m_Estimators[i] = new KernelEstimator(precision);
			}
		}
		/// <summary> Constructor
		/// 
		/// </summary>
		/// <param name="numSymbols">the number of symbols 
		/// </param>
		/// <param name="precision">the  precision to which numeric values are given. For
		/// example, if the precision is stated to be 0.1, the values in the
		/// interval (0.25,0.35] are all treated as 0.3. 
		/// </param>
		public DKConditionalEstimator(int numSymbols, double precision)
		{
			
			m_Estimators = new KernelEstimator[numSymbols];
			for (int i = 0; i < numSymbols; i++)
			{
				m_Estimators[i] = new KernelEstimator(precision);
			}
			m_Weights = new DiscreteEstimator(numSymbols, true);
		}
		/// <summary> Get a probability estimator for a value
		/// 
		/// </summary>
		/// <param name="data">the value to estimate the probability of
		/// </param>
		/// <param name="given">the new value that data is conditional upon 
		/// </param>
		/// <returns> the estimator for the supplied value given the condition
		/// </returns>
		public virtual Estimator getEstimator(double given)
		{
			
			Estimator result = new KernelEstimator(m_Precision);
			if (m_NumValues == 0)
			{
				return result;
			}
			
			double delta = 0, currentProb = 0;
			double zLower, zUpper;
			for (int i = 0; i < m_NumValues; i++)
			{
				delta = m_CondValues[i] - given;
				zLower = (delta - (m_Precision / 2)) / m_StandardDev;
				zUpper = (delta + (m_Precision / 2)) / m_StandardDev;
				currentProb = (Statistics.normalProbability(zUpper) - Statistics.normalProbability(zLower));
				result.addValue(m_Values[i], currentProb * m_Weights[i]);
			}
			return result;
		}