簡體   English   中英

C#類中向量的雙重聲明和初始化

[英]Double declaration and initialization of vector in a class C#

如何正確地使這個向量雙重聲明?

var asset = new Vector<double>(new double[2 * N + 1], -N)
         
asset[-N] = S * Math.Exp(-N * dx);

在定義中: asset[-N] = S * Math.Exp(-N * dx); 顯示錯誤

無法分配屬性或索引器“Vectorthis.[int]”,因為它是只讀的。

編譯器錯誤 CS0200 - 無法將屬性或索引器“屬性”分配給——它是只讀的

完整代碼如下:

using System;
using System.Numerics;

namespace TrinomialTree
{
    public class TrinomialTree
    {
        TrinomialParameters par;
        public TrinomialTree(TrinomialParameters pars)
        {
            this.par = pars;
            // Your program starts here:
            Console.WriteLine("Hello world!");

            // Declare and initialize the parameters
            TrinomialParameters myData;
            // Clewlow p. 55 C = 8.42534 for N = 3
            myData.sigma = 0.2;
            myData.T = 1.0; // One year
            myData.r = 0.06;
            myData.K = 100;
            myData.div = 0.0;
            myData.type = 'C';
            myData.exercise = false;
            myData.NumberOfSteps = 3;
            Console.WriteLine("How many timesteps: ");
            myData.NumberOfSteps = Convert.ToInt32(Console.ReadLine());
            // Now define option-related calculations and price
            TrinomialTree myTree = new TrinomialTree(myData);
            Console.WriteLine("Price {0}", myTree.Price(100));
        }

        double Price(int strike)
        {
            int N = 2;
            int S = strike;

            Vector<Vector<double>> option;

            double sig2 = par.sigma * par.sigma;
            double dt = par.T / N;
            double nu = par.r - par.div - 0.5 * sig2;
            // Since trinomial is explicit FDM we have a constraint between
            // dt and dx (Clewlow inequality (3.27))
            double dx = par.sigma * Math.Sqrt(3.0 * dt) + dt * 1;
            double edx = Math.Exp(dx);
            // Initialize asset prices at *maturity*.
            // Notice that the start index is a negative number
            
            var asset = new Vector<double>(new double[2 * N + 1], -N);

            //Vector<double> asset = new Vector<double>(2 * N + 1, -N);

            //var x = new Vector<double>(new double[2 * N + 1], -N);

            asset[-N] = S * Math.Exp(-N * dx);

            for (int n = -N + 1; n <= N; n++)
            {
                asset[n] = asset[n - 1] * edx;
            }
            // Initialize option values at maturity.
            int minIndex = 0;
            option = new Vector<Vector<double>>(N + 1, minIndex);

            for (int n = N; n >= 0; n--)
            {
                for (int j = -n; j <= n; j++)
                {
                    option[n] = new Vector<double>(2 * n + 1, -n);
                }
            }
            int nn = N;
            if (par.type == 'C')
            {
                for (int j = -nn; j <= nn; j++)
                {
                    option[nn][j] = Math.Max(0.0, asset[j] - par.K);
                }

            }

            // Step back through lattice, start from maturity as given value at n = N.
            // European option
            if (par.exercise == false)
            {
                for (int n = N - 1; n >= 0; n--)
                {
                    for (int j = -n; j <= n; j++)
                    { // eq. 10.6
                        option[n][j] = disc * (pu * option[n + 1][j + 1] + pm * option[n + 1][j]
                        + pd * option[n + 1][j - 1]);
                    }
                }
            }
            else // American put only.
            {
                double tmp;
                for (int n = N - 1; n >= 0; n--)
                {
                    for (int j = -n; j <= n; j++)
                    { // eq. 10.6
                        tmp = disc * (pu * option[n + 1][j + 1] + pm * option[n + 1][j]
                        + pd * option[n + 1][j - 1]);
                        // American correction term
                        option[n][j] = Math.Max(tmp, par.K - asset[j]);
                    }
                }
            }

            return option[0][0];
        }

        public struct TrinomialParameters
        {
            // Option data
            public double sigma;
            public double T;
            public double r;
            public double K;
            public double div; // Dividend
            public char type; // 'C' or 'P'
            public bool exercise; // false if European, true if American
                                  // 'Numeric' data
            public int NumberOfSteps; // Nr. of subdivisions of [0, T]
        }
    }

}

您可能想使用List<T>而不是Vector<T> 后者旨在優化 SIMD 操作,而不是作為通用動態數組。 List<T>將等效於 c++ 向量。

但是由於我看不到您正在添加任何值,因此您不妨使用鋸齒狀數組多維數組 或者我的偏好,包裝一維數組但提供二維索引的自定義類。

即使您想要 SIMD 優化,也可能有人認為Vector<T>不是很有效。 本文將Vector<T>與 SIMD intrinstics 進行比較 Vector<T>版本僅快 30% 左右,遠未達到理論上的 4 倍加速。 內在版本更接近理論改進。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM