// get the probability of the pose given by data based on the
    // gaussian associated with a single data item
    public float getProbability(MotionDataItem gaussian, float [] data)
    {
        // calculation for the gaussian distribution
        float coef = (float)(1.0 / Math.Pow(2 * Math.PI, gaussian.data.Length / 2.0));

        coef = (float)(coef * 1.0f / (Math.Pow(defaultSigma, gaussian.data.Length / 2.0f)));

        float product = 0.0f;

        for (int i = 0; i < data.Length; i++)
        {
            //Debug.Log ("data " + data[i] + " " + gaussian.data[i] + " " + defaultSigma);
            product += (data[i] - gaussian.data[i]) * (data[i] - gaussian.data[i]) / defaultSigma;
        }
        //Debug.Log ("product " + product);
        float p = (float)(coef * Math.Exp(-0.5f * product));

        if (Double.IsInfinity(p) || Double.IsNaN(p))
        {
            Debug.LogWarning("NaN probabilitiy " + p + " " + gaussian.label + " " + gaussian.time);
            return(0.0f);
            //throw new Exception ("Calculated probability is NaN");
        }

        // save the last probability
        // (used for scaling the thumbnails)
        gaussian.lastProbability = p;
        return(p);
    }
    // add a new posture to the data set
    // parameters are:
    // label - the class label to attach to the posture
    // clip - the animation clip containing the posture
    // time - the time at which it appears
    // tex - the texture to use for displaying the posture
    // selectedTex - the texture to use for displaying the posture when selected
    public int AddPosture(string label, string clip, float time, Texture2D tex, Texture2D selectedTex)
    {
        // turn the posture into animation data
        float [] data = GetDataInstanceFromAnimation(clip, time);

        // get the label ID of the posture
        // (checking for labels that don't exist)
        int labelId = -1;

        if (label == "")
        {
            labelId = -1;
        }
        else
        {
            labelId = GetClassId(label);
            if (labelId < 0)
            {
                return(-1);
            }
        }

        // resize the DataItems array, adding a new item at the end
        MotionDataItem [] newDataItems = new MotionDataItem[m_DataItems.Length + 1];
        for (int i = 0; i < m_DataItems.Length; i++)
        {
            newDataItems[i] = m_DataItems[i];
        }
        m_DataItems = newDataItems;
        m_DataItems[m_DataItems.Length - 1] = new MotionDataItem {
            label = label, clip = clip, time = time, labelIndex = labelId, data = data, lastProbability = 0, tex = tex, selectedTex = selectedTex
        };


        m_DataItems [m_DataItems.Length - 1].parameterValues = new ContinuousParameter[parameters.Length];
        for (int i = 0; i < m_DataItems [m_DataItems.Length - 1].parameterValues.Length; i++)
        {
            m_DataItems [m_DataItems.Length - 1].parameterValues[i]       = new ContinuousParameter();
            m_DataItems [m_DataItems.Length - 1].parameterValues[i].name  = parameters[i].name;
            m_DataItems [m_DataItems.Length - 1].parameterValues[i].value = parameters[i].value;
        }


        // return the id of the posture
        int id = m_DataItems.Length - 1;

        return(id);
    }