예제 #1
0
        public static DoubleVector GenerateRow(IMatrix A, int r, int c1, int c2)
        {
            int          cu = c2 - c1 + 1;
            DoubleVector u  = new DoubleVector(cu);

            for (int j = c1; j <= c2; j++)
            {
                u[j - c1] = A[r, j];
                A[r, j]   = 0.0;
            }

            double norm = u.GetNorm();

            if (c1 == c2 || norm == 0)
            {
                A[r, c1] = -u[0];
                u[0]     = (double)System.Math.Sqrt(2);
                return(u);
            }

            double scale = 1.0 / norm;

            if (u[0] < 0.0)
            {
                scale *= -1.0;
            }

            A[r, c1] = -1.0 / scale;

            for (int j = 0; j < cu; j++)
            {
                u[j] *= scale;
            }

            u[0] = u[0] + 1.0;
            double s = (double)System.Math.Sqrt(1 / u[0]);

            for (int j = 0; j < cu; j++)
            {
                u[j] *= s;
            }
            return(u);
        }
예제 #2
0
        public static DoubleVector GenerateColumn(IMatrix A, int r1, int r2, int c)
        {
            int          ru = r2 - r1 + 1;
            DoubleVector u  = new DoubleVector(r2 - r1 + 1);

            for (int i = r1; i <= r2; i++)
            {
                u[i - r1] = A[i, c];
                A[i, c]   = 0.0;
            }

            double norm = u.GetNorm();

            if (r1 == r2 || norm == 0)
            {
                A[r1, c] = -u[0];
                u[0]     = (double)System.Math.Sqrt(2);
                return(u);
            }

            double scale = 1.0 / norm;

            if (u[0] < 0.0)
            {
                scale *= -1.0;
            }

            A[r1, c] = -1.0 / scale;

            for (int i = 0; i < ru; i++)
            {
                u[i] *= scale;
            }

            u[0] += 1.0;
            double s = (double)System.Math.Sqrt(1 / u[0]);

            for (int i = 0; i < ru; i++)
            {
                u[i] *= s;
            }
            return(u);
        }
예제 #3
0
 ///<summary> Initialize the optimization method </summary>
 ///<remarks> The use of this function is intended for testing/debugging purposes only </remarks>
 public override void InitializeMethod(DoubleVector initialvector) 
 {
   g = GradientEvaluation(initialvector);
         
   // Calculate Diagonal preconditioner
   DoubleMatrix h = HessianEvaluation(initialvector);
   DoubleMatrix m_inv = new DoubleMatrix(initialvector.Length,initialvector.Length);
   for (int i=0; i<initialvector.Length; i++)
     m_inv[i,i] = 1/h[i,i];
   s = m_inv*g;
   
   DoubleVector d = -s;
   
   delta_new = g.GetDotProduct(d);
   
   restartCounter=0;
   /* ------------------------------ */
   this.iterationVectors_ = new DoubleVector[endCriteria_.maxIteration+1];
   this.iterationVectors_[0] = initialvector;
   
   this.iterationValues_ = new double[endCriteria_.maxIteration+1];
   this.iterationValues_[0] = FunctionEvaluation(this.iterationVectors_[0]);
   
   this.iterationGradients_ = new DoubleVector[endCriteria_.maxIteration+1];
   this.iterationGradients_[0] = new DoubleVector(g);
   
   this.iterationGradientNorms_ = new double[endCriteria_.maxIteration+1];
   this.iterationGradientNorms_[0] = g.GetNorm();
   
   this.iterationDirections_ = new DoubleVector[endCriteria_.maxIteration+1];
   this.iterationDirections_[0] = d;
   
   this.iterationTrialSteps_ = new double[endCriteria_.maxIteration+1];
   this.iterationTrialSteps_[0] = 1/this.iterationGradientNorms_[0];
 }
