Ejemplo n.º 1
0
 public static ExtendedDualNumber Sqr(ExtendedDualNumber f)
 {
     return new ExtendedDualNumber(f, f.value * f.value, 2.0 * f.value, 2.0, 0.0);
 }
Ejemplo n.º 2
0
        public static ExtendedDualNumber Sqrt(ExtendedDualNumber f)
        {
            double g = Math.Sqrt(f.value);
            double g1 = 0.5 / g;
            double g11 = -0.5 * g1 / f.value;
            double g111 = -3.0 * g11 / (2.0 * f.value);

            return new ExtendedDualNumber(f, g, g1, g11, g111);
        }
Ejemplo n.º 3
0
        public static ExtendedDualNumber Pow(ExtendedDualNumber f1, ExtendedDualNumber f2)
        {
            // FIXME Optimize this!

            double g = Math.Pow(f1.value, f2.value);

            double g1 = f2.value * Math.Pow(f1.value, f2.value - 1.0);
            double g2 = Math.Log(f1.value) * Math.Pow(f1.value, f2.value);

            double g11 = f2.value * (f2.value - 1.0) * Math.Pow(f1.value, f2.value - 2.0);
            double g22 = Math.Log(f1.value) * Math.Log(f1.value) * Math.Pow(f1.value, f2.value);
            double g12 = Math.Pow(f1.value, f2.value - 1.0) * (1.0 + Math.Log(f1.value) * f2.value);

            double g111 = f2.value * (f2.value - 1.0) * (f2.value - 2.0) * Math.Pow(f1.value, f2.value - 3.0);
            double g222 = Math.Log(f1.value) * Math.Log(f1.value) * Math.Log(f1.value) * Math.Pow(f1.value, f2.value);
            double g112 = (2.0 * f2.value - 1.0 + f2.value * (f2.value - 1.0) * Math.Log(f1.value)) * Math.Pow(f1.value, f2.value - 2.0);
            double g122 = 2.0 * Math.Log(f1.value) / f1.value * Math.Pow(f1.value, f2.value) + Math.Log(f1.value) * Math.Log(f1.value) * f2.value * Math.Pow(f1.value, f2.value - 1.0);

            return new ExtendedDualNumber(f1, f2, g, g1, g2, g11, g12, g22, g111, g112, g122, g222);
        }
Ejemplo n.º 4
0
        public static ExtendedDualNumber Sin(ExtendedDualNumber f)
        {
            double g = Math.Sin(f.value);
            double g1 = Math.Cos(f.value);
            double g11 = -g;
            double g111 = -g1;

            return new ExtendedDualNumber(f, g, g1, g11, g111);
        }
Ejemplo n.º 5
0
        public static ExtendedDualNumber Log(ExtendedDualNumber f)
        {
            double g = Math.Log(f.value);
            double g1 = 1.0 / f.value;
            double g11 = -g1 / f.value;
            double g111 = -2.0 * g11 / f.value;

            return new ExtendedDualNumber(f, g, g1, g11, g111);
        }
Ejemplo n.º 6
0
        public static ExtendedDualNumber Exp(ExtendedDualNumber f)
        {
            double g = Math.Exp(f.value);
            double g1 = g;
            double g11 = g;
            double g111 = g;

            return new ExtendedDualNumber(f, g, g1, g11, g111);
        }
Ejemplo n.º 7
0
 static ExtendedDualNumber()
 {
     zero = new ExtendedDualNumber(0.0);
 }
