Beispiel #1
0
 /// <summary>
 /// Multiply this vector by a scalar value
 /// </summary>
 /// <param name="scalar"></param>
 /// <returns></returns>
 public Vector Multiply(double scalar)
 {
     Vector scaledVector = new Vector(this.NDimensions);
     for (int i = 0; i < this.NDimensions; i++)
     {
         scaledVector[i] = this[i] * scalar;
     }
     return scaledVector;
 }
Beispiel #2
0
        /// <summary>
        /// Subtract another vector from this one
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public Vector Subtract(Vector v)
        {
            if (v.NDimensions != this.NDimensions)
                throw new ArgumentException("Can only subtract vectors of the same dimensionality");

            Vector vector = new Vector(v.NDimensions);
            for (int i = 0; i < v.NDimensions; i++)
            {
                vector[i] = this[i] - v[i];
            }
            return vector;
        }
        /// <summary>
        /// Test a scaling operation of the high point, and replace it if it is an improvement
        /// </summary>
        /// <param name="scaleFactor"></param>
        /// <param name="errorProfile"></param>
        /// <param name="vertices"></param>
        /// <param name="errorValues"></param>
        /// <returns></returns>
        private static double _tryToScaleSimplex(double scaleFactor, ref ErrorProfile errorProfile, Vector[] vertices, 
            double[] errorValues, ObjectiveFunctionDelegate objectiveFunction)
        {
            // find the centroid through which we will reflect
            Vector centroid = _computeCentroid(vertices, errorProfile);
            #if DEBUG
            Console.WriteLine("centroid:" + centroid.ToString());
            #endif
            // define the vector from the centroid to the high point
            Vector centroidToHighPoint = vertices[errorProfile.HighestIndex].Subtract(centroid);

            // scale and position the vector to determine the new trial point
            Vector newPoint = centroidToHighPoint.Multiply(scaleFactor).Add(centroid);

            // evaluate the new point
            double newErrorValue = objectiveFunction(newPoint.Components);

            // if it's better, replace the old high point
            if (newErrorValue < errorValues[errorProfile.HighestIndex])
            {
                vertices[errorProfile.HighestIndex] = newPoint;
                errorValues[errorProfile.HighestIndex] = newErrorValue;
            }

            return newErrorValue;
        }
 /// <summary>
 /// Contract the simplex uniformly around the lowest point
 /// </summary>
 /// <param name="errorProfile"></param>
 /// <param name="vertices"></param>
 /// <param name="errorValues"></param>
 private static void _shrinkSimplex(ErrorProfile errorProfile, Vector[] vertices, double[] errorValues, 
     ObjectiveFunctionDelegate objectiveFunction)
 {
     Vector lowestVertex = vertices[errorProfile.LowestIndex];
     for (int i = 0; i < vertices.Length; i++)
     {
         if (i != errorProfile.LowestIndex)
         {
             vertices[i] = (vertices[i].Add(lowestVertex)).Multiply(0.5);
             errorValues[i] = objectiveFunction(vertices[i].Components);
         }
     }
 }
        /// <summary>
        /// Construct an initial simplex, given starting guesses for the constants, and
        /// initial step sizes for each dimension
        /// </summary>
        /// <param name="simplexConstants"></param>
        /// <returns></returns>
        private static Vector[] _initializeVertices(SimplexConstant[] simplexConstants)
        {
            int numDimensions = simplexConstants.Length;
            Vector[] vertices = new Vector[numDimensions + 1];

            // define one point of the simplex as the given initial guesses
            Vector p0 = new Vector(numDimensions);
            for (int i = 0; i < numDimensions; i++)
            {
                p0[i] = simplexConstants[i].Value;
            }

            // now fill in the vertices, creating the additional points as:
            // P(i) = P(0) + Scale(i) * UnitVector(i)
            vertices[0] = p0;
            for (int i = 0; i < numDimensions; i++)
            {
                double scale = simplexConstants[i].InitialPerturbation;
                Vector unitVector = new Vector(numDimensions);
                unitVector[i] = 1;
                vertices[i + 1] = p0.Add(unitVector.Multiply(scale));
            #if DEBUG
                Console.Write(i+":" + vertices[i + 1].ToString() + "==");
            #endif
            }
            #if DEBUG
            Console.WriteLine("");
            #endif
            return vertices;
        }
 /// <summary>
 /// Evaluate the objective function at each vertex to create a corresponding
 /// list of error values for each vertex
 /// </summary>
 /// <param name="vertices"></param>
 /// <returns></returns>
 private static double[] _initializeErrorValues(Vector[] vertices, ObjectiveFunctionDelegate objectiveFunction)
 {
     double[] errorValues = new double[vertices.Length];
     for (int i = 0; i < vertices.Length; i++)
     {
         errorValues[i] = objectiveFunction(vertices[i].Components);
     #if DEBUG
         Console.Write(i + ":" + vertices[i]+"==");
     #endif
     }
     return errorValues;
 }
 /// <summary>
 /// Compute the centroid of all points except the worst
 /// </summary>
 /// <param name="vertices"></param>
 /// <param name="errorProfile"></param>
 /// <returns></returns>
 private static Vector _computeCentroid(Vector[] vertices, ErrorProfile errorProfile)
 {
     int numVertices = vertices.Length;
     // find the centroid of all points except the worst one
     Vector centroid = new Vector(numVertices - 1);
     for (int i = 0; i < numVertices; i++)
     {
         if (i != errorProfile.HighestIndex)
         {
             centroid = centroid.Add(vertices[i]);
         }
     }
     return centroid.Multiply(1.0d / (numVertices - 1));
 }
 /// <summary>
 /// Evaluate the objective function at each vertex to create a corresponding
 /// list of error values for each vertex
 /// </summary>
 /// <param name="vertices"></param>
 /// <returns></returns>
 private static double[] _initializeErrorValues(Vector[] vertices, ObjectiveFunctionDelegate objectiveFunction)
 {
     double[] errorValues = new double[vertices.Length];
     for (int i = 0; i < vertices.Length; i++)
     {
         errorValues[i] = objectiveFunction(vertices[i].Components);
     }
     return errorValues;
 }
Beispiel #9
0
        /// <summary>
        /// Compute the dot product of this vector and the given vector
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public double DotProduct(Vector v)
        {
            if (v.NDimensions != this.NDimensions)
                throw new ArgumentException("Can only compute dot product for vectors of the same dimensionality");

            double sum = 0;
            for (int i = 0; i < v.NDimensions; i++)
            {
                sum += this[i] * v[i];
            }
            return sum;
        }