Пример #1
0
        public static SparseMatrix Read2MatrixToSparseMatrix(List<DTMCState> scc, List<DTMCState> output)
        {
            int inputSize = scc.Count;
            int outputSize = output.Count;

            int column = inputSize + outputSize;

            var matrix = new SparseMatrix(inputSize,column);

            var dtmcState2Number = new Dictionary<DTMCState, int>(column);
            //var number2dtmcState = new Dictionary<int, DTMCState>(column);

            //assign coordination first
            int i = 0;
            foreach (DTMCState mdpState in scc)
            {
                dtmcState2Number.Add(mdpState, i);
                i++;
            }
            foreach (DTMCState mdpState in output)
            {
                dtmcState2Number.Add(mdpState, i);
                i++;
            }

            //assign rows to matrix
            foreach (DTMCState dtmcState in scc)
            {
                int rowCoord = dtmcState2Number[dtmcState];
                //update every valued rows elements
                var compressedRow = new SortedDictionary<int, double> {{rowCoord, 1}};

                foreach (KeyValuePair<double, DTMCState> pair in dtmcState.Transitions)
                {
                    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)) { diag = compressedRow[rowCoord], diagCol = rowCoord };
                matrix.Rows.Add(row);
                //update diagnoal elements

            }

            return matrix;
        }
