public Row(Row r2) { // diag = r2.diag; // diagCol = r2.diagCol; val = new List<double>(r2.val); col = new List<int>(r2.col); }
public Row DeepCopy(Row r2) { var r = new Row { //diag = r2.diag, //diagCol = r2.diagCol, val = new List<double>(r2.val), col = new List<int>(r2.col) }; return r; }
//public static HashSet<Row> CloneSetRows(HashSet<Row> rows) public static HashSet<Row> CloneSetRows(HashSet<Row> rows) { var clonedRows = new HashSet<Row>(); foreach (Row row in rows) { var r = new Row { val = new List<double>(row.val), col = new List<int>(row.col) }; clonedRows.Add(r); } return clonedRows; }
/// <summary> /// read scc and output to sparse matrix structure /// </summary> /// <param name="scc">scc states</param> /// <param name="output">output states</param> /// <returns></returns> public static SparseMatrixMDP Read2MatrixToSparseMatrix(List<MDPState> scc, List<MDPState> output) { int inputSize = scc.Count; int outputSize = output.Count; int column = inputSize + outputSize; var matrix = new SparseMatrixMDP(inputSize, column); var dtmcState2Number = new Dictionary<MDPState, int>(column); int i = 0; foreach (MDPState mdpState in scc) { dtmcState2Number.Add(mdpState, i); i++; } foreach (MDPState mdpState in output) { dtmcState2Number.Add(mdpState, i); i++; } //assign rows to matrix var groupIndex = 0; //foreach (MDPState dtmcState in scc) //{ // var rowCoord = dtmcState2Number[dtmcState]; for(int rowCoord=0;rowCoord<scc.Count;rowCoord++) { //construct group block MDPState dtmcState = scc[rowCoord]; var group = new Group(){Index = groupIndex}; int rowIndex = 0; for (int i2 = dtmcState.Distributions.Count - 1; i2 >= 0; i2--) { var dis = dtmcState.Distributions[i2]; var compressedRow = new SortedDictionary<int, double> {{rowCoord, 1}}; foreach (KeyValuePair<double, MDPState> pair in dis.States) { int colCoord = dtmcState2Number[pair.Value]; if (colCoord == rowCoord) { compressedRow[rowCoord] += -pair.Key; } else { compressedRow.Add(colCoord, -pair.Key); } } var row = new Row(new List<double>(compressedRow.Values), new List<int>(compressedRow.Keys)) { Index = rowIndex, SelectionMemoryInGroups = new Dictionary<int, int> { { groupIndex, rowIndex } }, WorkingGroup = new BitArray(inputSize), diag = 1, diagCol = groupIndex, }; row.WorkingGroup.Set(groupIndex,true); //TODO: set dia, diagCol might be redundant. rowIndex = rowIndex + 1; group.RowsInSameGroup.Add(row); //dtmcState.Distributions.RemoveAt(i2); } groupIndex++; matrix.Groups.Add(group); } return matrix; }
public static SparseMatrixMDP GaussianJordenEliminationForTreeStructure(SparseMatrixMDP smatrixMdp, bool first) { var r = smatrixMdp.Ngroup; // Debug.WriteLine(smatrixMdp); //reduce //if (first) //{ // foreach (var group in smatrixMdp.Groups) // { // group.RowsInSameGroup = LinearEquationsSolver.EliminateRedundantRowsSubExtreme(group.RowsInSameGroup); // } //} 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) foreach (Row currentRow1 in currentGroup.RowsInSameGroup) { // Debug.Assert(currentRow1.col[0] == i, "zero value"); if (currentRow1.col[0] == i) //TODO:I think this info is redundant { double currentFirstValue = currentRow1.val[0]; if (Math.Abs(currentFirstValue - 1) > EPSILON) { for (int k = 1; k < currentRow1.val.Count; k++) { currentRow1.val[k] = currentRow1.val[k] / currentFirstValue; } } currentRow1.col.RemoveAt(0); currentRow1.val.RemoveAt(0); currentRow1.diag = 1; } } currentGroup.RowsInSameGroup = LinearEquationsSolver.EliminateRedundantRowsSubExtreme(currentGroup.RowsInSameGroup); //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]; pivotRow.col.RemoveAt(0); pivotRow.val.RemoveAt(0); //if (currentGroup.RowsInSameGroup.Count > 1) //{ foreach (Row currentRow in currentGroup.RowsInSameGroup) { // bool flag; //if (!CheckDictionarySubset(pivotRow.SelectionMemoryInGroups, // currentRow.SelectionMemoryInGroups, pivotRow.WorkingGroup, currentRow.WorkingGroup)) //{ // continue; //} var r3 = new Row { diag = pivotRow.diag, diagCol = pivotRow.diagCol, Index = pivotRow.Index, }; //add elements in colValuePair // var hashset1 = new HashSet<int>(currentRow.col); //hashset1.UnionWith(pivotRow.col); var colValuePair = new SortedDictionary<int, double>(); for (int inneri = 0; inneri < currentRow.col.Count; inneri++) { //if (Math.Abs(currentRow.val[inneri]) > EPSILON) //{ colValuePair[currentRow.col[inneri]] = currentRow.val[inneri] * t; // } if (currentRow.col[inneri] == r3.diagCol) { r3.diag = r3.diag + currentRow.val[inneri] * t; } } //add workingRow to r3 //var hashset2 = new HashSet<int>(); for (int inneri = 0; inneri < pivotRow.col.Count; inneri++) { if (colValuePair.ContainsKey(pivotRow.col[inneri])) { double m = colValuePair[pivotRow.col[inneri]] + pivotRow.val[inneri]; if (Math.Abs(m) > EPSILON) { colValuePair[pivotRow.col[inneri]] = m; } } else { colValuePair[pivotRow.col[inneri]] = pivotRow.val[inneri]; } } r3.col = new List<int>(colValuePair.Keys); r3.val = new List<double>(colValuePair.Values); //r3.SelectionMemoryInGroups = new Dictionary<int, int>(pivotRow.SelectionMemoryInGroups); // r3.WorkingGroup = new BitArray(pivotRow.WorkingGroup); // foreach (KeyValuePair<int, int> d in currentRow.SelectionMemoryInGroups) // { // r3.SelectionMemoryInGroups[d.Key] = d.Value; // r3.WorkingGroup.Set(d.Key, true); // } addCollection.Add(r3); //if (pivotRow.SelectionMemoryInGroups.ContainsKey(currentGroup.Index)) //{ // break; //} } //} removeCollection.Add(pivotRow); } } //update rows in current group foreach (Row row in removeCollection) { pivotGroup.RowsInSameGroup.Remove(row); } //clear redundant rows in addCollection //pivotGroup.RowsInSameGroup.UnionWith(EliminateRedundantRows(addCollection)); //var reducedRows = EliminateRedundantRowsSubExtreme(addCollection); pivotGroup.RowsInSameGroup.UnionWith(addCollection); //if (pivotGroup.RowsInSameGroup.Count > smatrixMdp.Ncols) //r is not correct bound. //{ // pivotGroup.RowsInSameGroup = pivotGroup.Index > currentGroup.Index ? EliminateRedundantRowsSubExtremeWithNormalization(pivotGroup.RowsInSameGroup) : EliminateRedundantRowsSubExtreme(pivotGroup.RowsInSameGroup); //} } //Debug.WriteLine(smatrixMdp); } foreach (var group in smatrixMdp.Groups) { if(group.RowsInSameGroup.Count>smatrixMdp.Ncols) { group.RowsInSameGroup = LinearEquationsSolver.EliminateRedundantRowsSubExtreme(group.RowsInSameGroup); } } return smatrixMdp; }