Random generator test. Where is error? - c++

Strange tests behaviour.
I have class that generate random values.
std::random_device RandomProvider::rd;
std::mt19937 RandomProvider::rnb(RandomProvider::rd());
#define mainDataType unsigned int
mainDataType RandomProvider::GetNextValue(mainDataType upperLimit)
{
static std::uniform_int_distribution<int> uniform_dist(1, upperLimit);
return uniform_dist(rnb);
}
And unit-test that test it's behavior.
TEST_METHOD(TestRandomNumber)
{
CreateOper(RandomNumber);
int one = 0, two = 0, three = 0, unlim = 0;
const int cycles = 10000;
for (int i = 0; i < cycles; i++)
{
mainDataType res = RandomProvider::GetNextValue(3);
if (res == 1) one++;
if (res == 2) two++;
if (res == 3) three++;
}
double onePerc = one / (double)cycles;
double twoPerc = two / (double)cycles;
double threePerc = three / (double)cycles;
Assert::IsTrue(onePerc > 0.20 && onePerc < 0.40);
Assert::IsTrue(twoPerc > 0.20 && twoPerc < 0.40);
Assert::IsTrue(threePerc > 0.20 && threePerc < 0.40);
}
Test passed all-times in debug and if i chose it and Run only it. But it fails all times when i
run it with other tests. I added debug output to text file and got unreal values onePerc = 0.0556, twoPerc= 0.0474 and threePerc = 0.0526... What is going on here? (i am using VS2013 RC)

Since you use a static uniform_int_distribution the first time you call GetNextValue the max limit is set, never being changed in any subsequent call. Presumably in the test case you mentioned, your first call to GetNextValue had a different value than 3. Judging from the values returned it looks like probably either 19 or 20 was used in the first such call.

Related

Clamp framerate in Windows

I have a simple loop
LARGE_INTEGER ticks_per_second;
::QueryPerformanceFrequency(&ticks_per_second);
MSG msg = { 0 };
while (true)
{
if (msg.message == WM_QUIT)
exit(0);
if (::PeekMessageW(&msg, NULL, 0U, 0U, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessageW(&msg);
continue;
}
static double last_time_s = 0;
LARGE_INTEGER cur_time_li;
::QueryPerformanceCounter(&cur_time_li);
double cur_time_s = (double)cur_time_li.QuadPart / (double)ticks_per_second.QuadPart;
double diff_s = cur_time_s - last_time_s;
double rate_s = 1 / 30.0f;
uint32_t slept_ms = 0;
if (diff_s < rate_s)
{
slept_ms = (uint32_t)((rate_s - diff_s) * 1000.0);
::Sleep(slept_ms);
}
update();
::printf("updated %f %u\n", diff_s, slept_ms);
last_time_s = cur_time_s;
}
And want update() to be called 30 times per second, but not more often
With this code it goes wrong, in console I getting something like this:
updated 0.031747 1
updated 0.001997 31
updated 0.031912 1
updated 0.001931 31
updated 0.031442 1
updated 0.002084 31
Which is seems to be correct only for first update, second one called too fast, and I can't understand why
I understand that update, PeekMessageW and etc. also wasting time, but even if I create a while (true) loop and comment update() out, it's still printing similar result
I using DirectX 11 with vsync turned off for rendering (rendering inside update function):
g_pSwapChain->Present(0, 0);
How do I fix code to make update() stable called 30 times in one second?
I don't think casting to double is good idea.I would run something like this:
static LARGE_INTEGER last_time_s = { 0 };
::QueryPerformanceCounter(&cur_time_li);
time_diff_microsec.QuadPart = cur_time_li.QuadPart - last_time_s.QuadPart;
// To avoid precision lost, convert to seconds *before* dividing by ticks-per-second.
time_diff_microsec.QuadPart *= 1000000;
time_diff_microsec.QuadPart /= ticks_per_second.QuadPart;
double rate_s = 1 / 30.0f;
uint32_t slept_ms = 0;
if (time_diff_microsec.QuadPart >= rate_s)// if (diff_s < rate_s)
{
// slept_ms = (uint32_t)(rate_s - time_diff_microsec.LowPart);// *1000.0);
// ::Sleep(slept_ms);
//}
//update();
::printf("updated %lld %u\n", time_diff_microsec.QuadPart, slept_ms);
}
last_time_s.QuadPart = time_diff_microsec.QuadPart/ 1000000;
}
Just brief "sketch". Not verified that calculations are correct though.

