public static List <Tuple <int, int, double> > FindNashEq(MatrixR P1, MatrixR P2) { int columnCount = P1.GetCols(); int rowCount = P1.GetCols(); var best_payouts = new List <Tuple <int, int, double> > { //new Tuple<int,int>(1,1), }; var best_payout_labels = new List <Tuple <int, int, double> > { //new Tuple<int,int>(1,1), }; // column then row for (int c = 0; c < rowCount; c++) { // get max_payout per column double max_payout = double.NegativeInfinity; for (int r = 0; r < columnCount; r++) { //Console.WriteLine(P1[r,c]); if (P1[r, c] > max_payout) { max_payout = P1[r, c]; } } for (int r = 0; r < columnCount; r++) { if (P1[r, c] == max_payout) { best_payouts.Add(new Tuple <int, int, double>(r, c, max_payout)); } } } // row then column for (int r = 0; r < rowCount; r++) { double max_payout = double.NegativeInfinity; for (int c = 0; c < columnCount; c++) { //Console.WriteLine(P2[r,c]); if (P2[r, c] > max_payout) { max_payout = P2[r, c]; } } for (int c = 0; c < columnCount; c++) { if (P2[r, c] == max_payout) { var item = best_payouts.Find(x => x.Item1 == r && x.Item2 == c); if (item != null) { best_payout_labels.Add(item); } } } } return(best_payout_labels); }
public static void TestTridiagonalEigenvalues() { MatrixR A = new MatrixR(new double[, ] { { 5, 1, 2, 2, 4 }, { 1, 1, 2, 1, 0 }, { 2, 2, 0, 2, 1 }, { 2, 1, 2, 1, 2 }, { 4, 0, 1, 2, 4 } }); int nn = 5; MatrixR xx = new MatrixR(A.GetCols(), nn); MatrixR V = Eigenvalue.Tridiagonalize(A); double[] lambda = Eigenvalue.TridiagonalEigenvalues(nn); for (int i = 0; i < nn; i++) { double s = lambda[i] * 1.001; double lam; VectorR x = Eigenvalue.TridiagonalEigenvector(s, 1e-8, out lam); for (int j = 0; j < A.GetCols(); j++) { xx[j, i] = x[j]; } } xx = V * xx; Console.WriteLine("\n Results from the tridiagonalization method:"); Console.WriteLine("\n Eigenvalues: \n ({0,10:n6} {1,10:n6} {2,10:n6} {3,10:n6} {4,10:n6})", lambda[0], lambda[1], lambda[2], lambda[3], lambda[4]); Console.WriteLine("\n Eigenvectors:"); for (int i = 0; i < 5; i++) { Console.WriteLine(" ({0,10:n6} {1,10:n6} {2,10:n6} {3,10:n6} {4,10:n6})", xx[i, 0], xx[i, 1], xx[i, 2], xx[i, 3], xx[i, 4]); } A = new MatrixR(new double[, ] { { 5, 1, 2, 2, 4 }, { 1, 1, 2, 1, 0 }, { 2, 2, 0, 2, 1 }, { 2, 1, 2, 1, 2 }, { 4, 0, 1, 2, 4 } }); MatrixR xm; VectorR lamb; Eigenvalue.Jacobi(A, 1e-8, out xm, out lamb); Console.WriteLine("\n\n Results from the Jacobi method:"); Console.WriteLine("\n Eigenvalues: \n ({0,10:n6} {1,10:n6} {2,10:n6} {3,10:n6} {4,10:n6})", lamb[4], lamb[3], lamb[2], lamb[1], lamb[0]); Console.WriteLine("\n Eigenvectors:"); for (int i = 0; i < 5; i++) { Console.WriteLine(" ({0,10:n6} {1,10:n6} {2,10:n6} {3,10:n6} {4,10:n6})", xm[i, 4], xm[i, 3], xm[i, 2], xm[i, 1], xm[i, 0]); } }
/// <summary> /// Initializes a new instance of the <see cref="UserGramSchmidt"/> class. This object creates an unitary matrix /// using the modified Gram-Schmidt method. /// </summary> /// <param name="matrix">The matrix to factor.</param> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> row count is less then column count</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is rank deficient</exception> public UserGramSchmidt(Matrix <Complex32> matrix) { if (matrix == null) { throw new ArgumentNullException("matrix"); } if (matrix.RowCount < matrix.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixDimensions); } MatrixQ = matrix.Clone(); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); for (var k = 0; k < MatrixQ.ColumnCount; k++) { var norm = MatrixQ.Column(k).Norm(2).Real; if (norm == 0.0f) { throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); } MatrixR.At(k, k, norm); for (var i = 0; i < MatrixQ.RowCount; i++) { MatrixQ.At(i, k, MatrixQ.At(i, k) / norm); } for (var j = k + 1; j < MatrixQ.ColumnCount; j++) { var dot = Complex32.Zero; for (int i = 0; i < MatrixQ.RowCount; i++) { dot += MatrixQ.Column(k)[i].Conjugate() * MatrixQ.Column(j)[i]; } MatrixR.At(k, j, dot); for (var i = 0; i < MatrixQ.RowCount; i++) { var value = MatrixQ.At(i, j) - (MatrixQ.At(i, k) * dot); MatrixQ.At(i, j, value); } } } }
public void Test_Matching_Pennies() { Debug.WriteLine("Matching Pennies"); var P1columns = new MatrixR(new double[, ] { { 1, -1, }, { -1, 1, } }); var P2rows = new MatrixR(new double[, ] { { -1, 1, }, { 1, -1, } }); var test = NashEq.FindNashEq(P1columns, P2rows); foreach (var tuple in test) { Debug.WriteLine("P1 {0} - P2 {1} - Score {2}", tuple.Item1, tuple.Item2, tuple.Item3); } }
public void Test_Pigs_Game() { Debug.WriteLine("Pigs Game"); var P1columns = new MatrixR(new double[, ] { { 4, 2, }, { 2, 3, } }); var P2rows = new MatrixR(new double[, ] { { 6, 0, }, { -1, 0, } }); var test = NashEq.FindNashEq(P1columns, P2rows); foreach (var tuple in test) { Debug.WriteLine("P1 {0} - P2 {1} - Score {2}", tuple.Item1, tuple.Item2, tuple.Item3); } }
public void Test_Hawk_Dove() { Debug.WriteLine("Hawk - Dove"); var P1columns = new MatrixR(new double[, ] { { 0, 1, }, { 3, 2, } }); var P2rows = new MatrixR(new double[, ] { { 0, 3, }, { 1, 2, } }); var test = NashEq.FindNashEq(P1columns, P2rows); foreach (var tuple in test) { Debug.WriteLine("P1 {0} - P2 {1} - Score {2}", tuple.Item1, tuple.Item2, tuple.Item3); } }
public void Test_Prisoner_Dilemma() { Debug.WriteLine("Prisoner's Dilemma"); MatrixR P1columns = new MatrixR(new double[, ] { { 3, 0, }, { 5, 1, } }); MatrixR P2rows = new MatrixR(new double[, ] { { 3, 5, }, { 0, 1, } }); var test = NashEq.FindNashEq(P1columns, P2rows); foreach (var tuple in test) { Debug.WriteLine("P1 {0} - P2 {1} - Score {2}", tuple.Item1, tuple.Item2, tuple.Item3); } }
/// <summary> /// Initializes a new instance of the <see cref="UserGramSchmidt"/> class. This object creates an orthogonal matrix /// using the modified Gram-Schmidt method. /// </summary> /// <param name="matrix">The matrix to factor.</param> /// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> row count is less then column count</exception> /// <exception cref="ArgumentException">If <paramref name="matrix"/> is rank deficient</exception> public UserGramSchmidt(Matrix <float> matrix) { if (matrix == null) { throw new ArgumentNullException("matrix"); } if (matrix.RowCount < matrix.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixDimensions); } MatrixQ = matrix.Clone(); MatrixR = matrix.CreateMatrix(matrix.ColumnCount, matrix.ColumnCount); for (var k = 0; k < MatrixQ.ColumnCount; k++) { var norm = MatrixQ.Column(k).Norm(2); if (norm == 0.0) { throw new ArgumentException(Resources.ArgumentMatrixNotRankDeficient); } MatrixR.At(k, k, norm); for (var i = 0; i < MatrixQ.RowCount; i++) { MatrixQ.At(i, k, MatrixQ.At(i, k) / norm); } for (var j = k + 1; j < MatrixQ.ColumnCount; j++) { var dot = MatrixQ.Column(k).DotProduct(MatrixQ.Column(j)); MatrixR.At(k, j, dot); for (var i = 0; i < MatrixQ.RowCount; i++) { var value = MatrixQ.At(i, j) - (MatrixQ.At(i, k) * dot); MatrixQ.At(i, j, value); } } } }
/// <summary> /// Solves a system of linear equations, <b>Ax = b</b>, with A QR factorized. /// </summary> /// <param name="input">The right hand side vector, <b>b</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param> public override void Solve(Vector <double> input, Vector <double> result) { if (input == null) { throw new ArgumentNullException("input"); } if (result == null) { throw new ArgumentNullException("result"); } // Ax=b where A is an m x n matrix // Check that b is a column vector with m entries if (MatrixR.RowCount != input.Count) { throw new ArgumentException(Resources.ArgumentVectorsSameLength); } // Check that x is a column vector with n entries if (MatrixR.ColumnCount != result.Count) { throw Matrix.DimensionsDontMatch <ArgumentException>(MatrixR, result); } var inputCopy = input.Clone(); // Compute Y = transpose(Q)*B var column = new double[MatrixR.RowCount]; for (var k = 0; k < MatrixR.RowCount; k++) { column[k] = inputCopy[k]; } for (var i = 0; i < MatrixR.RowCount; i++) { double s = 0; for (var k = 0; k < MatrixR.RowCount; k++) { s += MatrixQ.At(k, i) * column[k]; } inputCopy[i] = s; } // Solve R*X = Y; for (var k = MatrixR.ColumnCount - 1; k >= 0; k--) { inputCopy[k] /= MatrixR.At(k, k); for (var i = 0; i < k; i++) { inputCopy[i] -= inputCopy[k] * MatrixR.At(i, k); } } for (var i = 0; i < MatrixR.ColumnCount; i++) { result[i] = inputCopy[i]; } }
/// <summary> /// Solves a system of linear equations, <b>AX = B</b>, with A QR factorized. /// </summary> /// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param> /// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param> public override void Solve(Matrix <double> input, Matrix <double> result) { // Check for proper arguments. if (input == null) { throw new ArgumentNullException("input"); } if (result == null) { throw new ArgumentNullException("result"); } // The solution X should have the same number of columns as B if (input.ColumnCount != result.ColumnCount) { throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); } // The dimension compatibility conditions for X = A\B require the two matrices A and B to have the same number of rows if (MatrixR.RowCount != input.RowCount) { throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); } // The solution X row dimension is equal to the column dimension of A if (MatrixR.ColumnCount != result.RowCount) { throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); } var inputCopy = input.Clone(); // Compute Y = transpose(Q)*B var column = new double[MatrixR.RowCount]; for (var j = 0; j < input.ColumnCount; j++) { for (var k = 0; k < MatrixR.RowCount; k++) { column[k] = inputCopy.At(k, j); } for (var i = 0; i < MatrixR.RowCount; i++) { double s = 0; for (var k = 0; k < MatrixR.RowCount; k++) { s += MatrixQ.At(k, i) * column[k]; } inputCopy.At(i, j, s); } } // Solve R*X = Y; for (var k = MatrixR.ColumnCount - 1; k >= 0; k--) { for (var j = 0; j < input.ColumnCount; j++) { inputCopy.At(k, j, inputCopy.At(k, j) / MatrixR.At(k, k)); } for (var i = 0; i < k; i++) { for (var j = 0; j < input.ColumnCount; j++) { inputCopy.At(i, j, inputCopy.At(i, j) - (inputCopy.At(k, j) * MatrixR.At(i, k))); } } } for (var i = 0; i < MatrixR.ColumnCount; i++) { for (var j = 0; j < inputCopy.ColumnCount; j++) { result.At(i, j, inputCopy.At(i, j)); } } }