Ejemplo n.º 8
0
        public ExtendedDualNumber(ExtendedDualNumber f1, ExtendedDualNumber f2, double g, double g1, double g2, double g11, double g12, double g22, double g111, double g112, double g122, double g222)
        {
            value = g;

            if (f1.gradientArray != null || f2.gradientArray != null)
            {
                if (f1.gradientArray != null && f2.gradientArray != null && (f1.n != f2.n || f1.n0 != f2.n0))
                {
                    throw new ArgumentException("Inconsistent number of derivatives.");
                }

                // One of the counters may be zero if the corresponding ExtendedDualNumber is a constant.
                n = Math.Max(f1.n, f2.n);
                n0 = Math.Max(f1.n0, f2.n0);
                gradientArray = new double[n];

                if (g1 != 0.0 && f1.gradientArray != null)
                {
                    for (int i = 0; i < n; i++)
                    {
                        gradientArray[i] += g1 * f1.gradientArray[i];
                    }
                }

                if (g2 != 0.0 && f2.gradientArray != null)
                {
                    for (int i = 0; i < n; i++)
                    {
                        gradientArray[i] += g2 * f2.gradientArray[i];
                    }
                }

                if (f1.hessianArray != null || f2.hessianArray != null || g11 != 0.0 || g12 != 0.0 || g22 != 0.0 || g111 != 0.0 || g112 != 0.0 || g122 != 0.0 || g222 != 0.0)
                {
                    hessianArray = new double[HessianSize(n)];

                    if (g1 != 0.0 && f1.hessianArray != null)
                    {
                        for (int i = 0, l = 0; i < n; i++)
                        {
                            for (int j = i; j < n; j++, l++)
                            {
                                hessianArray[l] += g1 * f1.hessianArray[l];
                            }
                        }
                    }

                    if (g2 != 0.0 && f2.hessianArray != null)
                    {
                        for (int i = 0, l = 0; i < n; i++)
                        {
                            for (int j = i; j < n; j++, l++)
                            {
                                hessianArray[l] += g2 * f2.hessianArray[l];
                            }
                        }
                    }

                    if (g11 != 0.0 && f1.gradientArray != null)
                    {
                        for (int i = 0, l = 0; i < n; i++)
                        {
                            for (int j = i; j < n; j++, l++)
                            {
                                hessianArray[l] += g11 * f1.gradientArray[i] * f1.gradientArray[j];
                            }
                        }
                    }

                    if (g22 != 0.0 && f2.gradientArray != null)
                    {
                        for (int i = 0, l = 0; i < n; i++)
                        {
                            for (int j = i; j < n; j++, l++)
                            {
                                hessianArray[l] += g22 * f2.gradientArray[i] * f2.gradientArray[j];
                            }
                        }
                    }

                    if (g12 != 0.0 && f1.gradientArray != null && f2.gradientArray != null)
                    {
                        for (int i = 0, l = 0; i < n; i++)
                        {
                            for (int j = i; j < n; j++, l++)
                            {
                                hessianArray[l] += g12 * (f1.gradientArray[i] * f2.gradientArray[j] + f2.gradientArray[i] * f1.gradientArray[j]);
                            }
                        }
                    }

                    if (f1.hessianArray != null || f2.hessianArray != null || g111 != 0.0 || g112 != 0.0 || g122 != 0.0 || g222 != 0.0)
                    {
                        thirdArray = new double[ThirdReducedSize(n, n0)];

                        // The counters below are constructed so that:
                        //
                        // hessianArray[l1] is the (i,j)th   entry of the Hessian,
                        // hessianArray[l2] is the (i,k)th   entry of the Hessian,
                        // hessianArray[l3] is the (j,k)th   entry of the Hessian,
                        // thirdArray[m]    is the (i,j,k)th entry of the third derivatives tensor.
                        //
                        // It's made this way to eliminate redundant entries. In case of the Hessian, only
                        // the upper triangular part is stored.

                        if (g1 != 0.0 && f1.thirdArray != null)
                        {
                            for (int i = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i; j < n; j++)
                                {
                                    for (int k = j; k < n; k++, m++)
                                    {
                                        thirdArray[m] += g1 * f1.thirdArray[m];
                                    }
                                }
                            }
                        }

                        if (g2 != 0.0 && f2.thirdArray != null)
                        {
                            for (int i = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i; j < n; j++)
                                {
                                    for (int k = j; k < n; k++, m++)
                                    {
                                        thirdArray[m] += g2 * f2.thirdArray[m];
                                    }
                                }
                            }
                        }

                        if (g11 != 0.0 && f1.hessianArray != null)
                        {
                            for (int i = 0, l1 = 0, l2 = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i, l3 = l2; j < n; j++, l1++, l2 -= n - j)
                                {
                                    for (int k = j; k < n; k++, l2++, l3++, m++)
                                    {
                                        thirdArray[m] += g11 * (f1.gradientArray[i] * f1.hessianArray[l3] + f1.gradientArray[j] * f1.hessianArray[l2] + f1.gradientArray[k] * f1.hessianArray[l1]);
                                    }
                                }
                            }
                        }

                        if (g22 != 0.0 && f2.hessianArray != null)
                        {
                            for (int i = 0, l1 = 0, l2 = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i, l3 = l2; j < n; j++, l1++, l2 -= n - j)
                                {
                                    for (int k = j; k < n; k++, l2++, l3++, m++)
                                    {
                                        thirdArray[m] += g22 * (f2.gradientArray[i] * f2.hessianArray[l3] + f2.gradientArray[j] * f2.hessianArray[l2] + f2.gradientArray[k] * f2.hessianArray[l1]);
                                    }
                                }
                            }
                        }

                        if (g12 != 0.0 && f1.gradientArray != null && f2.hessianArray != null)
                        {
                            for (int i = 0, l1 = 0, l2 = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i, l3 = l2; j < n; j++, l1++, l2 -= n - j)
                                {
                                    for (int k = j; k < n; k++, l2++, l3++, m++)
                                    {
                                        thirdArray[m] += g12 * (f1.gradientArray[i] * f2.hessianArray[l3] + f1.gradientArray[j] * f2.hessianArray[l2] + f1.gradientArray[k] * f2.hessianArray[l1]);
                                    }
                                }
                            }
                        }

                        if (g12 != 0.0 && f2.gradientArray != null && f1.hessianArray != null)
                        {
                            for (int i = 0, l1 = 0, l2 = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i, l3 = l2; j < n; j++, l1++, l2 -= n - j)
                                {
                                    for (int k = j; k < n; k++, l2++, l3++, m++)
                                    {
                                        thirdArray[m] += g12 * (f2.gradientArray[i] * f1.hessianArray[l3] + f2.gradientArray[j] * f1.hessianArray[l2] + f2.gradientArray[k] * f1.hessianArray[l1]);
                                    }
                                }
                            }
                        }

                        if (g111 != 0.0 && f1.gradientArray != null)
                        {
                            for (int i = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i; j < n; j++)
                                {
                                    for (int k = j; k < n; k++, m++)
                                    {
                                        thirdArray[m] += g111 * f1.gradientArray[i] * f1.gradientArray[j] * f1.gradientArray[k];
                                    }
                                }
                            }
                        }

                        if (g222 != 0.0 && f2.gradientArray != null)
                        {
                            for (int i = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i; j < n; j++)
                                {
                                    for (int k = j; k < n; k++, m++)
                                    {
                                        thirdArray[m] += g222 * f2.gradientArray[i] * f2.gradientArray[j] * f2.gradientArray[k];
                                    }
                                }
                            }
                        }

                        if (g112 != 0.0 && f1.gradientArray != null && f2.gradientArray != null)
                        {
                            for (int i = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i; j < n; j++)
                                {
                                    for (int k = j; k < n; k++, m++)
                                    {
                                        thirdArray[m] += g112 * (f1.gradientArray[i] * f1.gradientArray[j] * f2.gradientArray[k] + f1.gradientArray[i] * f2.gradientArray[j] * f1.gradientArray[k] + f2.gradientArray[i] * f1.gradientArray[j] * f1.gradientArray[k]);
                                    }
                                }
                            }
                        }

                        if (g122 != 0.0 && f1.gradientArray != null && f2.gradientArray != null)
                        {
                            for (int i = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i; j < n; j++)
                                {
                                    for (int k = j; k < n; k++, m++)
                                    {
                                        thirdArray[m] += g122 * (f2.gradientArray[i] * f2.gradientArray[j] * f1.gradientArray[k] + f2.gradientArray[i] * f1.gradientArray[j] * f2.gradientArray[k] + f1.gradientArray[i] * f2.gradientArray[j] * f2.gradientArray[k]);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 9
0
        public ExtendedDualNumber(ExtendedDualNumber f, double g, double g1, double g11, double g111)
        {
            value = g;

            if (f.gradientArray != null)
            {
                n = f.n;
                n0 = f.n0;
                gradientArray = new double[n];

                if (g1 != 0.0)
                {
                    for (int i = 0; i < n; i++)
                    {
                        gradientArray[i] += g1 * f.gradientArray[i];
                    }
                }

                if (f.hessianArray != null || g11 != 0.0 || g111 != 0.0)
                {
                    hessianArray = new double[HessianSize(n)];

                    if (g1 != 0.0 && f.hessianArray != null)
                    {
                        for (int i = 0, l = 0; i < n; i++)
                        {
                            for (int j = i; j < n; j++, l++)
                            {
                                hessianArray[l] += g1 * f.hessianArray[l];
                            }
                        }
                    }

                    if (g11 != 0.0)
                    {
                        for (int i = 0, l = 0; i < n; i++)
                        {
                            for (int j = i; j < n; j++, l++)
                            {
                                hessianArray[l] += g11 * f.gradientArray[i] * f.gradientArray[j];
                            }
                        }
                    }

                    if (f.hessianArray != null || g111 != 0.0)
                    {
                        thirdArray = new double[ThirdReducedSize(n, n0)];

                        // See how the counters work in the constructor below.

                        if (g1 != 0.0 && f.thirdArray != null)
                        {
                            for (int i = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i; j < n; j++)
                                {
                                    for (int k = j; k < n; k++, m++)
                                    {
                                        thirdArray[m] += g1 * f.thirdArray[m];
                                    }
                                }
                            }
                        }

                        if (g11 != 0.0 && f.hessianArray != null)
                        {
                            for (int i = 0, l1 = 0, l2 = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i, l3 = l2; j < n; j++, l1++, l2 -= n - j)
                                {
                                    for (int k = j; k < n; k++, l2++, l3++, m++)
                                    {
                                        thirdArray[m] += g11 * (f.gradientArray[i] * f.hessianArray[l3] + f.gradientArray[j] * f.hessianArray[l2] + f.gradientArray[k] * f.hessianArray[l1]);
                                    }
                                }
                            }
                        }

                        if (g111 != 0.0)
                        {
                            for (int i = 0, m = 0; i < n0; i++)
                            {
                                for (int j = i; j < n; j++)
                                {
                                    for (int k = j; k < n; k++, m++)
                                    {
                                        thirdArray[m] += g111 * f.gradientArray[i] * f.gradientArray[j] * f.gradientArray[k];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }