CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 17
  1. #1
    Join Date
    May 2001
    Location
    Mobile, AL.
    Posts
    64

    Question initializing static array

    I am writing a class which will have a static array. I need to initialize the array using a for loop. There will be several instances of the class, each of which will read values from the array. The instances need to treat the array as "constant". The code to initialize the array needs to be executed only once, not once for each instance.

    Can I do all of this, and what is the syntax?
    Last edited by bsaucer; November 20th, 2009 at 01:47 PM. Reason: duplicate word

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: initializing static array

    Are the values of the array known at compile time? If so, you can use initialiser syntax, and your job becomes very simple.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: initializing static array

    I suppose that you could write an object which takes the array pointer (and size) as an argument to its constructor, and then fills it there. Then just declare this object statically or globally.

    This is more or less the approach taken by the Boost.Assignment library for the list_of syntax.

  4. #4
    Join Date
    Nov 2009
    Posts
    18

    Re: initializing static array

    If values are known at compile-time:
    http://www.velocityreviews.com/forum...n-a-class.html

    If you need to use the for-loop, or if the values will be calculated on the first call to the class, I think you'll either need a static Init() function, or you could have a static bool in the constructor that indicates whether it's the first object to be constructed, and only populate the array then.

    e.g.

    Code:
    MyClass::MyClass() {
      static bool isFirst = true;
      if (isFirst) {
        isFirst = false;
        // initialize the array...
      }
    }
    I'm not sure if there are any thread-safety issues with this approach.

  5. #5
    Join Date
    May 2001
    Location
    Mobile, AL.
    Posts
    64

    Re: initializing static array

    Let me clarify what I mean by "static". I mean that the array is a static member of the class.
    Last edited by bsaucer; November 20th, 2009 at 03:25 PM. Reason: spelling

  6. #6
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: initializing static array

    Quote Originally Posted by bsaucer
    Let mne clarify what I mean by "static". I mean that the array is a static member of the class.
    Yes, that was clear. A static member array can be initialised with initialiser syntax if its values are known at compile time (though it might be tedious if the array is large).
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  7. #7
    Join Date
    May 2001
    Location
    Mobile, AL.
    Posts
    64

    Re: initializing static array

    To answer your questions: The array is large. The values never change, but need to be calculated. Since this is a static member, the values should be available to other classes
    without creating any instances of the class.

    Can they be calculated at compile time? That would save a lot of execution time at run time. I just don't want to type in a large array of doubles.

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: initializing static array

    Quote Originally Posted by bsaucer View Post
    Can they be calculated at compile time?
    Depends -- lets see the formula.

    Regards,

    Paul McKenzie

  9. #9
    Join Date
    May 2001
    Location
    Mobile, AL.
    Posts
    64

    Re: initializing static array

    Code:
    	static const double		m_fCos[1024];
    	static const double		m_fSin[1024];
    	static void		Initialize(void);
    Code:
    void MyClass::Initialize(void)
    {
    	for (int i = 0; i < 1024; i++)
    	{
    		m_fCos[i] = cos(2 * M_PI * i / 1024.0);
    		m_fSin[i] = sin(2 * M_PI * i / 1024.0);
    	}
    }

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: initializing static array

    Go here:

    http://www.oonumerics.org/blitz/examples/fft.cpp

    Use the Taylor expansion instead of the function call. You will see template metaprogram version of sin() and cos(). You should use these in place of the arrays m_fCos and m_fSin.

    Example:
    Code:
    #define M_PI       3.14159265358979323846
    
    template<unsigned N, unsigned I>
    class Sine {
    public:
      static inline double sin()
      {
            return (I*2*M_PI/N)*(1-(I*2*M_PI/N)*(I*2*M_PI/N)/2/3*(1-(I*2*M_PI/N)*
               (I*2*M_PI/N)/4/5*(1-(I*2*M_PI/N)*(I*2*M_PI/N)/6/7*(1-(I*2*M_PI/N)*
               (I*2*M_PI/N)/8/9*(1-(I*2*M_PI/N)*(I*2*M_PI/N)/10/11*(1-(I*2*M_PI/N)*
               (I*2*M_PI/N)/12/13*(1-(I*2*M_PI/N)*(I*2*M_PI/N)/14/15*
               (1-(I*2*M_PI/N)*(I*2*M_PI/N)/16/17*
               (1-(I*2*M_PI/N)*(I*2*M_PI/N)/18/19*(1-(I*2*M_PI/N)*
               (I*2*M_PI/N)/20/21))))))))));
      }
    };
    
    
    template<unsigned N, unsigned I>
    class Cosine {
    public:
      static inline double cos()
      {
        // This is a series expansion for cos(I*2*M_PI/N)
        // Since all of these quantities are known at compile time, it gets
        // simplified to a single number.
        return 1-(I*2*M_PI/N)*(I*2*M_PI/N)/2*(1-(I*2*M_PI/N)*(I*2*M_PI/N)/3/4*
            (1-(I*2*M_PI/N)*(I*2*M_PI/N)/5/6*(1-(I*2*M_PI/N)*(I*2*M_PI/N)/7/8*
            (1-(I*2*M_PI/N)*(I*2*M_PI/N)/9/10*(1-(I*2*M_PI/N)*(I*2*M_PI/N)/11/12*
            (1-(I*2*M_PI/N)*(I*2*M_PI/N)/13/14*(1-(I*2*M_PI/N)*(I*2*M_PI/N)/15/16*
            (1-(I*2*M_PI/N)*(I*2*M_PI/N)/17/18*(1-(I*2*M_PI/N)*(I*2*M_PI/N)/19/20*
            (1-(I*2*M_PI/N)*(I*2*M_PI/N)/21/22*(1-(I*2*M_PI/N)*(I*2*M_PI/N)/23/24
            )))))))))));
      }
    
    };
    
    int main()
    {
        double value = Cosine<1024,2>::cos();
        // instead of initializing and then using m_fCos[2];
    }
    Note that there are no more arrays, but the values are computed at compile time using the template syntax.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; November 23rd, 2009 at 03:27 PM.

  11. #11
    Join Date
    May 2001
    Location
    Mobile, AL.
    Posts
    64

    Re: initializing static array

    In your main routine, you are passing literal constants 1024 and 2 to the template. What if I pass integer variables to the template? Does that mean calculations take place at runtime?

    My routine will be passing a variable index to the array each time. So either I store 1024 sines and cosines in memory in advance, or I calculate them on the fly. I need to avoid using too many floating point calculations in a time-constrained loop.

  12. #12
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: initializing static array

    The Boost MPL probably contains a way to do it. I'm not familiar enough with it to know exactly, how, though.

  13. #13
    Join Date
    Oct 2008
    Posts
    1,456

    Re: initializing static array

    Quote Originally Posted by Lindley View Post
    The Boost MPL probably contains a way to do it. I'm not familiar enough with it to know exactly, how, though.
    if the OP wants to initialize a look up table then MPL is of little help. But there's the boost preprocessor:

    something like

    Code:
    #define COSINE_LOOKUP(z,n,d) Cosine<d,n>::cos(),
    
    float Cosine_[] = { BOOST_PP_REPEAT(1024, COSINE_LOOKUP, 1024) };

  14. #14
    Join Date
    Apr 1999
    Posts
    27,449

    Re: initializing static array

    Quote Originally Posted by bsaucer View Post
    In your main routine, you are passing literal constants 1024 and 2 to the template. What if I pass integer variables to the template? Does that mean calculations take place at runtime?
    No, you can't pass variables to the template at runtime.

    According to your original requirements, you have two choices, but actually they are the same choice.

    Do this in one big initialization:
    Code:
    double m_fCos[] = {Cosine<1024,0>::cos(), 
                       Cosine<1024,1>::cos(),
                       Cosine<1024,2>::cos(),
                       Cosine<1024,3>::cos(),
                       Cosine<1024,4>::cos(),
                       Cosine<1024,5>::cos(),
                       Cosine<1024,6>::cos(),
                       Cosine<1024,7>::cos(),
                       Cosine<1024,8>::cos(),
                       Cosine<1024,9>::cos(),
                       Cosine<1024,10>::cos(),
                       Cosine<1024,11>::cos(),
                       Cosine<1024,12>::cos(),
                       Cosine<1024,13>::cos(),
                       Cosine<1024,14>::cos()
                    // etc..
    };
    Or use boost, as superbonzo shows in his post. The above and the boost solution is done purely at compile-time.
    So either I store 1024 sines and cosines in memory in advance,
    That is what is shown above.
    I need to avoid using too many floating point calculations in a time-constrained loop.
    Using the template, there are no floating point calculations done at runtime for sin and cos.

    Regards,

    Paul McKenzie

  15. #15
    Join Date
    May 2001
    Location
    Mobile, AL.
    Posts
    64

    Re: initializing static array

    Using the template, there are no floating point calculations done at runtime for sin and cos.
    Well, not counting the fact that I'm multiplying the cosines and sines by other things, plus a bunch of other number crunching (addition, multiplying, etc.)

    My solution: I wrote a VB.Net program that would generate a large header (.h) file initiallizing the entire arrays each with 1024 douoble values.

    Code:
    /**********************************************************/
    /* MyTable2.h                                             */
    /**********************************************************/
    #ifndef ADOUBLE
    #define ADOUBLE __declspec(align(32)) double
    #endif
    
    ADOUBLE aCos[] = {
        +1.000000000000000, +0.999981175282601, +0.999924701839145, +0.999830581795823,   //aCos[0] to aCos[3]
        +0.999698818696204, +0.999529417501093, +0.999322384588350, +0.999077727752645,   //aCos[4] to aCos[7]
        +0.998795456205172, +0.998475580573295, +0.998118112900149, +0.997723066644192,   //aCos[8] to aCos[11]
    ...
    
    ADOUBLE aSin[] = {
        +0.000000000000000, +0.006135884649154, +0.012271538285720, +0.018406729905805,   //aSin[0] to aSin[3]
        +0.024541228522912, +0.030674803176637, +0.036807222941359, +0.042938256934941,   //aSin[4] to aSin[7]
        +0.049067674327418, +0.055195244349690, +0.061320736302209, +0.067443919563664,   //aSin[8] to aSin[11]
    ...
    Of course I could include other tables, too.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured