首页 \ 问答 \ #inf c ++ visual studio(#inf c++ visual studio)

#inf c ++ visual studio(#inf c++ visual studio)

我在计算双重总和时遇到了问题。 当我将迭代设置为100000时,函数Asian_call_MC仍然返回一个数字。 但是,当我将迭代设置为大约500000及以上时,它开始返回1.#INF。 有人能告诉我它为什么会发生以及如何解决它? 我正在使用visual studio 2013来编写c ++代码。

double Avg_Price(double init_p, double impl_vol, double drift, int step, double deltasqrt)
{
//Calculate the average price of one sample path
//delta  = T/ step
//drift = (risk_free - div_y - impl_vol*impl_vol / 2)*(T / step)
double Sa = 0.0;
double St = init_p;

for (int i = 0; i < step; i++)
{
    St = St*exp(drift + impl_vol*deltasqrt*normal_gen());
    //Sa = Sa * i / (i + 1) + St / (i + 1);
    Sa += St;
}
Sa = Sa / double(step);
return Sa;
}


double Asian_call_MC(double strike_p, double T, double init_p, double impl_vol, double risk_free, double div_y, int iter, int step)
{
//Calculate constants in advance to reduce computation time
double drift = (risk_free - div_y - impl_vol*impl_vol / 2)*double(T / step);
double deltasqrt = sqrt(double(T / step));


//Generate x1, average x and y
double cur_p = Avg_Price(init_p,impl_vol,drift,step,deltasqrt);
double pay_o=0.0;
double x = max(cur_p - strike_p,0.0);
//double y = pow(x, 2.0);


//Generate x2 to xn
for (int i = 0; i < iter; i++)
{
    cur_p = Avg_Price(init_p, impl_vol, drift, step, deltasqrt);
    x = max(cur_p - strike_p,0.0);
    //double q = double(i) / double(i + 1);
    //pay_o = pay_o *i/(i+1) + x / (i + 1);
    pay_o += x;
    //y = (1 - (1 / (i + 1)))*y + x*x / (i + 1);
}
//pay_o = pay_o / double(iter);
//stdev = sqrt((y - pow(pay_o , 2)) / (iter - 1));
//return pay_o*exp(-risk_free*T) ;
return pay_o;
}

I came across question in calculating the sum of a double. When I set iteration to 100000, the function Asian_call_MC still return a number. However, when I set iteration to around 500000 and above, it begin to return 1.#INF. Can someone tell me why it happens and how to solve it? I am using visual studio 2013 to write c++ code.

double Avg_Price(double init_p, double impl_vol, double drift, int step, double deltasqrt)
{
//Calculate the average price of one sample path
//delta  = T/ step
//drift = (risk_free - div_y - impl_vol*impl_vol / 2)*(T / step)
double Sa = 0.0;
double St = init_p;

for (int i = 0; i < step; i++)
{
    St = St*exp(drift + impl_vol*deltasqrt*normal_gen());
    //Sa = Sa * i / (i + 1) + St / (i + 1);
    Sa += St;
}
Sa = Sa / double(step);
return Sa;
}


double Asian_call_MC(double strike_p, double T, double init_p, double impl_vol, double risk_free, double div_y, int iter, int step)
{
//Calculate constants in advance to reduce computation time
double drift = (risk_free - div_y - impl_vol*impl_vol / 2)*double(T / step);
double deltasqrt = sqrt(double(T / step));


//Generate x1, average x and y
double cur_p = Avg_Price(init_p,impl_vol,drift,step,deltasqrt);
double pay_o=0.0;
double x = max(cur_p - strike_p,0.0);
//double y = pow(x, 2.0);


//Generate x2 to xn
for (int i = 0; i < iter; i++)
{
    cur_p = Avg_Price(init_p, impl_vol, drift, step, deltasqrt);
    x = max(cur_p - strike_p,0.0);
    //double q = double(i) / double(i + 1);
    //pay_o = pay_o *i/(i+1) + x / (i + 1);
    pay_o += x;
    //y = (1 - (1 / (i + 1)))*y + x*x / (i + 1);
}
//pay_o = pay_o / double(iter);
//stdev = sqrt((y - pow(pay_o , 2)) / (iter - 1));
//return pay_o*exp(-risk_free*T) ;
return pay_o;
}

