我是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);
}
答案 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)
的平均值。