Arduino Programming adding milliseconds delay

So I'm trying to create an energy meter device which will read power every minute and then send it every 5 minutes through a LoRa server, using an MKR 1300 arduino. The problem is that as of now the hardware is removing a few milliseconds on the delay and so the time in the server ends up being p.e:
10:50:30
10:50:30
10:50:30
... 2 hours later
10:50:29
10:50:29
...
10:49:59
The code looks like this:
#include <MKRWAN.h>
#include "EmonLib.h"
LoRaModem modem;
String appEui = "1234567891011121";
String appKey = "ffffffffffffffffffffffffffffffff";
EnergyMonitor emon1;
EnergyMonitor emon2;
EnergyMonitor emon3;
double totalWatt;
int time_running;
int sending;
int totalKW;
int DELAY = 60000; // millis
void setup() {
Serial.begin(115200);
if (!modem.begin(EU868)) {
Serial.println("Failed to start module");
while (1) {}
};
Serial.print("Your module version is: ");
Serial.println(modem.version());
Serial.print("Your device EUI is: ");
Serial.println(modem.deviceEUI());
Serial.println("Connecting");
int connected = modem.joinOTAA(appEui, appKey);
if (!connected) {
Serial.println("Something went wrong; are you indoor? Move near a window and retry");
while (1) {}
}
Serial.println("Connected");
modem.minPollInterval(60);
analogReadResolution(9);
emon1.current(1, 53);
emon2.current(2, 53);
emon3.current(3, 53);
time_running = 0;
randomSeed(analogRead(A4));
}
void loop() {
unsigned long StartTime = millis();
totalWatt = 0;
unsigned long delay_send = 0;
int sending = 0;
double Irms1 = emon1.calcIrms(600);
if (Irms1 < 0.3) Irms1 = 0;
double Watt1 = Irms1 * 230;
double Irms2 = emon2.calcIrms(600);
if (Irms2 < 0.3) Irms2 = 0;
double Watt2 = Irms2 * 230;
double Irms3 = emon3.calcIrms(600);
if (Irms3 < 0.3) Irms3 = 0;
double Watt3 = Irms3 * 230;
totalWatt = Watt1 + Watt2 + Watt3;
totalKW = totalKW + totalWatt/1000;
if (time_running == 5) { //15 para 15 mins
double IrmsTotal = Irms1 +Irms2 + Irms3;
String msg = "{\"id\":\"avac_aud1\",\"kW\":"+String(totalKW)+", \"current\":"+String(IrmsTotal)+"}";
int err;
modem.beginPacket();
modem.print(msg);
err = modem.endPacket(true);
if (err > 0) {
//message sent correctly
time_running = 0;
totalKW = 0;
} else {
Serial.println("ERR");
time_running = 0;
}
}
time_running = time_running + 1;
if ((millis() - StartTime) > DELAY){
delay(10);
return;
} else{
delay(DELAY-(millis() - StartTime));
return;
}
}
I tried adding a variable ARD_DELAY (not shown above) to the code that in that last delay would subtract 7 to 8 milliseconds to try and fix this, but apparently, it only made it worse (now it removes 1 second every 1 hours instead of 2 hours) so today I'll try to add those 7 to 8 millis and see if it works, but I would really like to know why the heck this is happening because from what I can see from my code the delay should always account for the processed time including the data sending time.
Question is, how precise is your clock at all...
Still, I personally would rather go with the following approach:
#define DELAY (5UL * 60UL * 1000UL) // or whatever is appropriate...
static unsigned long timestamp = millis();
if(millis() - timestamp > DELAY)
{
// adding a fix constant will prevent accumulating deviations over time
timestamp += DELAY;
// run the every-5-min task...
}
Edit: combined 1-min and 5-min task:
Variant 1:
#define DELAY_SHORT (1UL * 60UL * 1000UL)
#define DELAY_LONG (5UL * 60UL * 1000UL)
static unsigned long timestampS = millis();
static unsigned long timestampL = timestampS;
if(millis() - timestampS > DELAY_SHORT)
{
timestamp += DELAY_SHORT;
// run the every-1-min task...
}
if(millis() - timestampL > DELAY_LONG)
{
timestamp += DELAY_LONG;
// run the every-5-min task...
}
Variant 2:
#define DELAY_1M (1UL * 60UL * 1000UL)
static unsigned long timestamp = millis();
if(millis() - timestamp > DELAY)
{
// adding a fix constant will prevent accumulating deviations over time
timestamp += DELAY;
// run the every-1-min task...
static unsigned int counter = 0;
if(++counter == 5)
{
counter = 0;
// run the every-5-min task...
}
}
Instead of trying to measure a start time and adding delay depending on that, you could keep track of the timing for your next cycle.
unsigned long next_cycle = DELAY;
...
void loop() {
...
delay( next_cycle - millis() );
next_cycle += DELAY;
}
If you also want to adjust for any time the program spends on initialization or similar, you can next_cycle = millis() + DELAY; before you enter your loop.

