使用特征类对向量中的某些数字求和

时间:2017-04-04 02:22:10

标签: c++ eigen

我是C ++的新手,我使用的是Eigen库。我想知道是否有办法对矢量中的某些元素求和。例如,假设我有一个100乘1的向量,我只想总结前10个元素。有没有办法使用Eigen库?

我想要做的是:说我有一个1000乘1的向量,我想取前10个元素的平均值,然后是接下来的10个元素,依此类推并将其存储在某个向量中。因此,我将得到一个平均大小为100的向量。非常感谢任何想法或建议。

以下是我的代码中的开始步骤。我的S_temp4向量是1000乘1.现在我初始化一个新的向量S_A,我想要它作为均值的向量。到目前为止,这是我凌乱的草率代码:(请注意,我的问题在于crudeMonteCarlo函数)

#include <iostream>
#include <cmath>
#include <math.h>
#include <Eigen/Dense>
#include <Eigen/Geometry>
#include <random>
#include <time.h>

using namespace Eigen;
using namespace std;

void crudeMonteCarlo(int N,double K, double r, double S0, double sigma, double T, int n);
VectorXd time_vector(double min, double max, int n);
VectorXd call_payoff(VectorXd S, double K);

int main(){
    int N = 100;
    double K = 100;
    double r = 0.2;
    double S0 = 100;
    double sigma = 0.4;
    double T = 0.1;
    int n = 10;

    crudeMonteCarlo(N,K,r,S0,sigma,T,n);

    return 0;
}

VectorXd time_vector(double min, double max, int n){
    VectorXd m(n + 1);
     double delta = (max-min)/n;
     for(int i = 0; i <= n; i++){
             m(i) = min + i*delta;
     }
    return m;
}

MatrixXd generateGaussianNoise(int M, int N){
    MatrixXd Z(M,N);
    static random_device rd;
    static mt19937 e2(time(0));
    normal_distribution<double> dist(0.0, 1.0);
    for(int i = 0; i < M; i++){
        for(int j = 0; j < N; j++){
            Z(i,j) = dist(e2);
        }
    }
    return Z;
}

VectorXd call_payoff(VectorXd S, double K){
    VectorXd C(S.size());
    for(int i = 0; i < S.size(); i++){
        if(S(i) - K > 0){
            C(i) = S(i) - K;
        }else{
            C(i) = 0.0;
        }
    }
    return C;
}

void crudeMonteCarlo(int N,double K, double r, double S0, double sigma, double T, int n){
    // Create time vector
    VectorXd tt = time_vector(0.0,T,n);
    VectorXd t(n);
    double dt = T/n;
    for(int i = 0; i < n; i++){
            t(i) = tt(i+1);
    }

    // Generate standard normal Z matrix
    //MatrixXd Z = generateGaussianNoise(N,n);

    // Generate the log normal stock process N times to get S_A for crude Monte Carlo
    MatrixXd SS(N,n+1);
    MatrixXd Z = generateGaussianNoise(N,n);
    for(int i = 0; i < N; i++){
        SS(i,0) = S0;
        for(int j = 1; j <= n; j++){
                SS(i,j) = SS(i,j-1)*exp((double) (r - pow(sigma,2.0))*dt + sigma*sqrt(dt)*(double)Z(i,j-1));
        }
    }

    // This long bit of code gives me my S_A.....
    Map<RowVectorXd> S_temp1(SS.data(), SS.size());
    VectorXd S_temp2(S_temp1.size());
    for(int i = 0; i < S_temp2.size(); i++){
        S_temp2(i) = S_temp1(i);
    }
    VectorXd S_temp3(S_temp2.size() - N);
    int count = 0;
    for(int i = N; i < S_temp2.size(); i++){
        S_temp3(count) = S_temp2(i);
        count++;
    }
    VectorXd S_temp4(S_temp3.size());
    for(int i = 0; i < S_temp4.size(); i++){
        S_temp4(i) = S_temp3(i);
    }
    VectorXd S_A(N);
    S_A(0) = (S_temp4(0) + S_temp4(1) + S_temp4(2) + S_temp4(3) + S_temp4(4) + S_temp4(5) + S_temp4(6) + S_temp4(7) + S_temp4(8) + S_temp4(9))/(n);
    S_A(1) = (S_temp4(10) + S_temp4(11) + S_temp4(12) + S_temp4(13) + S_temp4(14) + S_temp4(15) + S_temp4(16) + S_temp4(17) + S_temp4(18) + S_temp4(19))/(n);
    int count1 = 0;
    for(int i = 0; i < S_temp4.size(); i++){
        S_A(count1) = 
    }



    // Calculate payoff of Asian option
    //VectorXd call_fun = call_payoff(S_A,K);




}

3 个答案:

答案 0 :(得分:3)

这个问题包含很多代码,这使得您很难理解您要问的问题。请考虑仅包含特定于您问题的代码。

无论如何,你可以直接使用Eigen来完成所有这些事情。在Eigen中,Vectors只是一列的矩阵,所以这里的所有推理都直接适用于你所写的内容。

.block

总结:您可以使用.sum()来获取块对象,{{1}}来对该块求和,然后使用常规除法来获得均值。

答案 1 :(得分:1)

您可以使用Map重新整形输入,然后立即执行所有子求和,而不进行任何循环:

VectorXd A(1000);                           // input
Map<MatrixXd> B(A.data(), 10, A.size()/10); // reshaped version, no copy
VectorXd res = B.colwise().mean();          // partial reduction, you can also use .sum(), .minCoeff(), etc.

答案 2 :(得分:0)

https://www.w3schools.com/php/php_form_complete.asp处的Eigen文档说,Eigen块是由matrix.block(i,j,p,q)访问的矩阵或数组的矩形部分,其中i和j是起始值(例如0和0)以及p和q块大小(例如10和1)。据推测,您将以10为步长迭代i,并使用std::accumulate或可能使用显式求和来查找matrix.block(i,0,10,1)的平均值。