Пример #1
0
        public static Object[][] SimplifySymbolicScalars(Object[][] A)
        {
            if (A == null) return null;

            // sort all arrays A[i] of A, and add the non-null ones in AL
            // also multiply all doubles
            ArrayList AL = new ArrayList();
            {
                SimplifySymbolicScalarsComparer SSSC = new SimplifySymbolicScalarsComparer();
                for (int i = 0; i < A.Length; i++)
                {
                    if ((A[i] != null) && (A[i].Length > 0))
                    {
                        Array.Sort(A[i], SSSC);

                        // multiply doubles (at the front)
                        if ((A[i].Length > 1) && (A[i][0] is Double) && (A[i][1] is Double)) // are there 2 or more Double at the front of A[i]?
                        {
                            // count number of doubles, multiply them together
                            int nb = 2; // we know the first two are already double!
                            double val = (double)A[i][0] * (double)A[i][1];
                            while ((nb < A[i].Length) && (A[i][nb] is Double))
                            {
                                val *= (double)A[i][nb];
                                nb++;
                            }

                            // form a new array
                            Object[] newAi = new Object[A[i].Length - nb + 1];
                            newAi[0] = val;
                            Array.Copy(A[i], nb, newAi, 1, A[i].Length - nb);
                            A[i] = newAi;
                        }

                        // if zero, then discard the whole thing:
                        if (!((A[i].Length > 1) && (A[i][0] is Double) && ((double)A[i][0] == 0.0)))
                            AL.Add(A[i]);
                    }
                }
            }

            if (AL.Count == 1) return new Object[1][] {(Object[])AL[0] };

            // sort the arrays themselves
            System.Collections.IComparer SSAC = new SimplifySymbolicArrayComparer();
            AL.Sort(SSAC);

            // merge adjacent identical (up to scale) arrays
            ArrayList mergedAL = new ArrayList();
            for (int i = 0; i < AL.Count;) // note: no increment
            {
                // find all arrays which are equal up to scale:
                int j = i+1; // j will become index of first array which is not equal up to scale
                while ((j < AL.Count) && (SSAC.Compare(AL[i], AL[j]) == 0)) j++;

                if (j - i > 1)
                { // at least one array equal up to scale: merge these arrays
                    double scale = 0; // collect scale here
                    int ALiFirstObjectIdx = -1;
                    for (int k = i; k < j; k++)
                    {
                        int l = 0;
                        Object[] ALk = (Object[])AL[k];
                        double ALkScale = 1.0;
                        while ((l < ALk.Length) && (Object.ReferenceEquals(ALk[l].GetType(), DT)))
                        {
                            ALkScale *= (double)ALk[l];
                            l++;
                        }
                        if (k == i) ALiFirstObjectIdx = l; // remember where the Objects start in AL[i]

                        scale += ALkScale;
                    }

                    if (scale != 0.0)
                    {
                        Object[] ALi = (Object[])AL[i];
                        bool scaleNotOne = (scale != 1.0);
                        Object[] newALi = new Object[ALi.Length - ALiFirstObjectIdx + ((scaleNotOne) ? 1 : 0)];
                        if (scaleNotOne) newALi[0] = scale;
                        Array.Copy(ALi, ALiFirstObjectIdx, newALi, (scaleNotOne) ? 1 : 0, ALi.Length - ALiFirstObjectIdx);
                        mergedAL.Add(newALi);
                    }

                    i = j;
                }
                else
                {
                    mergedAL.Add(AL[i]);
                    i++;
                }
            }

            if (mergedAL.Count == 0) return null;

            Object[][] resultA = new Object[mergedAL.Count][];
            for (int i = 0; i < mergedAL.Count; i++)
                resultA[i] = (Object[])mergedAL[i];
            return resultA;
        }