Random Number generation missing a pattern for the same seed

I am generating a random number for a particular seed ...So I have a property called seed which I allow the user to set. I give him two options: reset and trigger. The reset will re start the generation of random numbers. And trigger will generate the next random number. The pseudo code is somewhat like
::setSeed( unsigned & seed )
{
m_seed = seed
}
::reset()
{
m_seed = getcurrentseed()
srand(m_seed);
}
::trigger()
{
raValue = minValue + ( rand() % (maxValue-minValue+1) );
}
For a particular seed if I generate say 5 random values 5 times ..sometimes I see a value missing in one of the sets . What could be the reason ?
For eg.
seed(5)
rand()
rand()
rand()
seed(5)
rand()
rand()
rand()
After the second seed(5) call, sometimes I get a different sequence of numbers or I miss a number from the previous sequence
void RandomNodeLogic::process( SingleInputValueGetters const& singleInputValueGetters
, MultiInputValueGetters const& /*multiInputValueGetters*/
, OutputValueKeepers const& /*outputValueKeepers */
, OutputValueSetters const& outputValueSetters )
{
// get the seed and generate the random number
bool doRandom( false );
int maxValue= getMaxValue().getAs<int>();
int minValue = getMinValue().getAs<int>();
int newValue=0;
if(minValue > maxValue)
{
setMaxValue(minValue);
setMinValue(maxValue);
maxValue= getMaxValue().getAs<int>();
minValue = getMinValue().getAs<int>();
}
SingleInputValueGetters::const_iterator it = singleInputValueGetters.begin();
for( ; it != singleInputValueGetters.end(); ++it)
{
SlotID id = it->first;
const SlotValue* value = it->second();
if(!value)
{
continue;
}
if ( id == RTT::LogicNetwork::RandomNode::nextValuesSlotID )
{
doRandom = value->getAs<bool>();
newValue = minValue + ( rand() % (maxValue-minValue+1) ); // read the value from the next input slot
setRandomValue( ::convertToSlotValue( m_genValue.m_attrType, newValue ) );
}
else if ( id == RTT::LogicNetwork::RandomNode::resetValuesSlotID )
{
if ( value->getAs<bool>() )
{
doRandom = value->getAs<bool>();
setSeed(m_seed);
newValue = minValue + ( rand() % (maxValue-minValue+1) );
setRandomValue( ::convertToSlotValue( m_genValue.m_attrType, newValue ) );
}
}
}
if(!m_genValue.empty() && doRandom)
{
outputValueSetters.find( RTT::LogicNetwork::RandomNode::outputValuesSlotID)->second( m_genValue.getAs<int>() ) ;
RTT_LOG_INFO( QString("Random Number: %1").arg( m_genValue.getAs<int>() ));
}
if(!doRandom)
{
if(m_genValue.empty())
{
srand(1);
m_genValue = 0;
}
getAssociatedNode()->sleep();
}
}
void RandomNodeLogic::setSeed( const SlotValue& seed )
{
SlotValue oldValue = m_seed;
m_seed = seed;
srand(m_seed.getAs<unsigned int>());
modifiablePropertyValueChanged( RTT::LogicNetwork::RandomNode::seedPropertyID, m_seed, oldValue );
}
All informations you gave so far tell me that you are trying to write a C++ class wrapper for C random functions. Even if this wrapper is a class that can be instantiated multiple times, the underlying C functions access only one state. That's why you have to ensure that nobody else is using an instance of this wrapper class.
That's why it is a bad idea, to wrap C's random functions with a C++ class. As an C++ exercise in random try to implement your own random class, it's not as hard as it seems.

