Форум программистов
 
Расширенный поиск
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > C++ > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Ответ
 
Опции темы
Старый 21.04.2017, 09:26   #1
ivan.tiran
Форумчанин
 
Аватар для ivan.tiran
 
Регистрация: 24.08.2011
Сообщений: 95
Репутация: 8
По умолчанию Как сделать, чтобы числа в нормальном законе распределения были каждый раз разные?

Доброго времени суток. В своей работе моделирую измерения. Для этого вычисляю погрешности с помощью функции:
Код:

std::normal_distribution

Погрешности моделируются замечательно. Но, мне не нравится, что с каждым запуском программы они всегда одинаковые.

Помнится, что в rand() я использовал:
Код:

srand(time(NULL))

для этого, но для std::normal_distribution это не работает.

Как посчитать погрешности по нормальному закону распределения, чтобы они при каждом запуске программы были каждый раз разными?
ivan.tiran вне форума   Ответить с цитированием
Старый 21.04.2017, 09:38   #2
p51x
Профессионал
 
Регистрация: 15.02.2010
Сообщений: 9,362
Репутация: 1486

icq: 216409213
По умолчанию

Код:

std::random_device rd;
std::mt19937 gen(rd());

std::normal_distribution<> d(5,2);
d(gen);

__________________
Запомните раз и навсегда: помочь != "решите за меня"!
p51x вне форума   Ответить с цитированием
Старый 21.04.2017, 09:55   #3
ivan.tiran
Форумчанин
 
Аватар для ivan.tiran
 
Регистрация: 24.08.2011
Сообщений: 95
Репутация: 8
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Код:

std::random_device rd;
std::mt19937 gen(rd());

std::normal_distribution<> d(5,2);
d(gen);