原文:https://stackoverflow.com/questions/36782966
更新时间:2019-12-07 10:14

最满意答案

看起来你想要计算平均值。 大多数人学习计算均值的方法是将所有值相加,然后将总和除以贡献总和的值的数量。

这种方法有一些与之相关的问题 - 例如,在一起添加许多值可能会给持有它的变量一个太大的总和。

经常使用另一种技术,其累积“运行”均值而不是总和。 运行平均值始终是已累积的所有样本的平均值,因此它永远不会爆炸成溢出(浮点无穷大)值(除非其中一个累积样本为无穷大)。

下面的示例演示了如何计算运行平均值。 它还计算总和并显示总和/计数与运行平均值的比较(表明它们是相同的 - 我没有让它运行足够长以溢出总和)。

该示例使用C-Library rand(),用于演示目的 - 我只需要一些东西来计算平均值。

#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iomanip>

int main() {
        srand(static_cast<unsigned>(time(0)));

        double count = 0;
        double running_mean = 0;
        double sum = 0;

        auto start = time(0);
        auto end = start + 5;
        while(time(0) < end) {
            double sample = rand();
            count += 1;
            running_mean += (sample - running_mean)/count;
            sum += sample;
        }

        std::cout << std::setprecision(12);
        std::cout << "running mean:" << running_mean << "  count:" << count << '\n';
        double sum_mean = sum / count;
        std::cout << "sum:" << sum << "  sum/count:" << sum_mean << '\n';
}

编辑:他已经尝试过这个 - 这个技术出现在我在OP代码中遗漏的注释掉的行中

与通过累积总和来计算平均值不同,运行平均技术不能简单地在某个时刻溢出。 所以知道他已经尝试了这个并且它没有帮助解决这个问题,可能的原因就是迭代的一个术语本身就是INF。 一旦添加单个INF术语,累积的总和或平均值将变为INF并保持INF。

最可能的代码部分是在参数内部使用的normal_gen()用于调用exp函数。 名称normal_gen()听起来像是正常分布的随机值的来源。 通常的实现采用Box-Muller变换,其不能产生超过平均值大约7个标准偏差的值。 因此,如果Box-Muller生成器导致INF,它可能会在比报告的迭代次数更少的情况下发生。 然而,更高级的生成器可以产生更多的极值 - 理想情况下,正态分布具有产生任何有限实际值的非零概率。

如果一个随机大的Normal样本是造成问题的原因,那么它与迭代计数增加的相关性就不会是更多的迭代使总和膨胀,通过添加更多的值来溢出 - 这将是更多的迭代给了程序一个更好的机会击中一个不太可能的随机值,这将导致一个INF术语。


It looks like you want to compute mean values. The the way most people learn to calculate a mean is to sum up all the values, then divide the sum by the number of values which contributed to the sum.

This method has a few problems associated with it -- for example, adding many values together might give a sum which is too large for the variable holding it.

Another technique is often used, which accumulates a "running" mean instead of a sum. The running mean's value is always the mean value for all samples already accumulated, so it never blows up into an overflow (floating-point infinity) value (except when one of the accumulated samples was infinity).

