/// <summary> /// Does a curve fitting (actually by a straight line) as described in "Neural Networks for Pattern Recognition" by C.M. Bishop, page 9. /// </summary> /// <param name="cd"></param> private void ShowCurveFitting(CurveDescriptor cd) { PointPairList ppl = cd.Points; // Create a set of linear equations Aw = b, where // a[k,j] = sum(n = 1..N : x[n] ^ (k + j) // b[k] = sum(n = 1..N : x[n] ^ k * y[n] // Actually we need only the 2nd equation, because we have an additional condition // (and therefore 1 degree of freedom less): the straight goes througth the point (x0, 0). // Therefore solve the following system: // a[1,0]*w[0] + a[1,1]*w[1] = b[1] // w[0] + x[0]*w[1] = 0 int N = ppl.Count; double[] b = new double[2]; double[,] a = new double[2, N]; for (int k = 1; k <= 1; ++k) { for (int n = 0; n < N; ++n) { b[k] += Math.Pow(ppl[n].X, k) * ppl[n].Y; } for (int j = 0; j < N; ++j) { for (int n = 0; n < N; ++n) { a[k, j] += Math.Pow(ppl[n].X, k + j); } } } // w[0] = -x[0]*w[1] // -a[1,0]*x[0]*w[1] + a[1,1]*w[1] = b[1] // w[1] = b[1] / (a[1,1] - a[1,0]*x[0]) double[] w = new double[2]; w[1] = b[1] / (a[1, 1] - a[1, 0] * ppl[0].X); w[0] = -ppl[0].X * w[1]; PointPairList linePpl = new PointPairList(); for (int n = 0; n < N; ++n) { double x = ppl[n].X; double y = w[0] + x * w[1]; linePpl.Add(x, y); } LineItem curve1 = _pane.AddCurve(cd.Curve.Label.Text + " c-fitting", linePpl, cd.Curve.Color, SymbolType.None); }
private void UpdateChart(CurveDescriptor curveDescriptor, double total) { if (!_curves.Contains(curveDescriptor)) { curveDescriptor.Points = new PointPairList(); Color col = _colors[(_nextColor++) % _colors.Length]; col = Color.FromArgb((int)(col.R * _colorCoeff), (int)(col.G * _colorCoeff), (int)(col.B * _colorCoeff)); string label = string.Format("{0}{1}", curveDescriptor.Player, curveDescriptor.Position == -1 ? "" : "," + curveDescriptor.Position.ToString()); curveDescriptor.Curve = _pane.AddCurve(label, curveDescriptor.Points, col, SymbolType.None); _curves.Add(curveDescriptor); // Add initial 0-value. curveDescriptor.Points.Add(_samplesCount - 1, 0); } curveDescriptor.Points.Add(_samplesCount, total); }
private void ParseCurveDescriptors(string[] curveDescriptorsS) { if (curveDescriptorsS.Length == 0) { _autocreateCurveDescriptors = true; return; } _autocreateCurveDescriptors = false; foreach (string cdS in curveDescriptorsS) { string [] parts = cdS.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length < 1 || parts.Length > 2) { throw new ApplicationException(string.Format("Wrong curve descriptor '{0}'", cdS)); } CurveDescriptor cd = new CurveDescriptor(); cd.Player = parts[0]; cd.Position = parts.Length < 2 ? -1 : int.Parse(parts[1]); _curveDescriptors.Add(cd, cd); } }
void logParser_OnGameRecord(GameLogParser source, GameRecord gameRecord) { if (!gameRecord.IsGameOver) { return; } _samplesCount++; if (_samplesCount >= _sampleLimit) { _sampleStep *= 2; _sampleLimit *= 2; } CurveDescriptor cdKey = new CurveDescriptor(); for (int pos = 0; pos < gameRecord.Players.Count; ++pos) { GameRecord.Player player = gameRecord.Players[pos]; cdKey.Player = player.Name; cdKey.Position = pos; CurveDescriptor curveDescriptor; if (!_curveDescriptors.TryGetValue(cdKey, out curveDescriptor)) { if (_autocreateCurveDescriptors) { curveDescriptor = new CurveDescriptor { Player = player.Name, Position = -1 }; _curveDescriptors.Add(curveDescriptor, curveDescriptor); } else { // No curve for this player and position continue; } } double total; if (!_totalResult.TryGetValue(curveDescriptor, out total)) { total = 0; } total += player.Result; _totalResult[curveDescriptor] = total; curveDescriptor.SamplesCount++; // Add to the chart only samples from players from game record, // not from all from _totalResult, in order to see where a player // stops playing. if ((curveDescriptor.SamplesCount % _sampleStep) != 0) { continue; } UpdateChart(curveDescriptor, total); } }