Всё равно одинаковые(((
ivan.tiran вне форума   Ответить с цитированием
Старый 21.04.2017, 10:26   #4
ivan.tiran
Форумчанин
 
Аватар для ivan.tiran
 
Регистрация: 24.08.2011
Сообщений: 95
Репутация: 8
По умолчанию

Вот, мой код. Может, я что-то неправильно делаю?

Код:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <QVector>
#include "consts.h"
#include <random>
#include <time.h>


struct NU
{

    double x,y,vx,vy;

};


void runge_kut(double xx,double yy,double vxx,double vyy, double Step, double * b);
void CentralBody(double *r, double *w_gpz);
QVector<double> calcDeltaD(int begin, int end);
QVector<double> calcDeltaDp(int begin, int end);
QVector<double> calcD(QVector<NU> nu,QVector<double> deltaD);
QVector<double> calcDp(QVector<NU> nu,QVector<double> deltaDp,QVector<double> D);



int main()
{

    double x0 = 0.0;
    double y0 = 6671.0;
    double Vx0 = 7.72989;
    double Vy0 = 0.0;
    int Step = 1;
    int timeBegin = 0;
    int iterationTimeSec = 600;
    double b[4];
    QVector<double> deltaD,deltaDp;
    QVector<double> D,Dp;

    QVector<NU> nu;

    NU a;

    a.x = x0;
    a.y = y0;
    a.vx = Vx0;
    a.vy = Vy0;

    nu.append(a);


    for(int i = timeBegin + Step;i<iterationTimeSec;i+=Step)
    {
        runge_kut(x0,y0,Vx0,Vy0, Step, b);

        NU a;

        a.x  =  b[0];
        a.y  =  b[1];
        a.vx = b[2];
        a.vy = b[3];

        nu.append(a);

        x0 = a.x;
        y0 = a.y;
        Vx0= a.vx;
        Vy0= a.vy;
    }




    deltaD = calcDeltaD(timeBegin,iterationTimeSec);
    deltaDp = calcDeltaDp(timeBegin,iterationTimeSec);

    D = calcD(nu,deltaD);
    Dp = calcDp(nu,deltaDp,D);



    for(int i=0;i<nu.count();i++)
    {
        printf("%i\tD = %f\tDp = %f\n",i+1,deltaD[i],deltaDp[i]);

    }




    nu.clear();
    deltaD.clear();
    deltaDp.clear();
    return 0;
}


void runge_kut(double xx,double yy,double vxx,double vyy, double Step, double * b)
{


    double k1[2],k2[2],k3[2],k4[2];
    double m1[2],m2[2],m3[2],m4[2];
    double w_gpz_GSK[2] = {0,0};
    double f_GSK[2] = {0,0};
    double r_GSK[2] = {0,0};
    double v_GSK[2] = {0,0};
    double r0_GSK[2] = {0,0};
    double v0_GSK[2] = {0,0};


    for (int i =0; i < 2; i++)
    {
        k1[i] = 0; k2[i] = 0; k3[i] = 0; k4[i] = 0;
        m1[i] = 0; m2[i] = 0; m3[i] = 0; m4[i] = 0;
    }


    r_GSK[0] = xx;
    r_GSK[1] = yy;

    v_GSK[0] = vxx;
    v_GSK[1] = vyy;


    r0_GSK[0] = r_GSK[0];
    r0_GSK[1] = r_GSK[1];
    v0_GSK[0] = v_GSK[0];
    v0_GSK[1] = v_GSK[1];


    CentralBody(r_GSK,w_gpz_GSK);


    f_GSK[0] = w_gpz_GSK[0] * r_GSK[0];
    f_GSK[1] = w_gpz_GSK[1] * r_GSK[1];



    for (int i = 0; i < 2; i++)
    {
        k1[i] = Step*v_GSK[i];
        m1[i] = Step*f_GSK[i];
        r_GSK[i] =r0_GSK[i] + k1[i]/2.;
        v_GSK[i] =v0_GSK[i] + m1[i]/2.;
    }




    CentralBody(r_GSK,w_gpz_GSK);
    f_GSK[0] = w_gpz_GSK[0] * r_GSK[0];
    f_GSK[1] = w_gpz_GSK[1] * r_GSK[1];


    for (int i = 0; i < 2; i++)
    {
        k2[i] = Step*v_GSK[i];
        m2[i] = Step*f_GSK[i];
        r_GSK[i] =r0_GSK[i] + k2[i]/2.;
        v_GSK[i] =v0_GSK[i] + m2[i]/2.;
    }




    CentralBody(r_GSK,w_gpz_GSK);

    f_GSK[0] = w_gpz_GSK[0] * r_GSK[0];
    f_GSK[1] = w_gpz_GSK[1] * r_GSK[1];


    for (int i = 0; i < 2; i++)
    {
        k3[i] = Step*v_GSK[i];
        m3[i] = Step*f_GSK[i];
        r_GSK[i] =r0_GSK[i] + k3[i];
        v_GSK[i] =v0_GSK[i] + m3[i];
    }


    CentralBody(r_GSK,w_gpz_GSK);

    f_GSK[0] = w_gpz_GSK[0] * r_GSK[0];
    f_GSK[1] = w_gpz_GSK[1] * r_GSK[1];


    for (int i = 0; i < 2; i++)
    {
        k4[i] = Step*v_GSK[i];
        m4[i] = Step*f_GSK[i];

        b[i] =r0_GSK[i] + 1/6.*(k1[i]+2*k2[i]+2*k3[i]+k4[i]);
        b[i+2] =v0_GSK[i] + 1/6.*(m1[i]+2*m2[i]+2*m3[i]+m4[i]);
    }
}


void CentralBody(double *r, double *w_gpz)
{
    double mod_r = sqrt(r[0]*r[0] + r[1]*r[1]);
    for (int i = 0; i < 2; i++)
    {
        w_gpz[i] = -MU/(mod_r*mod_r*mod_r);
    }
}



QVector<double> calcDeltaD(int begin, int end)
{
    QVector<double> ret;


    std::random_device rd;
    std::mt19937 engine(rd());
    std::normal_distribution<double> dist(0.0,sigmaD);


    for(int i = begin;i<end;i++)
    {
        double  delta_d = dist(engine);
        ret.append(delta_d);
    }
    return ret;
}


QVector<double> calcDeltaDp(int begin, int end)
{
    QVector<double> ret;

    std::random_device rd;
    std::mt19937 engine(rd());
    std::normal_distribution<double> dist(0.0,sigmaDp);


    for(int i = begin;i<end;i++)
    {
        double  delta_dp = dist(engine);
        ret.append(delta_dp);
    }
    return ret;
}

QVector<double> calcD(QVector<NU> nu,QVector<double> deltaD)
{
    QVector<double> D;

    for(int i=0;i<nu.count();i++)
    {
        double xMinxN = nu[i].x - xN;
        double yMinyN = nu[i].y - yN;
        double d = sqrt(xMinxN*xMinxN + yMinyN*yMinyN) + deltaD[i];
        D.append(d);
    }


    return D;
}

QVector<double> calcDp(QVector<NU> nu,QVector<double> deltaDp,QVector<double> D)
{
    QVector<double> Dp;

    for(int i=0;i<nu.count();i++)
    {
        double xMinxN = nu[i].x - xN;
        double yMinyN = nu[i].y - yN;

        double dp = ( xMinxN*nu[i].vx +  yMinyN*nu[i].vy) / (D[i]) + deltaDp[i];
        Dp.append(dp);
    }


    return Dp;
}

Вложения
Тип файла: 7z kalman.7z (1.7 Кб, 1 просмотров)
ivan.tiran вне форума   Ответить с цитированием
Старый 21.04.2017, 16:20   #5
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 290
Репутация: 71
По умолчанию

Цитата:
static std::mt19937 engine(std::chrono::system_clock::n ow().time_since_epoch().count());
std::normal_distribution<double> dist(0.0,sigmaD);
Смысл в том, что engine должна жить от начала до конца работы и получать seed только в начале от времени. От другого генератора смысла нет, т.к. тот генератор тоже выдает одинаковые числа. Хотя, можно взять энтропийный генератор, вместо времени (который аппаратно случаен, но много чисел он не даст)

Последний раз редактировалось alexzk; 21.04.2017 в 16:24.
alexzk вне форума   Ответить с цитированием
Старый 21.04.2017, 21:55   #6
ivan.tiran
Форумчанин
 
Аватар для ivan.tiran
 
Регистрация: 24.08.2011
Сообщений: 95
Репутация: 8
По умолчанию

Цитата:
Сообщение от alexzk Посмотреть сообщение
Смысл в том, что engine должна жить от начала до конца работы и получать seed только в начале от времени. От другого генератора смысла нет, т.к. тот генератор тоже выдает одинаковые числа. Хотя, можно взять энтропийный генератор, вместо времени (который аппаратно случаен, но много чисел он не даст)
Я просто в шоке. Пришёл домой. Решил проверить, как моделируются погрешности пока без этого кода. Дома в качестве ОС использую Ubuntu. И что вы думаете?
Числа - разные. Почему так?
На XP - одинаковые, на Ubuntu - разные? Мистика.
ivan.tiran вне форума   Ответить с цитированием
Старый 21.04.2017, 22:13   #7
p51x
Профессионал
 
Регистрация: 15.02.2010
Сообщений: 9,362
Репутация: 1486

icq: 216409213
По умолчанию

Цитата:
На XP - одинаковые, на Ubuntu - разные? Мистика.
Никапли. В линукса зачастую испульзую /dev/(u)rand для генерации в отличии от винды ХП.
__________________
Запомните раз и навсегда: помочь != "решите за меня"!
p51x вне форума   Ответить с цитированием
Старый 21.04.2017, 22:17   #8
ivan.tiran
Форумчанин
 
Аватар для ivan.tiran
 
Регистрация: 24.08.2011
Сообщений: 95
Репутация: 8
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Никапли. В линукса зачастую испульзую /dev/(u)rand для генерации в отличии от винды ХП.
Неочень понял. Это особенность пингвинов такая генерить разный рандом?
ivan.tiran вне форума   Ответить с цитированием
Старый 22.04.2017, 00:44   #9
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 290
Репутация: 71
По умолчанию

Цитата:
Сообщение от ivan.tiran Посмотреть сообщение
Неочень понял. Это особенность пингвинов такая генерить разный рандом?
Нет, он имел ввиду, что в линуксах есть "аппаратный" генератор энтропии и он используется по умолчанию - там накапливается случайность, от движения мыши и т.д. Но, такая штука ограничена, если ничего не делать (не трогать мышь и т.д.) - числа быстро иссякнут и будут задержки генерации. Обычно его для криптографий берегут.

Т.о. в вашем примере, для старта второго генератора используется первый, который на линуксе аппаратный автоматически. Добавьте там static все равно, иначе при каждом вызове ф. будет перезапуск цепи.

Последний раз редактировалось alexzk; 22.04.2017 в 00:47.
alexzk вне форума   Ответить с цитированием
Старый 22.04.2017, 12:40   #10
ivan.tiran
Форумчанин
 
Аватар для ivan.tiran
 
Регистрация: 24.08.2011
Сообщений: 95
Репутация: 8
По умолчанию

Цитата:
Сообщение от alexzk Посмотреть сообщение
Нет, он имел ввиду, что в линуксах есть "аппаратный" генератор энтропии и он используется по умолчанию - там накапливается случайность, от движения мыши и т.д. Но, такая штука ограничена, если ничего не делать (не трогать мышь и т.д.) - числа быстро иссякнут и будут задержки генерации. Обычно его для криптографий берегут.

Т.о. в вашем примере, для старта второго генератора используется первый, который на линуксе аппаратный автоматически. Добавьте там static все равно, иначе при каждом вызове ф. будет перезапуск цепи.
где статик прописать?
ivan.tiran вне форума   Ответить с цитированием
Ответ



Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как сделать, чтобы текст, логотипы были привязаны к фону сайта? nikytt HTML и CSS 1 15.12.2015 01:35
Как сделать, чтобы с программой могли работать разные пользователи? вася радугов Помощь студентам 28 30.03.2014 23:28
Как сделать так, чтобы в Debug и Release использовались разные ддл'ки? TwiX Visual C++ 7 08.11.2011 10:51
Как сделать, чтобы разные таблицы имели одинаковую ширину столбцов? Natalie_M Microsoft Office Word 3 25.01.2011 08:53
Как сделать чтобы новые строки всегда были в области видимости? neugadal Microsoft Office Excel 9 06.09.2008 12:23




00:40.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.

купить трафик


как улучшить посещаемость, а также решения по монетизации сайтов, видео и приложений

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru