Thread: need help!!!

  1. #1
    Registered User
    Join Date
    Jun 2003
    Posts
    28

    need help!!!

    For this program, I want to generate a floating point number in the interval [-1, 1] using the formular X(n+1) = (X(n) + X(n-1)) % 1.0, however, when I print out the numbers it generated, it printed out some number less than -1. The function I used here is fmod(), this function generate a random number between 0 to 1, then it is multiplied by 2 and minus 1, which should give me a floating number between -1 to 1.

    The array for storing these random values are dynamically allocated using pointer.

    I spent a lot of time fixing this but couldn't find out where the error is. Very appreciated if anyone can help. Thanks!!

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    
    #define MAX_NUM 10
    
    int main(int argc, char **argv)
    {
    
      float init_x1 = 0.122840678;
      float init_x2 = 0.102683;
      int i;
      int j;
      
      int count[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0};      /* counter for histogram */
    
      float *random_floating, *nodePtr;
      float *temp_x1;
      float *temp_x2;
      
      random_floating = (float *) malloc (MAX_NUM * sizeof(float));  /* allocate enough space for random number generated */
      nodePtr = random_floating;
      
      *nodePtr++ = init_x1;
      *nodePtr++ = init_x2;
    
      for (; nodePtr < (MAX_NUM + random_floating); nodePtr++) {
        temp_x1 = nodePtr - 2;
        temp_x2 = nodePtr - 1;
        
        *nodePtr = fmod(*temp_x1 + *temp_x2, 1.0) * 2.0 - 1.0; /* generate a floating number in [-1, 1] */
       
        printf ("%f\n", *nodePtr);
        
        count[(int)(*nodePtr * 10) + 10]++;
      }
      
      for (i = 0; i < 20; i++)
        printf ("%d   ", count[i]);
    }

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Code:
    /* generate a floating number in [-1, 1] */
    *nodePtr = fmod(*temp_x1 + *temp_x2, 1.0) * 2.0 - 1.0;
    The result of fmod(x,y) "has the same sign as x and magnitude less than the magnitude of y". So I believe that you already obtain a range (-1,1) with the fmod call. I don't think you need to multiply by 2.0 and subtract 1.0, that may change your range to (-3,1).
    Code:
    *nodePtr = fmod(*temp_x1 + *temp_x2, 1.0);
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    Registered User
    Join Date
    Jun 2003
    Posts
    28
    I did try with *nodePtr = fmod(*temp_x1 + *temp_x2, 1.0); but the 1000000 floating-point numbers generated are all in the interval [0, 1.0), so times 2 and subtract 1 should give me a result between -1 and 1, however, this is not so.. I just can't seem to find out where the problem is..

    The first two initial numbers are >= 0 and < 1.
    Last edited by skyglin; 10-10-2003 at 10:16 AM.

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    I added the following line before the assignment of *node_ptr.
    Code:
    printf("*temp_x1(%f) + *temp_x2(%f) = %f; *nodePtr = ",
                 *temp_x1, *temp_x2, *temp_x1 + *temp_x2);
    The results I found were as follows.
    Code:
    *temp_x1(0.122841) + *temp_x2(0.102683) = 0.225524; *nodePtr = -0.548953
    *temp_x1(0.102683) + *temp_x2(-0.548953) = -0.446270; *nodePtr = -1.892539
    *temp_x1(-0.548953) + *temp_x2(-1.892539) = -2.441492; *nodePtr = -1.882984
    *temp_x1(-1.892539) + *temp_x2(-1.882984) = -3.775523; *nodePtr = -2.551046
    *temp_x1(-1.882984) + *temp_x2(-2.551046) = -4.434030; *nodePtr = -1.868060
    *temp_x1(-2.551046) + *temp_x2(-1.868060) = -4.419106; *nodePtr = -1.838212
    *temp_x1(-1.868060) + *temp_x2(-1.838212) = -3.706272; *nodePtr = -2.412544
    *temp_x1(-1.838212) + *temp_x2(-2.412544) = -4.250756; *nodePtr = -1.501512
    0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    Here, the 'x' value presented to fmod is not necessarily in the interval [0,1).
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    Registered User
    Join Date
    Jun 2003
    Posts
    28
    Thanks, I see.
    Now my problem is what I should modify so it will generate floating numbers between -1 to 1 using X(n+1) = (X(n) + X(n-1)) % 1.0. The initial two points must be in the interval [0, 1).

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    How about this?
    Code:
    *nodePtr = fmod(fabs(*temp_x1 + *temp_x2), 1.0) * 2.0 - 1.0;
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  7. #7
    Registered User
    Join Date
    Jun 2003
    Posts
    28
    this will work, but the numbers generated are not uniformaly distributed in the interval [-1, 1), almost all the points lies in [-1, -0.9) if 1000000 numbers are generated.

    what I did was first generated 1000000 numbers in the interval [0, 1), then in another for loop traverse through the list and mulitply each number by 2 and subtract 1. This gives me an unifomaly distrubuted number in [-1, 1).

    thanks Dave_Sinkula, really appreciated your help!!

Popular pages Recent additions subscribe to a feed