This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

function that choose a number randomly from a field



Hi all

I am looking for a function that can randomly return me a function from a finite field, let say an integer from 2 to 10, or something like 67 to 180, for example.

is that such a built in function?

Otherwise how can I implement one please?

Thanks 

  • Hi,

    use pseudo-random generator function that uses linear feedback register:
    http://en.wikipedia.org/wiki/Linear_feedback_shift_register

    You can 'clock' it by some hardware timer or use consecutive calls as state change event. The output can be further limited to the range you need.

    Regards,
    Piotr Romaniuk, Ph.D.
    ELESOFTROM

     

  • thanks for your replay, I will definitely have a look of it. However as I am a beginner of program, it will certainly take me some time to understand.

    so there is no any built in function allow me to do this job? let say random = rand([2...10])?

  • This is an elementary programming question, not anything MSP430-specific.

    No, there is not.  To do that, first you generate a random number from 0 to 8, then add 2.

    To generate a random number from 0 to 9, there are a few possibilities.  The most common is to take a larger random number and reduce it modulo 9, i.e. "random = rand()%9 + 2".  This generates a slight bias in the returned values, but it's usually not important.

    For example, if you start with a random value between 0 and 255, then r%9 will return 0,1, 2 or 3 29/256 of the time, and 4,5,6,7, or 8 28/256 of the time.

    If you need exactly random values, then you have to notice if your random number r is less than 256%9 = 4, and if it is, generate a new r.

    All of this uses division, which is slow on the MSP430.  A possibly faster and simpler technique is to mask off as many bits as you need (4 bits for a 9-way choice), and then if the random value is in the range, return it.  If not, generate a new random value.  This might require multiple calls to the basic RNG, but the average will never be more than 2.  (Since the fraction of the time you have to ask it for a new value is always less than 1/2.)

     

  • The Linux man page for rand() gives this algorthm.

    POSIX.1-2001 gives the following example of an implementation of rand() and srand(), possibly useful when one needs the same sequence on two different machines.

    static unsigned long next = 1;
    /* RAND_MAX assumed to be 32767 */
    int myrand(void) {
        next = next * 1103515245 + 12345;
        return((unsigned)(next/65536) % 32768);
    }
    void mysrand(unsigned seed) {
        next = seed;
    }


    The above is a form of Linear Congruential Generator. Described with a lot of dense math here:
      http://en.wikipedia.org/wiki/Linear_congruential_generator
    The above could be modified to give you your arbitrary range. For example, numbers between 2 to 10 inclusive:

    static unsigned long base  = 2;
    static unsigned long range = 8+1; /* Add 1 to be inclusive */
    static unsigned long next  = 1;
    int myrand(void)
    {
        next = next * 1103515245 + 12345;
        return((unsigned)((next%range)+base));
    }
    void mysrand(unsigned seed) {
        next = seed;
    }


    Note that such mods are definitely NOT mathematically sound. Pseudo Random Number Generators are a huge complex field way beyond my understanding.

    Piotr's recommendation of an LFSR is defintely an option if you are resource limited. It is preferred algorthm for most HW implementations and low level protocols. It is more difficult to modify for an arbitrary range without ruining the randomness. Here is one persons method for scaling values without a division:

    http://forums.parallax.com/showthread.php?112047-random-value-within-range-SOLVED
    http://forums.parallax.com/showthread.php?112349-Random-Numbers-Between-0-and-n-1

     

  • Thanks for your reply, in fact this is something I am looking, but what is the mysrand function, what does it do? next = seed, but seed doesn't seem to be used anywhere.

     

    In fact, I don't know much about programming, I bought a launchpad to start learning, and before that I was considering Arduino. The rand in Arduino is so much easier, there is a built in function which I can input my max and min, and I was wondering such a function can be found for MSP430 as well, this is why I asked.

  • The parameter "seed" is passed in and then assigned to the global variable "next". The global variable "next" has the initial value of 1 unless overwritten by mysrand().

    I had to look up Arduino. It uses C++ function overloading to define

    random(max)
    random(min, max)
    http://arduino.cc/en/Reference/Random

    The Arduino system also defines

    randomSeed(seed)
    http://arduino.cc/en/Reference/RandomSeed

    Both functions eventually call the OS functions random() and srandom(), as inidicated in the source file here:

    https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/WMath.cpp

    The link for randomSeed() describes what seed values are for PRNGs. You could port over all the code to faithfullyly emulate the Arduino function. Lot of work though. Simpler code:

    static unsigned long next  = 1;
    int myrand(unsigned long min, unsigned long max)
    {
        next = next * 1103515245 + 12345;
        return((unsigned)((next%(max-min))+min));
    }
    void mysrand(unsigned seed) {
        next = seed;
    }

    Are you trying to learn about programming language like C or C++  or programming an embedded system? Learning C first on Windows or Linux would be much easier than learning C to program a board.

     

  • With these highly ophisticated pseudo-random generators, you should be aware that they are sloooow on the MSP.

    The next = next * 1103515245 + 12345; calculation contais a 32 bit multiplication (which is okay on a 5x family device with 32bit multiplier, but rather slow on a device with only 16 bit or no hardware multiplier at all.)
    Also, the % operator is effectively a division. And divisions are even slower, much slower on the MSP.

    In many cases, especially if your system requires arandom value only every now and then, and you have external interrupts (from external async communication, port interrupts etc.), it might be sufficient to use the lower byte of TAR as random value.

    Of course if the event that requires the random value is triggered by the timer itself, this is everything but random.

  • The literature on pseudo-random number generators is immense, and too big to summarize here. Multiplies are popular primitives because they mix up bits quite well. Another detail is that recent results are usually designed for 32- or 64-bit processors, while the MSP would prefer 16 bits. But there are solutions with neither.

    If you have the basic 16×16→32 multiplier, you could implement a multiply with carry generator. This keeps 32 bits of state, divided into a high and a low word, and every cycle performs (high,low) = (low×65184) + high. The low word is the output. Since 65184 = 0xFEA0 = 65536−512+128+32, it's not that hard to do in software.

    Another good algorithm is a linear feedback shift register, basically a CRC implementation. It works a bit at a time, which makes it slow, but it's easy to make a multi-word implementation using the RRC instruction.

    A special type of LFSR is the Mersenne twister. It uses a huge state, but a cut-down 127-bit version (8 16-bit words) would be quite possible.

    If you need very good random numbers, you could always implement the RC4 cipher, or Bob Jenkins' ISAAC generator could be adapted to 16-bit use. Or the RC2 cipher is optimized for 16-bit machines.

  • Gustavo L has posted an "official" TI solution for HW based "real" random numbers in this thread:

    http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/t/108106.aspx

     

**Attention** This is a public forum