Error C2668: 'boost::bind' : ambiguous call to overloaded function

I am trying to build Quantlib on VS2013 in the Release x64 mode.
I added the Boost libraries using Property Manager and then Went to solutions explorer and clicked on Build.
The final output was: Build: 18 succeeded, 1 failed. 0 up-to-date, 0 skipped.
When I double clicked on the error this file opened up (convolvedstudentt.cpp)
Copyright (C) 2014 Jose Aparicio
This file is part of QuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://quantlib.org/
QuantLib is free software: you can redistribute it and/or modify it
under the terms of the QuantLib license. You should have received a
copy of the license along with this program; if not, please email
<quantlib-dev#lists.sf.net>. The license is also available online at
<http://quantlib.org/license.shtml>.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license for more details.
*/
#include <ql/experimental/math/convolvedstudentt.hpp>
#include <ql/errors.hpp>
#include <ql/math/factorial.hpp>
#include <ql/math/distributions/normaldistribution.hpp>
#include <ql/math/solvers1d/brent.hpp>
#include <boost/function.hpp>
#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#endif
#include <boost/bind.hpp>
#include <boost/math/distributions/students_t.hpp>
#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4))
#pragma GCC diagnostic pop
#endif
namespace QuantLib {
CumulativeBehrensFisher::CumulativeBehrensFisher(
const std::vector<Integer>& degreesFreedom,
const std::vector<Real>& factors
)
: degreesFreedom_(degreesFreedom), factors_(factors),
polyConvolved_(std::vector<Real>(1, 1.)), // value to start convolution
a_(0.)
{
QL_REQUIRE(degreesFreedom.size() == factors.size(),
"Incompatible sizes in convolution.");
for(Size i=0; i<degreesFreedom.size(); i++) {
QL_REQUIRE(degreesFreedom[i]%2 != 0,
"Even degree of freedom not allowed");
QL_REQUIRE(degreesFreedom[i] >= 0,
"Negative degree of freedom not allowed");
}
for(Size i=0; i<degreesFreedom_.size(); i++)
polynCharFnc_.push_back(polynCharactT((degreesFreedom[i]-1)/2));
// adjust the polynomial coefficients by the factors in the linear
// combination:
for(Size i=0; i<degreesFreedom_.size(); i++) {
Real multiplier = 1.;
for(Size k=1; k<polynCharFnc_[i].size(); k++) {
multiplier *= std::abs(factors_[i]);
polynCharFnc_[i][k] *= multiplier;
}
}
//convolution, here it is a product of polynomials and exponentials
for(Size i=0; i<polynCharFnc_.size(); i++)
polyConvolved_ =
convolveVectorPolynomials(polyConvolved_, polynCharFnc_[i]);
// trim possible zeros that might have arised:
std::vector<Real>::reverse_iterator it = polyConvolved_.rbegin();
while(it != polyConvolved_.rend()) {
if(*it == 0.) {
polyConvolved_.pop_back();
it = polyConvolved_.rbegin();
}else{
break;
}
}
// cache 'a' value (the exponent)
for(Size i=0; i<degreesFreedom_.size(); i++)
a_ += std::sqrt(static_cast<Real>(degreesFreedom_[i]))
* std::abs(factors_[i]);
a2_ = a_ * a_;
}
Disposable<std::vector<Real> >
CumulativeBehrensFisher::polynCharactT(Natural n) const {
Natural nu = 2 * n +1;
std::vector<Real> low(1,1.), high(1,1.);
high.push_back(std::sqrt(static_cast<Real>(nu)));
if(n==0) return low;
if(n==1) return high;
for(Size k=1; k<n; k++) {
std::vector<Real> recursionFactor(1,0.); // 0 coef
recursionFactor.push_back(0.); // 1 coef
recursionFactor.push_back(nu/((2.*k+1.)*(2.*k-1.))); // 2 coef
std::vector<Real> lowUp =
convolveVectorPolynomials(recursionFactor, low);
//add them up:
for(Size i=0; i<high.size(); i++)
lowUp[i] += high[i];
low = high;
high = lowUp;
}
return high;
}
Disposable<std::vector<Real> >
CumulativeBehrensFisher::convolveVectorPolynomials(
const std::vector<Real>& v1,
const std::vector<Real>& v2) const {
#if defined(QL_EXTRA_SAFETY_CHECKS)
QL_REQUIRE(!v1.empty() && !v2.empty(),
"Incorrect vectors in polynomial.");
#endif
const std::vector<Real>& shorter = v1.size() < v2.size() ? v1 : v2;
const std::vector<Real>& longer = (v1 == shorter) ? v2 : v1;
Size newDegree = v1.size()+v2.size()-2;
std::vector<Real> resultB(newDegree+1, 0.);
for(Size polyOrdr=0; polyOrdr<resultB.size(); polyOrdr++) {
for(Size i=std::max<Integer>(0, polyOrdr-longer.size()+1);
i<=std::min(polyOrdr, shorter.size()-1); i++)
resultB[polyOrdr] += shorter[i]*longer[polyOrdr-i];
}
return resultB;
}
Probability CumulativeBehrensFisher::operator()(const Real x) const {
// 1st & 0th terms with the table integration
Real integral = polyConvolved_[0] * std::atan(x/a_);
Real squared = a2_ + x*x;
Real rootsqr = std::sqrt(squared);
Real atan2xa = std::atan2(-x,a_);
if(polyConvolved_.size()>1)
integral += polyConvolved_[1] * x/squared;
for(Size exponent = 2; exponent <polyConvolved_.size(); exponent++) {
integral -= polyConvolved_[exponent] *
Factorial::get(exponent-1) * std::sin((exponent)*atan2xa)
/std::pow(rootsqr, static_cast<Real>(exponent));
}
return .5 + integral / M_PI;
}
Probability
CumulativeBehrensFisher::density(const Real x) const {
Real squared = a2_ + x*x;
Real integral = polyConvolved_[0] * a_ / squared;
Real rootsqr = std::sqrt(squared);
Real atan2xa = std::atan2(-x,a_);
for(Size exponent=1; exponent <polyConvolved_.size(); exponent++) {
integral += polyConvolved_[exponent] *
Factorial::get(exponent) * std::cos((exponent+1)*atan2xa)
/std::pow(rootsqr, static_cast<Real>(exponent+1) );
}
return integral / M_PI;
}
InverseCumulativeBehrensFisher::InverseCumulativeBehrensFisher(
const std::vector<Integer>& degreesFreedom,
const std::vector<Real>& factors,
Real accuracy)
: normSqr_(std::inner_product(factors.begin(), factors.end(),
factors.begin(), 0.)),
accuracy_(accuracy), distrib_(degreesFreedom, factors) { }
Real InverseCumulativeBehrensFisher::operator()(const Probability q) const {
Probability effectiveq;
Real sign;
// since the distrib is symmetric solve only on the right side:
if(q==0.5) {
return 0.;
}else if(q < 0.5) {
sign = -1.;
effectiveq = 1.-q;
}else{
sign = 1.;
effectiveq = q;
}
Real xMin =
InverseCumulativeNormal::standard_value(effectiveq) * normSqr_;
// inversion will fail at the Brent's bounds-check if this is not enough
// (q is very close to 1.), in a bad combination fails around 1.-1.e-7
Real xMax = 1.e6;
return sign *
Brent().solve(boost::bind(std::bind2nd(std::minus<Real>(),
effectiveq), boost::bind<Real>(
&CumulativeBehrensFisher::operator (),
distrib_, _1)), accuracy_, (xMin+xMax)/2., xMin, xMax);
}
}
The error seems to be in the third line from the bottom. That's the one that's highlighted.
effectiveq), boost::bind<Real>(
&CumulativeBehrensFisher::operator (),
distrib_, _1)), accuracy_, (xMin+xMax)/2., xMin, xMax);
When I hover a mouse over it, it says
Error: more than one instance of overloaded function "boost::bind" matches the argument list: function template "boost_bi::bind_t " etc. Please see the attached screenshot
How can I fix this? Please help.
This came up quite a few times lately on the QuantLib mailing list. In short, the code worked with Boost 1.57 (the latest version at the time of the QuantLib 1.5 release) but broke with Boost 1.58.
There's a fix for this in the QuantLib master branch on GitHub, but it hasn't made it into a release yet. If you want to (or have to) use Boost 1.58, you can check out the latest code from there. If you want to use a released QuantLib version instead, the workaround is to downgrade to Boost 1.57.

