Assembla home | Assembla project page
 

Changeset 223

Show
Ignore:
Timestamp:
07/03/08 18:44:06 (3 months ago)
Author:
snovik
Message:

New: MCAmericanEngine. Ready for the first try of monte-carlo for american options

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/QLNet/QLNet/Math/Matrix.cs

    r175 r223  
    9191            #endregion 
    9292     
    93         //! \name Algebraic operators 
    94         /*! \pre all matrices involved in an algebraic expression must have 
    95                  the same size. 
    96         */ 
    97         //@{ 
     93        #region Algebraic operators 
     94        /*! \pre all matrices involved in an algebraic expression must have the same size. */ 
    9895        public static Matrix operator +(Matrix m1, Matrix m2) { return operMatrix(ref m1, ref m2, (x, y) => x + y); } 
    9996        public static Matrix operator -(Matrix m1, Matrix m2) { return operMatrix(ref m1, ref m2, (x, y) => x - y); } 
     
    121118        } 
    122119 
    123         public static Vector operator *(Vector v, Matrix m)
     120        public static Vector operator *(Vector v, Matrix m)
    124121            if (!(v.Count == m.rows())) 
    125122                throw new ApplicationException("vectors and matrices with different sizes (" 
     
    146143                       m1.rows() + "x" + m1.columns() + ", " + 
    147144                       m2.rows() + "x" + m2.columns() + ") cannot be multiplied"); 
    148             Matrix result = new Matrix(m1.rows(),m2.columns()); 
    149             for (int i=0; i<result.rows(); i++) 
    150                 for (int j=0; j<result.columns(); j++) 
     145            Matrix result = new Matrix(m1.rows(), m2.columns()); 
     146            for (int i = 0; i < result.rows(); i++) 
     147                for (int j = 0; j < result.columns(); j++) 
    151148                    result.data_[i, j] = m1.row(i) * m2.column(j); 
    152149            return result; 
    153         } 
     150        }  
     151        #endregion 
    154152 
    155153        public static Matrix transpose(Matrix m) { 
     
    176174            return result; 
    177175        } 
     176 
     177        public void swap(int i1, int j1, int i2, int j2) { 
     178            double t = this[i2, j2]; 
     179            this[i2, j2] = this[i1, j1]; 
     180            this[i1, j1] = t; 
     181        } 
    178182    } 
    179183} 
  • trunk/QLNet/QLNet/Math/Optimization/ArmijoLineSearch.cs

    r204 r223  
    6565 
    6666            qt_ = q0; 
    67             qpt_ = (gradient_.Count == 0) ? qp0 : -Utils.DotProduct(gradient_, searchDirection_); 
     67            qpt_ = (gradient_.Count == 0) ? qp0 : -Vector.DotProduct(gradient_, searchDirection_); 
    6868 
    6969            // Initialize gradient 
     
    101101            P.gradient(gradient_, xtd_); 
    102102            // and it squared norm 
    103             qpt_ = Utils.DotProduct(gradient_, gradient_); 
     103            qpt_ = Vector.DotProduct(gradient_, gradient_); 
    104104 
    105105            // Return new step value 
  • trunk/QLNet/QLNet/Math/Optimization/ConjugateGradient.cs

    r145 r223  
    7373                        // Initialize cost function, gradient g and search direction 
    7474                        P.setFunctionValue(P.valueAndGradient(g, x_)); 
    75                        P.setGradientNormValue(Utils.DotProduct(g, g)); 
     75            P.setGradientNormValue(Vector.DotProduct(g, g)); 
    7676                        lineSearch_.searchDirection = g * -1.0; 
    7777                        // Loop over iterations 
     
    9999                                        // conjugate gradient search direction 
    100100                                        sddiff = ((g*-1.0) + c * d) - lineSearch_.searchDirection; 
    101                                        normdiff = Math.Sqrt(Utils.DotProduct(sddiff, sddiff)); 
     101                    normdiff = Math.Sqrt(Vector.DotProduct(sddiff, sddiff)); 
    102102                                        lineSearch_.searchDirection = (g*-1.0) + c * d; 
    103103                                        // Now compute accuracy and check end criteria 
  • trunk/QLNet/QLNet/Math/Optimization/LeastSquareProblem.cs

    r145 r223  
    6464            Vector diff = target - fct2fit; 
    6565            // and compute the scalar product (square of the norm) 
    66             return Utils.DotProduct(diff, diff); 
     66            return Vector.DotProduct(diff, diff); 
    6767        } 
    6868        public override Vector values(Vector x) 
     
    7575            // do the difference 
    7676            Vector diff = target - fct2fit; 
    77             return Utils.DirectMultiply(diff, diff); 
     77            return Vector.DirectMultiply(diff, diff); 
    7878        } 
    7979        //! compute vector of derivatives of the least square function 
     
    107107            grad_f = -2.0 * (Matrix.transpose(grad_fct2fit) * diff); 
    108108            // and compute the scalar product (square of the norm) 
    109             return Utils.DotProduct(diff, diff); 
     109            return Vector.DotProduct(diff, diff); 
    110110        } 
    111111    } 
  • trunk/QLNet/QLNet/Math/Optimization/Simplex.cs

    r146 r223  
    3636            { 
    3737                Vector temp = vertices[i] - center; 
    38                 result += Math.Sqrt(Utils.DotProduct(temp, temp)); 
     38                result += Math.Sqrt(Vector.DotProduct(temp, temp)); 
    3939            } 
    4040            return result / (double)(vertices.Count); 
  • trunk/QLNet/QLNet/Math/Optimization/SteepestDescent.cs

    r145 r223  
    6161            P.setFunctionValue(P.valueAndGradient(gold, x_)); 
    6262            lineSearch_.searchDirection = gold*-1.0; 
    63             P.setGradientNormValue(Utils.DotProduct(gold, gold)); 
     63            P.setGradientNormValue(Vector.DotProduct(gold, gold)); 
    6464            normdiff = Math.Sqrt(P.gradientNormValue()); 
    6565 
     
    8484                // New gradient and search direction vectors 
    8585                gdiff = gold - lineSearch_.lastGradient(); 
    86                 normdiff = Math.Sqrt(Utils.DotProduct(gdiff, gdiff)); 
     86                normdiff = Math.Sqrt(Vector.DotProduct(gdiff, gdiff)); 
    8787                gold = lineSearch_.lastGradient(); 
    8888                lineSearch_.searchDirection = gold*-1.0; 
  • trunk/QLNet/QLNet/Math/Vector.cs

    r192 r223  
    125125        //public static double operator /(Vector v1, Vector v2) { return operVector(ref v1, ref v2, (x, y) => x / y); } 
    126126        #endregion 
    127     } 
    128127 
    129     public static partial class Utils { 
     128 
     129        #region Vector utils 
    130130        // dot product. It is already overloaded in the vector. Thus for compatibility only 
    131         public static double DotProduct(Vector v1, Vector v2) { 
     131        public static double DotProduct(Vector v1, Vector v2) { 
    132132            return v1 * v2; 
    133133        } 
    134134 
    135         public static Vector DirectMultiply(Vector v1, Vector v2) 
    136         { 
     135        public static Vector DirectMultiply(Vector v1, Vector v2) { 
    137136            return Vector.operVector(v1, v2, (x, y) => x * y); 
    138137        } 
    139138 
     139        public static Vector Sqrt(Vector v) { 
     140            Vector result = new Vector(v.size()); 
     141            result.ForEach((i, x) => result[i] = Math.Sqrt(v[i])); 
     142            return result; 
     143        } 
     144 
     145        public void swap(int i1, int i2) { 
     146            double t = this[i2]; 
     147            this[i2] = this[i1]; 
     148            this[i1] = t; 
     149        } 
     150        #endregion 
    140151    } 
    141152} 
  • trunk/QLNet/QLNet/Methods/Finitedifferences/TridiagonalOperator.cs

    r155 r223  
    127127            // transform(InputIterator1 start1, InputIterator1 finish1, InputIterator2 start2, OutputIterator result, 
    128128            // BinaryOperation binary_op) 
    129             result = Utils.DirectMultiply(diagonal_, v); 
     129            result = Vector.DirectMultiply(diagonal_, v); 
    130130 
    131131            // matricial product 
  • trunk/QLNet/QLNet/Methods/lattices/lattice.cs

    r123 r223  
    100100        public override double presentValue(DiscretizedAsset asset) { 
    101101            int i = t_.index(asset.time()); 
    102             return Utils.DotProduct(asset.values(), statePrices(i)); 
     102            return Vector.DotProduct(asset.values(), statePrices(i)); 
    103103        } 
    104104 
  • trunk/QLNet/QLNet/Methods/montecarlo/earlyexercisepathpricer.cs

    r198 r223  
    2828        \ingroup mcarlo 
    2929    */ 
     30 
     31    public static class EarlyExerciseTraits<PathType> where PathType : Path { 
     32        //typedef Real StateType; 
     33        public static int pathLength(PathType path) { return path.length(); } 
     34    } 
     35 
     36 
    3037    // template<class PathType, class TimeType=Size, class ValueType=Real> 
    3138    public interface EarlyExercisePathPricer<PathType> { 
    3239        // typedef typename EarlyExerciseTraits<PathType>::StateType StateType; 
    3340 
    34         double value(PathType path, double t); 
     41        double value(PathType path, int t); 
    3542 
    36         double state(PathType path, double t); 
    37         List<IValue> basisSystem(); 
     43        double state(PathType path, int t); 
     44        List<Func<double, double>> basisSystem(); 
    3845    } 
    3946} 
  • trunk/QLNet/QLNet/Methods/montecarlo/longstaffschwartzpathpricer.cs

    r198 r223  
    3535              reproducing results available in web/literature 
    3636    */ 
    37     public abstract class LongstaffSchwartzPathPricer<PathType> : PathPricer<PathType> where PathType : Path { 
     37    public class LongstaffSchwartzPathPricer<PathType> : PathPricer<PathType> where PathType : Path { 
    3838        protected bool  calibrationPhase_; 
    3939        protected EarlyExercisePathPricer<PathType> pathPricer_; 
     
    4343 
    4444        protected List<PathType> paths_; 
    45         protected List<IValue> v_; 
     45        protected List<Func<double, double>> v_; 
    4646 
     47        public LongstaffSchwartzPathPricer(TimeGrid times, EarlyExercisePathPricer<PathType> pathPricer, 
     48                                           YieldTermStructure termStructure) { 
     49            calibrationPhase_ = true; 
     50            pathPricer_ = pathPricer; 
     51            coeff_ = new InitializedList<Vector>(times.size()-1); 
     52            dF_ = new InitializedList<double>(times.size()-1); 
     53            v_ = pathPricer_.basisSystem(); 
     54 
     55            for (int i=0; i<times.size()-1; ++i) { 
     56                dF_[i] =   termStructure.discount(times[i+1]) 
     57                         / termStructure.discount(times[i]); 
     58            } 
     59        } 
    4760         
     61 
     62        public override double value(PathType path) { 
     63            if (calibrationPhase_) { 
     64                // store paths for the calibration 
     65                paths_.Add(path); 
     66                // result doesn't matter 
     67                return 0.0; 
     68            } 
     69 
     70            int len = EarlyExerciseTraits<PathType>.pathLength(path); 
     71            double price = pathPricer_.value(path, len-1); 
     72            for (int i = len - 2; i > 0; --i) { 
     73                price*=dF_[i]; 
     74 
     75                double exercise = pathPricer_.value(path, i); 
     76                if (exercise > 0.0) { 
     77                    double regValue  = pathPricer_.state(path, i); 
     78 
     79                    double continuationValue = 0.0; 
     80                    for (int l = 0; l < v_.Count; ++l) { 
     81                        continuationValue += coeff_[i][l] * v_[l](regValue); 
     82                    } 
     83 
     84                    if (continuationValue < exercise) { 
     85                        price = exercise; 
     86                    } 
     87                } 
     88            } 
     89 
     90            return price*dF_[0]; 
     91        } 
     92 
    4893        public void calibrate() { 
    49             //const int n = paths_.size()
    50             //Vector prices = new Vector(n), exercise = new Vector(n); 
    51             //const int len = EarlyExerciseTraits<PathType>::pathLength(paths_[0]); 
     94            int n = paths_.Count
     95            Vector prices = new Vector(n), exercise = new Vector(n); 
     96            int len = EarlyExerciseTraits<PathType>.pathLength(paths_[0]); 
    5297 
    53             //std::transform(paths_.begin(), paths_.end(), prices.begin(), 
    54             //               boost::bind(&EarlyExercisePathPricer<PathType> 
    55             //                             ::operator(), 
    56             //                           pathPricer_.get(), _1, len-1)); 
     98            for(int i = 0; i<paths_.Count; i++) 
     99                prices[i] = pathPricer_.value(paths_[i], len-1); 
    57100 
    58             //for (Size i=len-2; i>0; --i) { 
    59             //    std::vector<Real>      y
    60             //    std::vector<StateType> x
     101            for (int i=len-2; i>0; --i) { 
     102                List<double> y = new List<double>()
     103                List<double> x = new List<double>()
    61104 
    62             //    //roll back step 
    63             //    for (Size j=0; j<n; ++j) { 
    64             //        exercise[j]=(*pathPricer_)(paths_[j], i); 
     105                //roll back step 
     106                for (int j=0; j<n; ++j) { 
     107                    exercise[j]=pathPricer_.value(paths_[j], i); 
    65108 
    66             //        if (exercise[j]>0.0) { 
    67             //            x.push_back(pathPricer_->state(paths_[j], i)); 
    68             //            y.push_back(dF_[i]*prices[j]); 
    69             //        } 
    70             //    } 
     109                    if (exercise[j]>0.0) { 
     110                        x.Add(pathPricer_.state(paths_[j], i)); 
     111                        y.Add(dF_[i]*prices[j]); 
     112                    } 
     113                } 
    71114 
    72             //    if (v_.size() <=  x.size()) { 
    73             //        coeff_[i] 
    74             //            = LinearLeastSquaresRegression<StateType>(x, y, v_).a(); 
    75             //    } 
    76             //    else { 
    77             //    // if number of itm paths is smaller then the number of 
    78             //    // calibration functions -> no early exercise 
    79             //        coeff_[i] = Array(v_.size(), 0.0); 
    80             //    } 
     115                if (v_.Count <= x.Count) { 
     116                    coeff_[i] = new LinearLeastSquaresRegression<double>(x, y, v_).a(); 
     117                } 
     118                else { 
     119                // if number of itm paths is smaller then the number of 
     120                // calibration functions -> no early exercise 
     121                    coeff_[i] = new Vector(v_.Count); 
     122                } 
    81123 
    82             //    for (Size j=0, k=0; j<n; ++j) { 
    83             //        prices[j]*=dF_[i]; 
    84             //        if (exercise[j]>0.0) { 
    85             //            Real continuationValue = 0.0; 
    86             //            for (Size l=0; l<v_.size(); ++l) { 
    87             //                continuationValue += coeff_[i][l] * v_[l](x[k]); 
    88             //            } 
    89             //            if (continuationValue < exercise[j]) { 
    90             //                prices[j] = exercise[j]; 
    91             //            } 
    92             //            ++k; 
    93             //        } 
    94             //    } 
    95             //
     124                for (int j=0, k=0; j<n; ++j) { 
     125                    prices[j]*=dF_[i]; 
     126                    if (exercise[j]>0.0) { 
     127                        double continuationValue = 0.0; 
     128                        for (int l = 0; l < v_.Count; ++l) { 
     129                            continuationValue += coeff_[i][l] * v_[l](x[k]); 
     130                        } 
     131                        if (continuationValue < exercise[j]) { 
     132                            prices[j] = exercise[j]; 
     133                        } 
     134                        ++k; 
     135                    } 
     136                } 
     137           
    96138 
    97             //// remove calibration paths 
    98             //paths_.clear(); 
    99             //// entering the calculation phase 
    100             //calibrationPhase_ = false; 
     139            // remove calibration paths 
     140            paths_.Clear(); 
     141            // entering the calculation phase 
     142            calibrationPhase_ = false; 
    101143        } 
    102144    } 
  • trunk/QLNet/QLNet/Pricingengines/vanilla/mcamericanengine.cs

    r198 r223  
    3131              reproducing results available in web/literature 
    3232    */ 
    33     public class MCAmericanEngine<RNG, S> { 
     33    public class MCAmericanEngine<RNG, S> : MCLongstaffSchwartzEngine<VanillaOption.Engine, SingleVariate, RNG, S> 
     34        where RNG : IRSG, new() 
     35        where S : IGeneralStatistics, new() { 
     36 
     37        private int polynomOrder_; 
     38        private LsmBasisSystem.PolynomType polynomType_; 
     39 
     40        //     int nCalibrationSamples = Null<Size>())  
     41        public MCAmericanEngine(GeneralizedBlackScholesProcess process, int timeSteps, int timeStepsPerYear, 
     42             bool antitheticVariate, bool controlVariate, int requiredSamples, double requiredTolerance, 
     43             int maxSamples, ulong seed, int polynomOrder, LsmBasisSystem.PolynomType polynomType, 
     44             int nCalibrationSamples)  
     45            : base(process, timeSteps, timeStepsPerYear, false, antitheticVariate, controlVariate, requiredSamples, 
     46                   requiredTolerance, maxSamples, seed, nCalibrationSamples) { 
     47            polynomOrder_ = polynomOrder; 
     48            polynomType_ = polynomType; 
     49        } 
     50 
     51 
     52        protected override LongstaffSchwartzPathPricer<Path> lsmPathPricer() { 
     53            GeneralizedBlackScholesProcess process = process_ as GeneralizedBlackScholesProcess; 
     54            if (process == null) 
     55                throw new ApplicationException("generalized Black-Scholes process required"); 
     56 
     57            EarlyExercise exercise = arguments_.exercise as EarlyExercise; 
     58            if (exercise == null) 
     59                throw new ApplicationException("wrong exercise given"); 
     60            if(exercise.payoffAtExpiry()) 
     61                throw new ApplicationException("payoff at expiry not handled"); 
     62 
     63            AmericanPathPricer earlyExercisePathPricer = new AmericanPathPricer(arguments_.payoff, polynomOrder_, polynomType_); 
     64 
     65            return new LongstaffSchwartzPathPricer<Path>(timeGrid(), earlyExercisePathPricer, process.riskFreeRate()); 
     66        } 
     67 
     68        protected override double controlVariateValue() { 
     69            IPricingEngine controlPE = controlPricingEngine(); 
     70 
     71            if (controlPE == null) 
     72                throw new ApplicationException("engine does not provide control variation pricing engine"); 
     73 
     74            VanillaOption.Arguments controlArguments = controlPE.getArguments() as VanillaOption.Arguments; 
     75            controlArguments = arguments_; 
     76            controlArguments.exercise = new EuropeanExercise(arguments_.exercise.lastDate()); 
     77 
     78            controlPE.calculate(); 
     79 
     80            VanillaOption.Results controlResults = controlPE.getResults() as VanillaOption.Results; 
     81 
     82            return controlResults.value.GetValueOrDefault(); 
     83        } 
     84 
     85        protected override IPricingEngine controlPricingEngine() { 
     86            GeneralizedBlackScholesProcess process = process_ as GeneralizedBlackScholesProcess; 
     87            if (process == null) 
     88                throw new ApplicationException("generalized Black-Scholes process required"); 
     89 
     90            return new AnalyticEuropeanEngine(process); 
     91        } 
     92 
     93        protected override PathPricer<Path> controlPathPricer() { 
     94            StrikedTypePayoff payoff = arguments_.payoff as StrikedTypePayoff; 
     95            if(payoff == null) 
     96                throw new ApplicationException("StrikedTypePayoff needed for control variate"); 
     97 
     98            GeneralizedBlackScholesProcess process = process_ as GeneralizedBlackScholesProcess; 
     99            if (process == null) 
     100                throw new ApplicationException("generalized Black-Scholes process required"); 
     101 
     102            return new EuropeanPathPricer(payoff.optionType(), payoff.strike(), 
     103                                          process.riskFreeRate().link.discount(timeGrid().Last())); 
     104        } 
    34105    } 
     106 
     107 
     108    public class AmericanPathPricer : EarlyExercisePathPricer<Path>  { 
     109        protected double scalingValue_; 
     110        protected Payoff payoff_; 
     111        protected List<Func<double, double>> v_ = new List<Func<double,double>>(); 
     112 
     113        public AmericanPathPricer(Payoff payoff, int polynomOrder, LsmBasisSystem.PolynomType polynomType) { 
     114            scalingValue_ = 1; 
     115            payoff_ = payoff; 
     116            v_ = LsmBasisSystem.pathBasisSystem(polynomOrder, polynomType); 
     117 
     118            if (!(polynomType == LsmBasisSystem.PolynomType.Monomial 
     119                  || polynomType == LsmBasisSystem.PolynomType.Laguerre 
     120                  || polynomType == LsmBasisSystem.PolynomType.Hermite 
     121                  || polynomType == LsmBasisSystem.PolynomType.Hyperbolic 
     122                  || polynomType == LsmBasisSystem.PolynomType.Chebyshev2th)) 
     123                throw new ApplicationException("insufficient polynom type"); 
     124 
     125            // the payoff gives an additional value 
     126            v_.Add(payoff.value); 
     127 
     128            StrikedTypePayoff strikePayoff = payoff_ as StrikedTypePayoff; 
     129 
     130            if (strikePayoff != null) { 
     131                scalingValue_/=strikePayoff.strike(); 
     132            } 
     133        } 
     134 
     135        // scale values of the underlying to increase numerical stability 
     136        public double state(Path path, int t) { return path[t]*scalingValue_; } 
     137        public double value(Path path, int t) { return payoff(state(path, t)); } 
     138        public List<Func<double, double>> basisSystem() { return v_; } 
     139 
     140        protected double payoff(double state) { return state/scalingValue_; } 
     141    } 
     142 
    35143 
    36144    //! Monte Carlo American engine factory 
    37145    //template <class RNG = PseudoRandom, class S = Statistics> 
    38     public class MakeMCAmericanEngine<RNG, S> { 
     146    public class MakeMCAmericanEngine<RNG, S> 
     147        where RNG : IRSG, new() 
     148        where S : IGeneralStatistics, new() { 
     149 
     150        private GeneralizedBlackScholesProcess process_; 
     151        private bool antithetic_, controlVariate_; 
     152        private int steps_, stepsPerYear_; 
     153        private int samples_, maxSamples_, calibrationSamples_; 
     154        private double tolerance_; 
     155        private ulong seed_; 
     156        private int polynomOrder_; 
     157        private LsmBasisSystem.PolynomType polynomType_; 
     158 
     159        public MakeMCAmericanEngine(GeneralizedBlackScholesProcess process) { 
     160            process_ = process; 
     161            antithetic_ = false; 
     162            controlVariate_ = false; 
     163            steps_ = 0; 
     164            stepsPerYear_ = 0; 
     165            samples_ = 0; 
     166            maxSamples_ = 0; 
     167            calibrationSamples_ = 2048; 
     168            tolerance_ = 0; 
     169            seed_ = 0; 
     170            polynomOrder_ = 2; 
     171            polynomType_ = LsmBasisSystem.PolynomType.Monomial; 
     172        } 
     173         
     174        // named parameters 
     175        public MakeMCAmericanEngine<RNG, S> withSteps(int steps) { 
     176            steps_ = steps; 
     177            return this; 
     178        } 
     179        public MakeMCAmericanEngine<RNG, S> withStepsPerYear(int steps) { 
     180            stepsPerYear_ = steps; 
     181            return this; 
     182        } 
     183        public MakeMCAmericanEngine<RNG, S> withSamples(int samples) { 
     184            if (tolerance_ != 0) 
     185                throw new ApplicationException("tolerance already set"); 
     186            samples_ = samples; 
     187            return this; 
     188        } 
     189        public MakeMCAmericanEngine<RNG, S> withTolerance(double tolerance) { 
     190            if (samples_ != 0) 
     191                throw new ApplicationException("number of samples already set"); 
     192 
     193            if (new RNG().allowsErrorEstimate == 0) 
     194                throw new ApplicationException("chosen random generator policy does not allow an error estimate"); 
     195            tolerance_ = tolerance; 
     196            return this; 
     197        } 
     198        public MakeMCAmericanEngine<RNG, S> withMaxSamples(int samples) { 
     199            maxSamples_ = samples; 
     200            return this; 
     201        } 
     202        public MakeMCAmericanEngine<RNG, S> withSeed(ulong seed) { 
     203            seed_ = seed; 
     204            return this; 
     205        } 
     206        //public MakeMCAmericanEngine withAntitheticVariate(bool b = true); b) { 
     207        public MakeMCAmericanEngine<RNG, S> withAntitheticVariate(bool b) { 
     208            antithetic_ = b; 
     209            return this; 
     210        } 
     211        //public MakeMCAmericanEngine withControlVariate(bool b = true); 
     212        public MakeMCAmericanEngine<RNG, S> withControlVariate(bool b) { 
     213            controlVariate_ = b; 
     214            return this; 
     215        } 
     216        public MakeMCAmericanEngine<RNG, S> withPolynomOrder(int polynomOrder) { 
     217            polynomOrder_ = polynomOrder; 
     218            return this; 
     219        } 
     220        public MakeMCAmericanEngine<RNG, S> withBasisSystem(LsmBasisSystem.PolynomType polynomType) { 
     221            polynomType_ = polynomType; 
     222            return this; 
     223        } 
     224        public MakeMCAmericanEngine<RNG, S> withCalibrationSamples(int samples) { 
     225            calibrationSamples_ = samples; 
     226            return this; 
     227        } 
     228 
     229        // conversion to pricing engine 
     230        public IPricingEngine value() { 
     231            if (!(steps_ != 0 || stepsPerYear_ != 0)) 
     232                throw new ApplicationException("number of steps not given"); 
     233            if (!(steps_ == 0 || stepsPerYear_ == 0)) 
     234                throw new ApplicationException("number of steps overspecified"); 
     235            return new MCAmericanEngine<RNG, S>(process_, steps_, stepsPerYear_, antithetic_, controlVariate_, samples_, tolerance_, 
     236                                                maxSamples_, seed_, polynomOrder_, polynomType_, calibrationSamples_); 
     237        } 
    39238    } 
    40239} 
  • trunk/QLNet/QLNet/QLNet.csproj

    r222 r223  
    157157    <Compile Include="Math\Interpolations\multicubicspline.cs" /> 
    158158    <Compile Include="Math\Interpolations\sabrinterpolation.cs" /> 
     159    <Compile Include="Math\linearleastsquaresregression.cs" /> 
    159160    <Compile Include="Math\Matrix.cs" /> 
     161    <Compile Include="Math\matrixutilities\svd.cs" /> 
    160162    <Compile Include="Math\Optimization\ArmijoLineSearch.cs" /> 
    161163    <Compile Include="Math\Optimization\ConjugateGradient.cs" /> 
  • trunk/QLNet/QLNet/Utils.cs

    r214 r223  
    5656        } 
    5757 
     58        public static void swap(ref double a1, ref double a2) { swap<double>(ref a1, ref a2); } 
    5859        public static void swap<T>(ref T a1, ref T a2) { 
    5960            T t = a2;