/// <summary> /// Computes the endpoint deviation of the trials in this condition. For ribbon targets, the univariate /// result is the standard deviation of x-coordinates. The bivariate result is undefined. For circle /// targets, the univariate result is the standard deviation of x-coordinates. The bivariate result is /// the deviation of points around the centroid. /// </summary> /// <param name="bivariate">If true, a result considering deviation in both x- and y-dimensions is given. /// If false, only the deviation in x, defined as "along the task axis," is given.</param> /// <returns>The endpoint deviation for normalized trials in this condition.</returns> /// <remarks>Spatial outliers are excluded from this calculation so that the /// measure remains consistent with its counterpart, We.</remarks> public double GetSD(bool bivariate) { double stdev = 0.0; // compute the normalized endpoint locations for each trial in this condition List <PointF> pts = new List <PointF>(_trials.Count); for (int i = 0; i < _trials.Count; i++) { if (!_trials[i].IsPractice && _trials[i].IsComplete && !_trials[i].IsSpatialOutlier) { pts.Add(_trials[i].NormalizedEnd); // normalized selection endpoints } } // compute the desired endpoint deviation if (pts.Count > 0) { if (bivariate) { stdev = _circular ? StatsEx.StdDev2D(pts) : 0.0; // 0.0 is for ribbon task--no bivariate deviation } else { double[] dxs = new double[pts.Count]; for (int j = 0; j < pts.Count; j++) { dxs[j] = pts[j].X; } stdev = StatsEx.StdDev(dxs); // stdev in x-dimension only } } return(stdev); }
/// <summary> /// Calculates the movement variability of this movement path. This is the wigglyness of /// the path and is based on the standard deviation of movement points' distances from the /// task axis. /// </summary> /// <param name="pts">The points to analyze. These must be first rotated such that /// the task axis they are following is horizontal.</param> /// <param name="horizontal">The y-value coordinate of the horizontal task axis.</param> /// <returns>The movement variability computation.</returns> private double MovementVariability(List <PointF> pts, float horizontal) { double[] yvals = new double[pts.Count]; for (int i = 0; i < pts.Count; i++) { yvals[i] = pts[i].Y - horizontal; } return(StatsEx.StdDev(yvals)); }
private Graph gphErr; // error rates /// <summary> /// /// </summary> /// <param name="sd"></param> public ResultsForm(SessionData sd, string filename) { InitializeComponent(); this.Text = filename; // create a graph for speed gphWpm = new Graph(); gphWpm.Title = "Speed"; gphWpm.XAxisName = "Trial No."; gphWpm.YAxisName = "WPM"; gphWpm.XAxisTicks = (sd.NumTrials > 1) ? sd.NumTrials - 1 : 1; gphWpm.XAxisDecimals = 1; gphWpm.YAxisDecimals = 1; gphWpm.Legend = true; // create a graph for error rates gphErr = new Graph(); gphErr.Title = "Error Rates"; gphErr.XAxisName = "Trial No."; gphErr.YAxisName = "Error Rate"; gphErr.XAxisTicks = (sd.NumTrials > 1) ? sd.NumTrials - 1 : 1; gphErr.XAxisDecimals = 1; gphErr.YAxisDecimals = 3; gphErr.Legend = true; // create each series we wish to graph Graph.Series sWpm = new Graph.Series("WPM", Color.Red, Color.Red, true, true); Graph.Series sAdj = new Graph.Series("AdjWPM", Color.Gray, Color.Gray, true, true); Graph.Series sTot = new Graph.Series("Total", Color.Red, Color.Red, true, true); Graph.Series sUnc = new Graph.Series("Uncorrected", Color.Gray, Color.Gray, true, true); Graph.Series sCor = new Graph.Series("Corrected", Color.LightGray, Color.LightGray, true, true); // use these lists to compute the means and stdevs for each series List <double> mWpm = new List <double>(); List <double> sdWpm = new List <double>(); List <double> mAdj = new List <double>(); List <double> sdAdj = new List <double>(); List <double> mTot = new List <double>(); List <double> sdTot = new List <double>(); List <double> mUnc = new List <double>(); List <double> sdUnc = new List <double>(); List <double> mCor = new List <double>(); List <double> sdCor = new List <double>(); // add the points for each series for (int i = 0; i < sd.NumTrials; i++) { if (sd[i].NumEntries > 0) { sWpm.AddPoint(new PointR(i + 1, sd[i].WPM)); mWpm.Add(sd[i].WPM); sdWpm.Add(sd[i].WPM); sAdj.AddPoint(new PointR(i + 1, sd[i].AdjWPM)); mAdj.Add(sd[i].AdjWPM); sdAdj.Add(sd[i].AdjWPM); sTot.AddPoint(new PointR(i + 1, sd[i].TotalErrorRate)); mTot.Add(sd[i].TotalErrorRate); sdTot.Add(sd[i].TotalErrorRate); sUnc.AddPoint(new PointR(i + 1, sd[i].UncorrectedErrorRate)); mUnc.Add(sd[i].UncorrectedErrorRate); sdUnc.Add(sd[i].UncorrectedErrorRate); sCor.AddPoint(new PointR(i + 1, sd[i].CorrectedErrorRate)); mCor.Add(sd[i].CorrectedErrorRate); sdCor.Add(sd[i].CorrectedErrorRate); } } // add the means and standard deviations to the series' names sWpm.Name = String.Format("{0} (µ={1:f1}, σ={2:f1})", sWpm.Name, StatsEx.Mean(mWpm.ToArray()), StatsEx.StdDev(sdWpm.ToArray())); sAdj.Name = String.Format("{0} (µ={1:f1}, σ={2:f1})", sAdj.Name, StatsEx.Mean(mAdj.ToArray()), StatsEx.StdDev(sdAdj.ToArray())); sTot.Name = String.Format("{0} (µ={1:f3}, σ={2:f3})", sTot.Name, StatsEx.Mean(mTot.ToArray()), StatsEx.StdDev(sdTot.ToArray())); sUnc.Name = String.Format("{0} (µ={1:f3}, σ={2:f3})", sUnc.Name, StatsEx.Mean(mUnc.ToArray()), StatsEx.StdDev(sdUnc.ToArray())); sCor.Name = String.Format("{0} (µ={1:f3}, σ={2:f3})", sCor.Name, StatsEx.Mean(mCor.ToArray()), StatsEx.StdDev(sdCor.ToArray())); // add the origin point to the graphs Graph.Series origin = new Graph.Series(String.Empty, Color.Black, Color.Black, false, false); origin.AddPoint(1.0, 0.0); gphWpm.AddSeries(origin); gphErr.AddSeries(origin); // finally, add the series gphWpm.AddSeries(sWpm); gphWpm.AddSeries(sAdj); gphErr.AddSeries(sTot); gphErr.AddSeries(sUnc); gphErr.AddSeries(sCor); }