예제 #4
0
    ///<summary> Perform a single iteration of the optimization method </summary>
    ///<remarks> The use of this function is intended for testing/debugging purposes only </remarks>
    public override void IterateMethod() 
    {
    
      DoubleVector d = this.iterationDirections_[endCriteria_.iterationCounter-1];
      DoubleVector x = this.iterationVectors_[endCriteria_.iterationCounter-1];
      DoubleVector g = this.iterationGradients_[endCriteria_.iterationCounter-1];
      double stp = this.iterationTrialSteps_[endCriteria_.iterationCounter-1];
      
      // Shanno-Phua's Formula for Trial Step
      if (restartCounter==0 && endCriteria_.iterationCounter>1) 
      {
        double dg = d.GetDotProduct(g);
        double dg0 = this.iterationDirections_[endCriteria_.iterationCounter-2].GetDotProduct(
          this.iterationGradients_[endCriteria_.iterationCounter-2])/stp;
        stp = dg0/dg;
      }
      
      delta_mid = g.GetDotProduct(g);
      
      // Conduct line search
      x = lineSearchMethod_.Search(x,d,stp);
      g = GradientEvaluation(x);
      
      delta_old = delta_new;
      delta_mid = g.GetDotProduct(s);
      
      // Calculate Diagonal preconditioner
      DoubleMatrix h = HessianEvaluation(x);
      DoubleMatrix m_inv = new DoubleMatrix(x.Length,x.Length);
      for (int i=0; i<x.Length; i++)
        m_inv[i,i] = 1/h[i,i];
      s = m_inv*g;
  
      // Calculate Beta
      delta_new = g.GetDotProduct(s);
      double beta = (delta_new-delta_mid)/delta_old;

      // Check for restart conditions
      restartCounter++;
      if (restartCounter==restartCount || (restartCounter==x.Length && restartCount==0) || beta<=0) 
      {
        restartCount = 0;
        beta=0;
      }
      
      // Calculate next line search direction
      d = -s + beta*d;
      
      this.iterationVectors_[endCriteria_.iterationCounter] = x;
      this.iterationValues_[endCriteria_.iterationCounter] = FunctionEvaluation(x);
      this.iterationGradients_[endCriteria_.iterationCounter] = g;
      this.iterationGradientNorms_[endCriteria_.iterationCounter] = g.GetNorm();
      this.iterationDirections_[endCriteria_.iterationCounter] = d;
      this.iterationTrialSteps_[endCriteria_.iterationCounter] = stp;
    }
예제 #5
0
		public static DoubleVector GenerateRow(IMatrix A, int r, int c1, int c2)
		{
			int cu = c2 - c1 + 1;
			DoubleVector u = new DoubleVector(cu);

			for (int j = c1; j <= c2; j++)
			{
				u[j - c1] = A[r, j];
				A[r, j] = 0.0;
			}

			double norm = u.GetNorm();

			if (c1 == c2 || norm == 0)
			{
				A[r, c1] = -u[0];
				u[0] = (double)System.Math.Sqrt(2);
				return u;
			}

			double scale = 1.0 / norm;
			if (u[0] < 0.0)
				scale *= -1.0;

			A[r, c1] = -1.0 / scale;

			for (int j = 0; j < cu; j++)
			{
				u[j] *= scale;
			}

			u[0] = u[0] + 1.0;
			double s = (double)System.Math.Sqrt(1 / u[0]);

			for (int j = 0; j < cu; j++)
			{
				u[j] *= s;
			}
			return u;
		}
예제 #6
0
		public static DoubleVector GenerateColumn(IMatrix A, int r1, int r2, int c)
		{
			int ru = r2 - r1 + 1;
			DoubleVector u = new DoubleVector(r2 - r1 + 1);

			for (int i = r1; i <= r2; i++)
			{
				u[i - r1] = A[i, c];
				A[i, c] = 0.0;
			}

			double norm = u.GetNorm();

			if (r1 == r2 || norm == 0)
			{
				A[r1, c] = -u[0];
				u[0] = (double)System.Math.Sqrt(2);
				return u;
			}

			double scale = 1.0 / norm;
			if (u[0] < 0.0)
				scale *= -1.0;

			A[r1, c] = -1.0 / scale;

			for (int i = 0; i < ru; i++)
			{
				u[i] *= scale;
			}

			u[0] += 1.0;
			double s = (double)System.Math.Sqrt(1 / u[0]);

			for (int i = 0; i < ru; i++)
			{
				u[i] *= s;
			}
			return u;
		}
예제 #7
0
 public void GetNorm()
 {
   DoubleVector a = new DoubleVector(new double[4]{0,1,2,3});
   DoubleVector b = new DoubleVector(new double[4]{4,5,6,7});
   
   Assert.AreEqual(a.GetNorm(),System.Math.Sqrt(14));
   Assert.AreEqual(a.GetNorm(),a.GetNorm(2));
   Assert.AreEqual(a.GetNorm(0),3);
   
   Assert.AreEqual(b.GetNorm(),3*System.Math.Sqrt(14));
   Assert.AreEqual(b.GetNorm(),b.GetNorm(2));
   Assert.AreEqual(b.GetNorm(0),7);  
 }