Пример #1
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;
        }
Пример #2
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);
        }