QLNet.TridiagonalOperator.setLastRow C# (CSharp) Метод

setLastRow() публичный Метод

public setLastRow ( double valA, double valB ) : void
valA double
valB double
Результат void
        public void setLastRow(double valA, double valB)
        {
            lowerDiagonal_[size() - 2] = valA;
            diagonal_[size() - 1] = valB;
        }

Usage Example

Пример #1
0
      public override void update()
      {
         TridiagonalOperator L = new TridiagonalOperator(cH_.n_);

         Array<double> tmp = new Array<double>(cH_.n_);
         var dx = new Array<double>(cH_.n_ - 1);
         var S = new Array<double>(cH_.n_ - 1);

         int i=0;
         dx[i] = this.xBegin_[i+1] - this.xBegin_[i];
         S[i] = (this.yBegin_[i+1] - this.yBegin_[i])/dx[i];
         for (i=1; i<cH_.n_-1; ++i) {
           dx[i] = this.xBegin_[i+1] - this.xBegin_[i];
           S[i] = (this.yBegin_[i+1] - this.yBegin_[i])/dx[i];

           L.setMidRow(i, dx[i], 2.0*(dx[i]+dx[i-1]), dx[i-1]);
           tmp[i] = 3.0*(dx[i]*S[i-1] + dx[i-1]*S[i]);
         }

         /**** BOUNDARY CONDITIONS ****/

         // left condition
         switch (leftType_) 
         {
            case CubicSplineInterpolation.BoundaryCondition.NotAKnot:
              // ignoring end condition value
              L.setFirstRow(dx[1]*(dx[1]+dx[0]),
                            (dx[0]+dx[1])*(dx[0]+dx[1]));
              tmp[0] = S[0]*dx[1]*(2.0*dx[1]+3.0*dx[0]) +
                       S[1]*dx[0]*dx[0];
              break;
            case CubicSplineInterpolation.BoundaryCondition.FirstDerivative:
              L.setFirstRow(1.0, 0.0);
              tmp[0] = leftValue_;
              break;
            case CubicSplineInterpolation.BoundaryCondition.SecondDerivative:
              L.setFirstRow(2.0, 1.0);
              tmp[0] = 3.0*S[0] - leftValue_*dx[0]/2.0;
              break;
            case CubicSplineInterpolation.BoundaryCondition.Periodic:
            case CubicSplineInterpolation.BoundaryCondition.Lagrange:
              // ignoring end condition value
              throw new ApplicationException("this end condition is not implemented yet");
            default:
              throw new ApplicationException("unknown end condition");
         }

         // right condition
         switch (rightType_) 
         {
            case CubicSplineInterpolation.BoundaryCondition.NotAKnot:
              // ignoring end condition value
              L.setLastRow(-(dx[cH_.n_-2]+dx[cH_.n_-3])*(dx[cH_.n_-2]+dx[cH_.n_-3]),
                           -dx[cH_.n_-3]*(dx[cH_.n_-3]+dx[cH_.n_-2]));
              tmp[cH_.n_-1] = -S[cH_.n_-3]*dx[cH_.n_-2]*dx[cH_.n_-2] -
                           S[cH_.n_-2]*dx[cH_.n_-3]*(3.0*dx[cH_.n_-2]+2.0*dx[cH_.n_-3]);
              break;
            case CubicSplineInterpolation.BoundaryCondition.FirstDerivative:
              L.setLastRow(0.0, 1.0);
              tmp[cH_.n_-1] = rightValue_;
              break;
            case CubicSplineInterpolation.BoundaryCondition.SecondDerivative:
              L.setLastRow(1.0, 2.0);
              tmp[cH_.n_-1] = 3.0*S[cH_.n_-2] + rightValue_*dx[cH_.n_-2]/2.0;
              break;
            case CubicSplineInterpolation.BoundaryCondition.Periodic:
            case CubicSplineInterpolation.BoundaryCondition.Lagrange:
              // ignoring end condition value
              throw new ApplicationException("this end condition is not implemented yet");
            default:
              throw new ApplicationException("unknown end condition");
         }

         // solve the system
         tmp = L.solveFor(tmp);

         for (int j = 0; i < cH_.monotonicityAdjustments_.Count; j++ )
            cH_.monotonicityAdjustments_[j] = false;

         if (constrained_) 
         {
           double correction;
           double pm, pu, pd, M;
           for (i=0; i<cH_.n_; ++i) {
               if (i==0) {
                   if (tmp[i]*S[0]>0.0) 
                   {
                       correction = tmp[i]/Math.Abs(tmp[i]) *
                           Math.Min(Math.Abs(tmp[i]),
                                    Math.Abs(3.0*S[0]));
                   } 
                   else 
                   {
                       correction = 0.0;
                   }
                   if (correction!=tmp[i]) 
                   {
                       tmp[i] = correction;
                       cH_.monotonicityAdjustments_[i] = true;
                   }
               } 
               else if (i==cH_.n_-1) 
               {
                  if (tmp[i]*S[cH_.n_-2]>0.0) 
                   {
                       correction = tmp[i]/Math.Abs(tmp[i]) *
                           Math.Min(Math.Abs(tmp[i]),
                                    Math.Abs(3.0*S[cH_.n_-2]));
                   } 
                   else 
                   {
                       correction = 0.0;
                   }
                   if (correction!=tmp[i]) 
                   {
                       tmp[i] = correction;
                       cH_.monotonicityAdjustments_[i] = true;
                   }
               } 
               else 
               {
                   pm=(S[i-1]*dx[i]+S[i]*dx[i-1])/
                       (dx[i-1]+dx[i]);
                   M = 3.0 * Math.Min(Math.Min(Math.Abs(S[i-1]),
                                               Math.Abs(S[i])),
                                      Math.Abs(pm));
                   if (i>1) 
                   {
                       if ((S[i-1]-S[i-2])*(S[i]-S[i-1])>0.0) 
                       {
                           pd=(S[i-1]*(2.0*dx[i-1]+dx[i-2])
                               -S[i-2]*dx[i-1])/
                               (dx[i-2]+dx[i-1]);
                           if (pm*pd>0.0 && pm*(S[i-1]-S[i-2])>0.0) 
                           {
                               M = Math.Max(M, 1.5*Math.Min(
                                       Math.Abs(pm),Math.Abs(pd)));
                           }
                       }
                   }
                   if (i<cH_.n_-2) 
                   {
                       if ((S[i]-S[i-1])*(S[i+1]-S[i])>0.0) 
                       {
                           pu=(S[i]*(2.0*dx[i]+dx[i+1])-S[i+1]*dx[i])/
                               (dx[i]+dx[i+1]);
                           if (pm*pu>0.0 && -pm*(S[i]-S[i-1])>0.0) 
                           {
                               M = Math.Max(M, 1.5*Math.Min(
                                       Math.Abs(pm),Math.Abs(pu)));
                           }
                       }
                   }
                   if (tmp[i]*pm>0.0) 
                   {
                       correction = tmp[i]/Math.Abs(tmp[i]) *
                           Math.Min(Math.Abs(tmp[i]), M);
                   } 
                   else 
                   {
                       correction = 0.0;
                   }
                   if (correction!=tmp[i]) 
                   {
                       tmp[i] = correction;
                       cH_.monotonicityAdjustments_[i] = true;
                   }
               }
           }
         }

         for (i=0; i<cH_.n_-1; ++i) 
         {
           cH_.a_[i] = tmp[i];
           cH_.b_[i] = (3.0*S[i] - tmp[i+1] - 2.0*tmp[i])/dx[i];
           cH_.c_[i] = (tmp[i+1] + tmp[i] - 2.0*S[i])/(dx[i]*dx[i]);
         }

         cH_.primitiveConst_[0] = 0.0;
         for (i=1; i<cH_.n_-1; ++i) 
         {
           cH_.primitiveConst_[i] = cH_.primitiveConst_[i-1]
               + dx[i-1] *
               (this.yBegin_[i-1] + dx[i-1] *
                (cH_.a_[i-1]/2.0 + dx[i-1] *
                 (cH_.b_[i-1]/3.0 + dx[i-1] * cH_.c_[i-1]/4.0)));
         }
      }
All Usage Examples Of QLNet.TridiagonalOperator::setLastRow