0

私は C/C++ でいくつかの疾患モデルをいじくり回してきましたが、より精度を高めたいと考えています。80 ビットの精度 (私は cygwin の GCC 4.8.3 を使用しています) のために long double を使用することを考えましたが、それを使用して計算を行った後、「nan」(数値ではない) の出力値が得られます。ここに私が取り組んでいるコードがあります。すべての変数は long double です。

#include <cstdlib>
#include <iostream>
#include <cstdio>
#include <ctime>
#include <random>
#include <omp.h>
#include <cfloat>



using namespace std;

int
main ( int argc, char** argv )
{

    long double S, E, I, R, V, dS, dE, dI, dR, dV;
    long double a, b, g, t, c, d, e, f;
    long double dt = .005, tmax = 365;

    S = 318000000;
    I = 1;
    E = 0;
    R = 0;
    V = 0;

    FILE* F;

    F = fopen ( "valoresSIR1.txt", "w+" );
    //fprintf ( F, "Tempo, Susceptivel, Incubado, Infectado, Recuperado, Vacinado\n" );

    a = 0.000005; 
    b = 0.01;
    c = 0.05; 
    d = 0.000034; 
    e = 0.00000; 
    f = 0.0; 
    g = 0.000000;
    t = 0.0000;

    //printf("%Lg", a); exit(0);
    for ( long double i = 0; i < tmax; i += dt )
    {
        dS = ( - a * I * S - g + t * R + d * ( S + E + R + V ) - f * S ) * dt;
        dE = ( a * I * S - c * E - g ) * dt;
        dI = ( c * E - g - e * I - b * I ) * dt;
        dR = ( b * I - g - t * R ) * dt;
        dV = ( f * S - g ) * dt;


        S += dS;
        E += dE;
        I += dI;
        R += dR;
        V += dV;

        //printf ( "%Lg, %Lg, %Lg, %Lg, %Lg, %Lg\n", S, E, I, R, V );
        std::cout.precision (50);
        std::cout << S << std::endl;
        exit ( 0 );
        fprintf ( F, "%Lg, %Lg, %Lg, %Lg, %Lg, %Lg\n", i, S, E, I, R, V );
        switch ( ( int ) i )
        {
            case 0: std::cout << i << endl;
                break;
            case 100: std::cout << i << endl;
                break;
            case 200: std::cout << i << endl;
                break;
            case 300: std::cout << i << endl;
                break;
            case 4000: std::cout << i << endl;
                break;
            case 5000: std::cout << i << endl;
                break;
            case 6000: std::cout << i << endl;
                break;
            case 7000: std::cout << i << endl;
                break;

        }

    }

    fclose ( F );

    return 0;
}

出力の期待値: http://pastebin.com/mJqkSVUf

4

1 に答える 1

4

計算dS = ( - a * I * S - g + t * R + d * ( S + E + R + V ) - f * S ) * dt;では、初期化されていない変数が使用されますV。これにより、未定義の動作が発生します。

未定義の動作が発生すると、あらゆることが起こります。あなたの場合、それはnanを含む操作の結果として明らかにされていVます。

于 2015-11-12T01:15:59.217 に答える