The example below demonstrates how to calculate a running mean. It also calculates the sum and shows how sum/count compares to the running mean (to show that they are the same -- I haven't let it run long enough to overflow the sum).

The example uses the C-Library rand(), for demonstration purposes -- I just needed something to calculate mean values from.

#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iomanip>

int main() {
        srand(static_cast<unsigned>(time(0)));

        double count = 0;
        double running_mean = 0;
        double sum = 0;

        auto start = time(0);
        auto end = start + 5;
        while(time(0) < end) {
            double sample = rand();
            count += 1;
            running_mean += (sample - running_mean)/count;
            sum += sample;
        }

        std::cout << std::setprecision(12);
        std::cout << "running mean:" << running_mean << "  count:" << count << '\n';
        double sum_mean = sum / count;
        std::cout << "sum:" << sum << "  sum/count:" << sum_mean << '\n';
}

Edit: He already tried this -- the technique appeared in commented-out lines that I missed in the OP's code

Unlike computing the average value by accumulating a grand sum, the running mean technique cannot simply overflow at some point. So knowing that he already tried this and that it didn't help the problem, the probable cause becomes that one of the iteration's terms is, itself INF. As soon as a single INF term is added, the accumulated sum or mean will become INF and stay INF.

The most likely section of code was normal_gen() used inside the argument for a call to the exp function. The name normal_gen() sounds like a source of Normally-distributed random values. The usual implementation employs a Box–Muller transform, which cannot produce values over about 7 standard-deviations away from the mean. So if a Box-Muller generator was causing the INF, it would probably occur within fewer iterations than reported. However, more advanced generators can produce more extreme values -- ideally a Normal distribution has a nonzero probability of producing any finite real value.

If a randomly large Normal sample is what was causing the problem, its correlation with increased iteration count would not be that more iterations inflate the sum, to the point of overflowing by adding more values -- it would be that more iterations gave the program a better chance to hit an unlikely random value which would result in an INF term.

2016-04-23

相关文章

更多

最新问答

更多
  • 删除不适用于JSP中使用for循环的每个id(Deletion not working for every id using for loop in JSP)
  • 如何从std :: filesystem :: path中删除引号(How to remove quotation marks from std::filesystem::path)
  • 验证多个控制器方法的URL路径(Validate URL path for several controller methods)
  • 如何在datarow []中的列中找到最大值?(How to find max value in a column in a datarow[] ?)
  • 如何使用预定义文本替换来自数据库的部分结果(How do I replace part of result coming from Database with predefined text)
  • Selenium Java注入了新的Javascript函数(Selenium Java inject new Javascript function)
  • 使用.on的多个下拉菜单选择文本仅适用于第一个下拉列表(Multiple Dropdowns Menu Selection text using .on works only on first dropdown)
  • 快速将黄土曲线添加到大型数据集图中的方法(Quick way to add loess curve to large data set graph)
  • FilteringSelect in mvc(FilteringSelect in mvc)
  • 在Delphi XE2中开发Mac或iOS应用程序需要哪些硬件/软件?(What hardware/software is necessary to develop Mac or iOS apps in Delphi XE2?)
  • 在原型的构造函数中初始化属性时获取“未定义”(Getting 'undefined' when a property is initialized in the constructor of a prototype)
  • 通过越狱加载的应用程序的Documents文件夹位置(Location of Documents folder for an app loaded via jailbreak)
  • 在OpenGL中使用可编程和固定管道功能(Using both programmable and fixed pipeline functionality in OpenGL)
  • 将任何用户输入重定向到单独的底层程序(redirect any user input to a separate underlying program)
  • 编辑文本不能正常工作android(Edit texts not working properly android)
  • “user_denied”Facebook应用页面上的Facebook用户区域设置(Facebook user locale on “user_denied” facebook app page)
  • 在大图像中找到小的部分透明图像的坐标(find coordinates of small partially-transparent image within a large image)
  • 我如何在cakephp 3.1中获得完整的相对路径?(How i can get full relative path of image in cakephp 3.1?)
  • 如何保存拖动标记的新本地化?(How to save new localization of dragged marker?)
  • MySQL UPDATE vs INSERT和DELETE(MySQL UPDATE vs INSERT and DELETE)
  • 在执行查询之前,在SQLAlchemy模型中将datetime转换为unix时间戳?(Convert datetime to unix timestamp in SQLAlchemy model before executing query?)
  • OpenCL与OpenGL互操作的优势(Advantage of OpenCL interoperability with OpenGL)
  • 如何解析用点和等分隔的数据然后添加到listview(How to parsing data from delimited with dot and equal then add to listview)
  • 带调试输出的X3解析器段错误(BOOST_SPIRIT_X3_DEBUG)(X3 parser segfaults with debug output (BOOST_SPIRIT_X3_DEBUG))
  • 将文件夹名称添加到fgrep结果(Add folder name to fgrep result)
  • 在MySQL中加载一个表是非常慢的(Loading one table in MySQL is ridiculously slow)
  • 如何将JSON放入PHP变量?(How do I put JSON into a PHP Variable?)
  • 如何绕过Microsoft.Speech.Recognition中的不流畅?(How to bypass disfluencies in Microsoft.Speech.Recognition?)
  • 原点的最后一行是什么?(What is the last row of an origin for?)
  • 将字符串转换为javascript中的操作(Translate String to operation in javascript)