Example #1
0
 public Row(Row r2)
 {
     diag = r2.diag;
     diagCol = r2.diagCol;
     val = new List<double>(r2.val);
     col = new List<int>(r2.col);
 }
Example #2
0
        //adding r2 to r1, so diagonal element follow r2
        //assuming r2[r1.diagCol] is zero. This is true in our
        //pivoting calculation/elimination in general
        public static Row Addition(Row r1, Row r2, int denseNcol)
        {
            var r3 = new Row
                         {
                             diag = r1.diag,
                             diagCol = r1.diagCol,
                             col= new List<int>(),
                             val = new List<double>()
                         };
            //auxiliary dense vector helps to record position info
            bool[] auxiDense = new bool[denseNcol];

            //register location of nonzeros of r2. For zeros, take value as -1
            for(int i=0; i<r2.col.Count;i++)
            {
                auxiDense[r2.col[i]] = true;
            }

            //add matching nonzeros of r2 and r1 into r3;
            bool flag = false;//to detect diagnal position matching
            for (int i = 0; i < r1.col.Count;i++)
            {
                int j = r1.col[i];
                if(auxiDense[j])
                {
                    r3.col.Add(r1.col[i]);
                    r3.val.Add(r1.val[i]+r2.val[i]);
                }
                auxiDense[j] = false;
                if((!flag) && r1.col[i]==r2.diagCol)
                {
                    r3.col.Add(r1.col[i]);
                    r3.val.Add(r1.val[i] + r2.val[i]);
                    flag = true;
                }
            }

            //if diagonal element of r2 doesnot matching
            if(!flag)
            {
                r3.col.Add(r2.diagCol);
                r3.val.Add(r2.diag);
            }

            for (int i = 0; i < r2.col.Count;i++)
            {
                int j = r2.col[i];
                if(auxiDense[j])
                {
                    r3.col.Add(r2.diagCol);
                    r3.val.Add(r2.diag);
                }
                auxiDense[j] = false;
            }

            return r3;
        }
Example #3
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;
        }
Example #4
0
        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;
        }
Example #5
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;
        }
Example #6
0
 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;
 }
Example #7
0
        public static Row Addition2(Row r1, Row r2)
        {
            var hashset1 = new HashSet<int>(r1.col);
            hashset1.UnionWith(new HashSet<int>(r2.col));
            var r3 = new Row
            {
                diag = r1.diag,
                diagCol = r1.diagCol,
                //col = hashset1.ToList(),
                //val = new List<double>(hashset1.Count)

            };

               var mapCol2ValIndex = new SortedDictionary<int, double>();

            foreach (int i in hashset1)
            {
                mapCol2ValIndex.Add(i,0);
            }

            //copy r2 to r3
            for (int i = 0; i < r2.col.Count; i++)
            {
                mapCol2ValIndex[r2.col[i]]+=r2.val[i];
            }

            //copy r1 to r3
            for (int i = 0; i < r1.col.Count; i++)
            {
                mapCol2ValIndex[r1.col[i]] += r1.val[i];
            }
            r3.col = new List<int>(mapCol2ValIndex.Keys);
            r3.val = new List<double>(mapCol2ValIndex.Values);
            r3.diag = r3.col.Contains(r3.diagCol) ? mapCol2ValIndex[r3.diagCol] : 0;

            return r3;

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

            //};

            //var mapCol2ValIndex = new SortedDictionary<int, int>();

            //for (int i = 0; i < r3.col.Count;i++)
            //{
            //    mapCol2ValIndex.Add(r3.col[i],i);
            //    r3.val.Add(0); //initialization
            //}

            ////copy r2 to r3
            //for (int i = 0; i < r2.col.Count;i++)
            //{
            //    int j = r2.col[i];
            //    int k = mapCol2ValIndex[j];
            //    r3.val[k] += r2.val[i];
            //}

            ////copy r1 to r3
            //for (int i = 0; i < r1.col.Count; i++)
            //{
            //    int j = r1.col[i];
            //    r3.val[mapCol2ValIndex[j]] += r1.val[i];
            //}

            //r3.diag = r3.col.Contains(r3.diagCol) ? r3.val[mapCol2ValIndex[r3.diagCol]] : 0;

            //return r3;
        }