Ejemplo n.º 1
0
        /// <summary>
        /// Adds the specified sparse rows regarding defined multipliers.
        /// </summary>
        /// <param name="a1">The a1.</param>
        /// <param name="a2">The a2.</param>
        /// <param name="a1Coef">The a1 coef.</param>
        /// <param name="a2Coef">The a2 coef.</param>
        /// <returns> a1 * a1Coef + a2 * a2Coef</returns>
        public static SparseRow Add(SparseRow a1, SparseRow a2, double a1Coef, double a2Coef)
        {
            var buf = new SparseRow(a2.Size + a1.Size);

            //based on https://stackoverflow.com/a/12993675/1106889
            //result = a1 * a1Coef + a2 * a2Coef;

            var c1 = 0;
            var c2 = 0;

            var i1s = a1.Indexes;
            var v1s = a1.Values;
            var l1  = a1.Size;

            var i2s = a2.Indexes;
            var v2s = a2.Values;
            var l2  = a2.Size;


            while (c1 < l1 && c2 < l2)
            {
                var i1 = i1s[c1];
                var i2 = i2s[c2];

                var v1 = v1s[c1];
                var v2 = v2s[c2];

                if (i1 > i2)
                {
                    buf.Add(i2 /*or i1*/, v2 * a2Coef);
                    c2++;
                }
                else if (i1 < i2)
                {
                    buf.Add(i1, v1 * a1Coef);
                    c1++;
                }
                else
                {//common
                    var newValue = v1 * a1Coef + v2 * a2Coef;

                    buf.Add(i1, newValue);

                    c1++;
                    c2++;
                }
            }

            return(buf);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Eliminates the specified index of <see cref="eliminated"/> row by adding appropriated multiply of <see cref="eliminator"/> to it.
        /// </summary>
        /// <param name="eliminator">The eliminator row.</param>
        /// <param name="eliminated">The eliminated row.</param>
        /// <param name="eliminateIndex">The index of eliminated member.</param>
        /// <returns>Eliminated version of <see cref="eliminated"/></returns>
        public static SparseRow Eliminate(SparseRow eliminator, SparseRow eliminated, int eliminateIndex, double epsilon = 0)
        {
            var buf = new SparseRow(eliminated.Size + eliminator.Size);

            //based on https://stackoverflow.com/a/12993675/1106889
            //result = eliminator * coef + eliminated

            double coef;

            {
                var t1 = Array.BinarySearch(eliminator.Indexes, 0, eliminator.Size, eliminateIndex);
                var t2 = Array.BinarySearch(eliminated.Indexes, 0, eliminated.Size, eliminateIndex);

                if (t1 < 0 || t2 < 0)
                {
                    throw new Exception();
                }

                coef = -eliminated.Values[t2] / eliminator.Values[t1];
            }

            var c1 = 0;
            var c2 = 0;

            var i1s = eliminator.Indexes;
            var v1s = eliminator.Values;
            var l1  = eliminator.Size;

            var i2s = eliminated.Indexes;
            var v2s = eliminated.Values;
            var l2  = eliminated.Size;


            while (c1 < l1 && c2 < l2)
            {
                var i1 = i1s[c1];
                var i2 = i2s[c2];

                var v1 = v1s[c1];
                var v2 = v2s[c2];

                if (i1 > i2)
                {
                    buf.Add(i2 /*or i1*/, v2);
                    c2++;
                }
                else if (i1 < i2)
                {
                    buf.Add(i1, v1 * coef);
                    c1++;
                }
                else
                {//common
                    if (i1 != i2)
                    {
                        throw new Exception();
                    }

                    var newValue = v1 * coef + v2;

                    if (i1 == eliminateIndex || Math.Abs(newValue) < epsilon)
                    {
                        //this is eliminated item, newValue should be zero and nothing to add
                        if (Math.Abs(newValue) > 1e-6)
                        {
                            throw new Exception("wrong result");
                        }
                    }
                    else
                    {
                        buf.Add(i1, newValue);
                    }

                    c1++;
                    c2++;
                }
            }


            //tail
            {
                for (; c1 < l1; c1++)
                {
                    var i1 = i1s[c1];
                    var v1 = v1s[c1];

                    buf.Add(i1, v1 * coef);
                }

                for (; c2 < l2; c2++)
                {
                    var i2 = i2s[c2];
                    var v2 = v2s[c2];

                    buf.Add(i2, v2);
                }
            }



            return(buf);
        }