Пример #2
0
        public static SparseMatrix GaussianJordenElimination(SparseMatrix smatrix)
        {
            //int r = smatrix.Nrows;
            //for (int i = 0; i < r; i++)
            //{
            //    //row value divide pivot element
            //    var currentRow = smatrix.Rows[i];
            //    if (Math.Abs(currentRow.diag) > EPSILON)
            //    {
            //        if (Math.Abs(currentRow.diag - 1) > EPSILON)
            //        {
            //            for (int k = 0; k < currentRow.val.Count; k++)
            //            {
            //                currentRow.val[k] = currentRow.val[k]/currentRow.diag;
            //            }
            //        }

            //        var colIndexCurrentRow = currentRow.col.BinarySearch(i);
            //        //using current row to deduct every other rows in smatrix if corresponding element in row i is not zero

            //        for (int j = 0; j < r; j++)
            //        {
            //            if(j==i)
            //            {
            //                continue;
            //            }
            //            var pivotRow = smatrix.Rows[j];
            //            int colIndexPivot = pivotRow.col.BinarySearch(i);
            //            if (colIndexPivot >= 0 && Math.Abs(pivotRow.val[colIndexPivot] - 0) > EPSILON)
            //                //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[colIndexPivot];
            //                //var hashset1 = new HashSet<int>(pivotRow.col);
            //                //hashset1.UnionWith(new HashSet<int>(currentRow.col));
            //                var r3 = new Row
            //                             {
            //                                 diag = pivotRow.diag,
            //                                 diagCol = pivotRow.diagCol,
            //                                // val = new List<double>(hashset1.Count),
            //                                // col = hashset1.ToList(),
            //                             };

            //                //foreach (int i1 in hashset1)
            //                //{
            //                //    colValuePair.Add(i1,0);
            //                //}

            //                //add elements in colValuePair
            //                var hashset1 = new HashSet<int>();
            //               for (int inneri = colIndexCurrentRow; inneri < currentRow.col.Count; inneri++)
            //               {
            //                   hashset1.Add(currentRow.col[inneri]);
            //               }

            //               //add workingRow to r3
            //               var hashset2 = new HashSet<int>();
            //               for (int inneri =colIndexPivot; inneri < pivotRow.col.Count; inneri++)
            //               {
            //                   hashset2.Add(pivotRow.col[inneri]);
            //               }

            //                hashset2.UnionWith(hashset1);
            //                var colValuePair = new SortedDictionary<int, double>();
            //                foreach (int i1 in hashset2)
            //                {
            //                    colValuePair.Add(i1,0);
            //                }

            //                //add currentRow*t to r3
            //                //inneri starts from colValue as it only needs to update elements after colValue
            //                for (int inneri = colIndexCurrentRow; inneri < currentRow.col.Count; inneri++)
            //                {
            //                    colValuePair[currentRow.col[inneri]] += currentRow.val[inneri]*t;
            //                }

            //                //add workingRow to r3
            //                for (int inneri = colIndexPivot; inneri < pivotRow.col.Count; inneri++)
            //                {
            //                    colValuePair[pivotRow.col[inneri]] += pivotRow.val[inneri];
            //                }

            //                //remove new introduced zeros //Comments: this is not productive.
            //                //var hashsetZeros = new HashSet<int>();
            //                //foreach (KeyValuePair<int, double> keyValuePair in colValuePair)
            //                //{
            //                //    if (Math.Abs(keyValuePair.Value) < EPSILON)
            //                //    {
            //                //        hashsetZeros.Add(keyValuePair.Key);
            //                //    }
            //                //}
            //                //foreach (int hashsetZero in hashsetZeros)
            //                //{
            //                //    colValuePair.Remove(hashsetZero);
            //                //}

            //                r3.col = new List<int>(colValuePair.Keys);
            //                r3.val = new List<double>(colValuePair.Values);

            //                //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;
            //                smatrix.Rows[j] = r3;
            //                Debug.WriteLine(smatrix);
            //            }
            //        }
            //    }
            //}
            //return smatrix;

            //the algo can be simplified because of the property for this matrix. The pivot position is positive and nozero.
            //we also assume the first element in the column gives the right index (pivot colum index)
            //for each elimiantion operation
            //there will no redundant row, therefore, after elimiantion, there will no be the case for all elements in a row being
            //zeros

            int r = smatrix.Nrows;
            for (int i = 0; i < r; i++)
            {
                //row value divide pivot element
                var currentRow = smatrix.Rows[i];
                //if (Math.Abs(currentRow.diag) > EPSILON)
                if(currentRow.col[0]==i) //assert current.Row.col.count>0;
                {
                    if (Math.Abs(currentRow.val[0] - 1) > EPSILON)
                    {
                        for (int k = 1; k < currentRow.val.Count; k++)
                        {
                            currentRow.val[k] = currentRow.val[k] / currentRow.val[0];
                        }
                    }

                    //remove the pivot position element, dia, diacol is redundant now and remove them
                    currentRow.col.RemoveAt(0);
                    currentRow.val.RemoveAt(0);

                   // var colIndexCurrentRow = currentRow.col.BinarySearch(i); //by right, this should always be the first element in the row
                   // var colIndexCurrentRow = currentRow.col[0];
                    //using current row to deduct every other rows in smatrix if corresponding element in row i is not zero

                    for (int j = 0; j < r; j++)
                    {
                        if (j == i)
                        {
                            continue;
                        }
                        var pivotRow = smatrix.Rows[j];
                        //int colIndexPivot = pivotRow.col.BinarySearch(i);
                       //int colIndexPivot = pivotRow.col[0];
                       // if (colIndexPivot >= 0 && Math.Abs(pivotRow.val[colIndexPivot] - 0) > EPSILON)
                        if(pivotRow.col[0]==i) //this actually guarantees the value nonzero,
                        //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);
                            //diag, diagcol are also redundant.

                            //var hashset1 = new HashSet<int>(pivotRow.col);
                            //hashset1.UnionWith(new HashSet<int>(currentRow.col));
                            var r3 = new Row
                            {
                                diag = pivotRow.diag,
                                diagCol = pivotRow.diagCol,
                                // val = new List<double>(hashset1.Count),
                                // col = hashset1.ToList(),
                            };

                            //add elements in colValuePair
                            var hashset1 = new HashSet<int>(currentRow.col);
                            hashset1.UnionWith(new HashSet<int>(pivotRow.col));
                            var colValuePair = new SortedDictionary<int, double>();
                            foreach (int i1 in hashset1)
                            {
                                colValuePair.Add(i1,0);
                            }

                            //add currentRow*t to r3
                            //inneri starts from colValue as it only needs to update elements after colValue
                            for (int inneri = 0; inneri < currentRow.col.Count; inneri++)
                            {
                                if (Math.Abs(currentRow.val[inneri]) > EPSILON) //make sure zero is not added
                                {
                                    colValuePair[currentRow.col[inneri]] += currentRow.val[inneri] * t;
                                }
                            }

                            //add workingRow to r3
                            for (int inneri = 0; inneri < pivotRow.col.Count; inneri++)
                            {
                                double m = colValuePair[pivotRow.col[inneri]] + pivotRow.val[inneri];
                                if (Math.Abs(m) > EPSILON) //make sure zero is not added
                                {
                                    colValuePair[pivotRow.col[inneri]] = m;
                                }
                            }

                            r3.col = new List<int>(colValuePair.Keys);
                            r3.val = new List<double>(colValuePair.Values);

                            //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;
                            smatrix.Rows[j] = r3;
                            Debug.WriteLine(smatrix);
                        }
                    }
                }
            }
            return smatrix;
        }