public static SparseMatrixMDP GaussianJordenElimination(SparseMatrixMDP smatrixMdp) { var r = smatrixMdp.Ngroup; var groups = smatrixMdp.Groups; for (int i = 0; i < r; i++) //operating on each group, i can take as pivot position { var currentGroup = groups[i]; //rows in ith group should normalized according to the element in its pivot position (ith group, ith column) Debug.Assert(groups != null, "groups != null"); foreach (Row currentRow1 in currentGroup.RowsInSameGroup) { if (currentRow1.col[0] == i) //TODO:I think this info is redundant { if (Math.Abs(currentRow1.val[0] - 1) > EPSILON) { for (int k = 1; k < currentRow1.val.Count; k++) { currentRow1.val[k] = currentRow1.val[k]/currentRow1.val[0]; } } currentRow1.col.RemoveAt(0); currentRow1.val.RemoveAt(0); } } //currentRow1.colIndexCurrentRow = currentRow1.col.BinarySearch(i); //using current row to deduct every rows in other group if corresponding element (column i in dense matrix) is not zero //follow upper triangular form. for (int j = 0; j < r; j++) //scan all groups { if (j == i) { continue; } //update rows in group j var pivotGroup = groups[j]; var removeCollection = new HashSet<Row>(); var addCollection = new HashSet<Row>(); foreach (Row pivotRow in pivotGroup.RowsInSameGroup) { if (pivotRow.col[0] == i) //index of col for column value in dense matrix equal to pivot element. if value is zero, it will not be found { double t = -pivotRow.val[0]; //var hashset1 = new HashSet<int>(pivotRow.col); //hashset1.UnionWith(new HashSet<int>(currentRow.col)); pivotRow.col.RemoveAt(0); pivotRow.val.RemoveAt(0); foreach (Row currentRow in currentGroup.RowsInSameGroup) { // bool flag; if (!CheckDictionarySubset(pivotRow.SelectionMemoryInGroups, currentRow.SelectionMemoryInGroups)) { continue; } var r3 = new Row { diag = pivotRow.diag, diagCol = pivotRow.diagCol, // val = new List<double>(hashset1.Count), // col = hashset1.ToList(), Index = pivotRow.Index, }; //add elements in colValuePair var hashset1 = new HashSet<int>(currentRow.col); hashset1.UnionWith(new HashSet<int>(pivotRow.col)); var colValuePair = new Dictionary<int, double>(hashset1.ToDictionary(item => item, item => 0.0)); for (int inneri = 0; inneri < currentRow.col.Count; inneri++) { if (Math.Abs(currentRow.val[inneri]) > EPSILON) { colValuePair[currentRow.col[inneri]] += currentRow.val[inneri]*t; } } //add workingRow to r3 //var hashset2 = new HashSet<int>(); for (int inneri = 0; inneri < pivotRow.col.Count; inneri++) { double m = colValuePair[pivotRow.col[inneri]] + pivotRow.val[inneri]; if (Math.Abs(m) > EPSILON) { colValuePair[pivotRow.col[inneri]] = m; } } r3.col = new List<int>(colValuePair.Keys); r3.val = new List<double>(colValuePair.Values); // r3.SelectionMemoryInGroups = new Dictionary<Group, Row>(pivotRow.SelectionMemoryInGroups); // r3.SelectionMemoryInGroups[currentGroup] = currentRow; r3.SelectionMemoryInGroups = new Dictionary<int,int>(pivotRow.SelectionMemoryInGroups); r3.SelectionMemoryInGroups[currentGroup.Index] = currentRow.Index; //update diag elements in that row. After row adding, the pivot element/diag info is redundant. // r3.diag = r3.col.Contains(r3.diagCol) ? colValuePair[r3.diagCol] : 0; //pivotGroup.RowsInSameGroup.Add(r3); addCollection.Add(r3); if(pivotRow.SelectionMemoryInGroups.ContainsKey(currentGroup.Index)) { break; } //If pivotRow contains currentGroup index, and currentRow can work with pivotRow, //that means the rest of rows in the group are not that useful. } removeCollection.Add(pivotRow); } } //update rows in current group foreach (Row row in removeCollection) { pivotGroup.RowsInSameGroup.Remove(row); } foreach (Row row in addCollection) { pivotGroup.RowsInSameGroup.Add(row); } } Debug.WriteLine(smatrixMdp); } return smatrixMdp; }
public static SparseMatrixMDP GaussianJordenElimination(SparseMatrixMDP smatrixMdp) { var r = smatrixMdp.Ngroup; var groups = smatrixMdp.Groups; for (int i = 0; i < r; i++) //operating on each group, i can take as pivot position { var currentGroup = groups[i]; //rows in ith group should normalized according to the element in its pivot position (ith group, ith column) Debug.Assert(groups != null, "groups != null"); foreach (Row currentRow1 in currentGroup.RowsInSameGroup) { if (currentRow1.col[0] == i) //TODO:I think this info is redundant { if (Math.Abs(currentRow1.val[0] - 1) > EPSILON) { for (int k = 1; k < currentRow1.val.Count; k++) { currentRow1.val[k] = currentRow1.val[k] / currentRow1.val[0]; } } currentRow1.col.RemoveAt(0); currentRow1.val.RemoveAt(0); } } //currentRow1.colIndexCurrentRow = currentRow1.col.BinarySearch(i); //using current row to deduct every rows in other group if corresponding element (column i in dense matrix) is not zero //follow upper triangular form. for (int j = 0; j < r; j++) //scan all groups { if (j == i) { continue; } //update rows in group j var pivotGroup = groups[j]; var removeCollection = new HashSet <Row>(); var addCollection = new HashSet <Row>(); foreach (Row pivotRow in pivotGroup.RowsInSameGroup) { if (pivotRow.col[0] == i) //index of col for column value in dense matrix equal to pivot element. if value is zero, it will not be found { double t = -pivotRow.val[0]; //var hashset1 = new HashSet<int>(pivotRow.col); //hashset1.UnionWith(new HashSet<int>(currentRow.col)); pivotRow.col.RemoveAt(0); pivotRow.val.RemoveAt(0); foreach (Row currentRow in currentGroup.RowsInSameGroup) { // bool flag; if (!CheckDictionarySubset(pivotRow.SelectionMemoryInGroups, currentRow.SelectionMemoryInGroups)) { continue; } var r3 = new Row { diag = pivotRow.diag, diagCol = pivotRow.diagCol, // val = new List<double>(hashset1.Count), // col = hashset1.ToList(), Index = pivotRow.Index, }; //add elements in colValuePair var hashset1 = new HashSet <int>(currentRow.col); hashset1.UnionWith(new HashSet <int>(pivotRow.col)); var colValuePair = new Dictionary <int, double>(hashset1.ToDictionary(item => item, item => 0.0)); for (int inneri = 0; inneri < currentRow.col.Count; inneri++) { if (Math.Abs(currentRow.val[inneri]) > EPSILON) { colValuePair[currentRow.col[inneri]] += currentRow.val[inneri] * t; } } //add workingRow to r3 //var hashset2 = new HashSet<int>(); for (int inneri = 0; inneri < pivotRow.col.Count; inneri++) { double m = colValuePair[pivotRow.col[inneri]] + pivotRow.val[inneri]; if (Math.Abs(m) > EPSILON) { colValuePair[pivotRow.col[inneri]] = m; } } r3.col = new List <int>(colValuePair.Keys); r3.val = new List <double>(colValuePair.Values); // r3.SelectionMemoryInGroups = new Dictionary<Group, Row>(pivotRow.SelectionMemoryInGroups); // r3.SelectionMemoryInGroups[currentGroup] = currentRow; r3.SelectionMemoryInGroups = new Dictionary <int, int>(pivotRow.SelectionMemoryInGroups); r3.SelectionMemoryInGroups[currentGroup.Index] = currentRow.Index; //update diag elements in that row. After row adding, the pivot element/diag info is redundant. // r3.diag = r3.col.Contains(r3.diagCol) ? colValuePair[r3.diagCol] : 0; //pivotGroup.RowsInSameGroup.Add(r3); addCollection.Add(r3); if (pivotRow.SelectionMemoryInGroups.ContainsKey(currentGroup.Index)) { break; } //If pivotRow contains currentGroup index, and currentRow can work with pivotRow, //that means the rest of rows in the group are not that useful. } removeCollection.Add(pivotRow); } } //update rows in current group foreach (Row row in removeCollection) { pivotGroup.RowsInSameGroup.Remove(row); } foreach (Row row in addCollection) { pivotGroup.RowsInSameGroup.Add(row); } } Debug.WriteLine(smatrixMdp); } return(smatrixMdp); }