"printf" appears to be non-deterministic in Qt?

I know "printf" is standard-c and should be deterministic. But when run in Qt I see a more non-deterministic response(clock cycles). Could this be due to Qt adding some "pork" to its response?
I have multiple threads that make call to function that uses a mutex. When one thread enters it set a switch so the others can't until it is done. Things appeared to work ok for acouple seconds and then threads appeared to be killed off from 10 to 1 thread. So I tried adding a delay: (k=k+1: no help), then (looping k=k+1: no help), (usleep works), and so does (printf) work at creating a random delay and allowing all threads to continue running.
void CCB::Write(int iThread)
{
static bool bUse = false;
bool bDone = false;
char cStr[20];
int posWrite;// = *m_posWrite; // issue of posWrite be altered with next extrance
long k = 0;
long m = 0;
m_threadCount++;
while(bDone == false){
if(bUse == false){
bUse = true;
posWrite = *m_posWrite;
memcpy(m_cmMessageCB + posWrite, &m_cmMessageWrite, sizeof(typeCanMessage));
memset(cStr, '\0', 20);
memcpy(cStr, (m_cmMessageCB + posWrite)->cMessage, 11); //fails: every 20
*m_posWrite = *m_posWrite + 1;
if(*m_posWrite == m_iNBufferLength)
*m_posWrite = 0;
bDone = true;
bUse = false;
}else if(bUse == true){
//why are threads being killed ?
// printf("T%d_%d ", iThread, m_threadCount);//non-deterministic value ?
usleep(1);//non-deterministic value
//k++;//delay of a couple clock cycles was not enough
/*
for(k = 0; k < iThread * 100; k++){//deterministic and fails to resolve thread problem
m++;
}
*/
}
}
}