Пример #2
0
        public static Object[][] SimplifySymbolicScalars(Object[][] A)
        {
            if (A == null)
            {
                return(null);
            }

            // sort all arrays A[i] of A, and add the non-null ones in AL
            // also multiply all doubles
            ArrayList AL = new ArrayList();

            {
                SimplifySymbolicScalarsComparer SSSC = new SimplifySymbolicScalarsComparer();
                for (int i = 0; i < A.Length; i++)
                {
                    if ((A[i] != null) && (A[i].Length > 0))
                    {
                        Array.Sort(A[i], SSSC);

                        // multiply doubles (at the front)
                        if ((A[i].Length > 1) && (A[i][0] is Double) && (A[i][1] is Double)) // are there 2 or more Double at the front of A[i]?
                        {
                            // count number of doubles, multiply them together
                            int    nb  = 2; // we know the first two are already double!
                            double val = (double)A[i][0] * (double)A[i][1];
                            while ((nb < A[i].Length) && (A[i][nb] is Double))
                            {
                                val *= (double)A[i][nb];
                                nb++;
                            }

                            // form a new array
                            Object[] newAi = new Object[A[i].Length - nb + 1];
                            newAi[0] = val;
                            Array.Copy(A[i], nb, newAi, 1, A[i].Length - nb);
                            A[i] = newAi;
                        }

                        // if zero, then discard the whole thing:
                        if (!((A[i].Length > 1) && (A[i][0] is Double) && ((double)A[i][0] == 0.0)))
                        {
                            AL.Add(A[i]);
                        }
                    }
                }
            }

            if (AL.Count == 1)
            {
                return new Object[1][] { (Object[])AL[0] }
            }
            ;

            // sort the arrays themselves
            System.Collections.IComparer SSAC = new SimplifySymbolicArrayComparer();
            AL.Sort(SSAC);


            // merge adjacent identical (up to scale) arrays
            ArrayList mergedAL = new ArrayList();

            for (int i = 0; i < AL.Count;) // note: no increment
            {
                // find all arrays which are equal up to scale:
                int j = i + 1; // j will become index of first array which is not equal up to scale
                while ((j < AL.Count) && (SSAC.Compare(AL[i], AL[j]) == 0))
                {
                    j++;
                }

                if (j - i > 1)
                {                                 // at least one array equal up to scale: merge these arrays
                    double scale             = 0; // collect scale here
                    int    ALiFirstObjectIdx = -1;
                    for (int k = i; k < j; k++)
                    {
                        int      l        = 0;
                        Object[] ALk      = (Object[])AL[k];
                        double   ALkScale = 1.0;
                        while ((l < ALk.Length) && (Object.ReferenceEquals(ALk[l].GetType(), DT)))
                        {
                            ALkScale *= (double)ALk[l];
                            l++;
                        }
                        if (k == i)
                        {
                            ALiFirstObjectIdx = l;         // remember where the Objects start in AL[i]
                        }
                        scale += ALkScale;
                    }


                    if (scale != 0.0)
                    {
                        Object[] ALi         = (Object[])AL[i];
                        bool     scaleNotOne = (scale != 1.0);
                        Object[] newALi      = new Object[ALi.Length - ALiFirstObjectIdx + ((scaleNotOne) ? 1 : 0)];
                        if (scaleNotOne)
                        {
                            newALi[0] = scale;
                        }
                        Array.Copy(ALi, ALiFirstObjectIdx, newALi, (scaleNotOne) ? 1 : 0, ALi.Length - ALiFirstObjectIdx);
                        mergedAL.Add(newALi);
                    }

                    i = j;
                }
                else
                {
                    mergedAL.Add(AL[i]);
                    i++;
                }
            }

            if (mergedAL.Count == 0)
            {
                return(null);
            }

            Object[][] resultA = new Object[mergedAL.Count][];
            for (int i = 0; i < mergedAL.Count; i++)
            {
                resultA[i] = (Object[])mergedAL[i];
            }
            return(resultA);
        }