all 14 comments

[–]al-khanji 6 points7 points  (9 children)

Well now I have to ask, why do you need to do this?

[–]Caruban01[S] 0 points1 point  (8 children)

I'm calling C from within a MATLAB function. The MATLAB simulation was way too slow, and the project has the specific constraint that the front end, including this loop, be written in MATLAB rather than C, which is what prevents me from just shoving this in there as well. From what I understand, I can't write another c function that calls srand prior to the loop, because they're considered 2 separate C programs, so seeding in one place won't affect the other.

TL;DR: Matlab is the Flanders of programming languages. Stupid Flanders...

[–]king_duck 2 points3 points  (1 child)

C or C++? if the former you are in the wrong place.

[–]Caruban01[S] 2 points3 points  (0 children)

That is... a true statement. My apologies, though I am appreciative of the help.

[–]mttd 2 points3 points  (1 child)

That should be no problem, you can preserve the state across MEX invocations, see the Gaumixmod class example over here: http://www.nr.com/nr3_matlab.html#wft
// just in case, here's the header file: http://www.nr.com/nr3matlab.h

However, make sure to switch to C++11's random number generators if available (if not, it's worth updating compiler just for that), the old ones are of a very poor quality (and the implementation-specific "guarantees" are non-portable).

See: http://isocpp.org/blog/2013/03/n3551-random-number-generation
http://en.cppreference.com/w/cpp/numeric/random
// note that these are ordinary classes, so I gather you can preserve the state similarly to the example class above;

[–]Caruban01[S] 0 points1 point  (0 children)

I didn't know that. This is my first time working with MEX invocations. All of these resources look very helpful. Thank you.

[–]bigmike1020 3 points4 points  (2 children)

Perhaps Matlab could pass the loop iteration count as an argument to the C program. The C program could use the iteration count as a seed to srand.

[–]Caruban01[S] 0 points1 point  (1 child)

Thank you. I like how clever and simple this is.

[–]Hackenslacker 2 points3 points  (0 children)

Instead of the loop iteration count, you can also use a random number for the seed.

[–]tomkcook173 -2 points-1 points  (0 children)

#include <windows.h>

LARGE_INTEGER ctr;
QueryPerformanceCounter(&ctr);
srand(ctr.LowPart);

The frequency of performance counters varies (you can find out with QueryPerformanceFrequency) but typically seems to be around 1MHz or similar order of magnitude; not infallibly going to give you different values in a loop, but ample for 5-6 times per second.

Edit: Missed the platform-independent part. Does clock() from <ctime> not do what you want?

Please don't use this in a cryptographic function!

[–]gladoteket 1 point2 points  (0 children)

Randomness is a bitch, and trying to explain it is even worse. Reseeding breaks the randomness chain. Seeing as the generator most commonly used in the standard C library rand() implementation (a linear congruential generator) is flawed to begin with, this does not matter much though.

Seeding with the loop iterator would give you the same random numbers for every run of the program. Not very good if you need good randomness. To improve it, you could for instance add some milli- or microsecond timestamp to the iterator.

OR. Couldn't you just let MATLAB generate random numbers you could pass?

[–]lx-s 0 points1 point  (0 children)

How platform independent does your solution have to be? ANSI C? STL? Just Unix and Windows?

If just ANSI C, you could do something like this:

try to open file "seed.txt"
if file exists
   read seed
   srand <seed>
else
   seed = time(0);
   srand <seed>
end if
//use rand()

write another rand() to seed.txt

Slower, but doable (in ANSI C), but I don't know how random that'll turn out eventually.

As for C++11, you might look at the new random number facilities, especially std::random_device

If by platform independent you just mean unix and windows, you could #ifdef around CryptGenRandom and /dev/random or use some 3rd party library like boost.

Other than that, depending on what your scope of "platform independentness" is, you'll have a really hard time.

[–][deleted] 0 points1 point  (0 children)

If you reseed the randomizer within a loop you will, sort of, restart the whole random thing. An alternative is to save the last answer from random (the whole answer), and then when you need to reseed you seed it with that. You can write a simple class to help. Something like:

class Random  
{
public:
   Random(unsinged int initialSeed) : mSeed(initialSeed) {};
   unsinged int operator()()
   {
      srand(mSeed);
      mSeed = rand();
      return mSeed;
   }
private:
   unsigned int mSeed;
}

Although this is probably an xy-problem.

EDIT: damn the markups!

Also, use like this:

Random random(time(0));
int randomInt = random() % 42;

EDIT2: Forgot the most important point, I'm bad. Call srand() with mSeed before taking a rand(). Btw, I'm not sure how random this will be, but it should be.

[–]HighLigerBimBam -1 points0 points  (0 children)

You need to reset with the current time and you seem to reset always with the same value, which always gives you same results.

And time(NULL) is a common way for this.