[Developers] fixing init_number_vector without a plan
Johnoel Ancheta
johnoel at hawaii.edu
Wed Apr 4 19:28:37 PDT 2012
Geez, that is cool. Thanks Dave, this is a great way to do code
testing. I'll work on this tomorrow or you can commit the fix.
Johnoel
On Wed, Apr 4, 2012 at 2:14 PM, dave fournier <davef at otter-rsch.com> wrote:
>
> At our workshop Mark pointed out some problem with the init_number_vector
> class for RE models.
> I have identified some serious problems that are not so easy to fix so I
> wondered if, as an exercise
> it would be easy to use some C++ capabilities to introduce a new class
> which works better,
> without having to modify the existing code. This sort of programming
> typically uses virtual
> functions.
>
> One starts with the df1b2_init_vector class which is what gets invoked
> when you use an init_vector
> in an RE model. Now the problem with a df1b2_init_vector is that it only
> has an int for its starting phase. Since we want the different elements
> of the vector to have their own starting phase we will add that to the
> class.
> Sow we derive a new class xdf1b2_init_number_vector from
> public df1b2_init_vector and add what we need to it.
>
> class xdf1b2_init_number_vector : public df1b2_init_vector
> {
> index_type * it;
>
> // ... other stuff
>
> };
>
> all that is needed is a pointer to index_type. This will permit the use
> of a vector or a number to specify the starting phases. If a number is used
> they will all be the same.
>
> Now what you can do is to use the class in a toy program.
> Start with a tpl file like this.
> **********************************************************
> **********************************************************
>
> DATA_SECTION
> int n
> !! n=2;
> ivector st(1,n)
> !! st(1)=1;
> !! st(2)=-1;
>
>
> PARAMETER_SECTION
> init_number_vector beta(1,n,st)
> random_effects_vector eps(1,1)
>
> objective_function_value f
>
> PROCEDURE_SECTION
> f+=0.5*norm2(eps);
> for (int i=1;i<=n;i++)
> {
> f+= square(beta(i)-1.0);
> }
>
> GLOBALS_SECTION
>
>
> #include <admodel.h>
> #include <df1b2fun.h>
> #include <adrndeff.h>
> class xdf1b2_init_number_vector : public df1b2_init_vector
> {
> index_type * it;
> public:
> xdf1b2_init_number_vector(**void);
>
> void allocate(int imin,int imax,const index_type& ps,char * s)
> {
> df1b2_init_vector::allocate(**imin,imax,s);
> it=new index_type(ps);
> }
>
> };
>
> xdf1b2_init_number_vector::**xdf1b2_init_number_vector(**void):
> df1b2_init_vector()
> {
> it=0;
> }
>
> **********************************************************
> **********************************************************
> **********************************************************
> **********************************************************
>
> Run tpl2rem on this tpl file and change
>
> df1b2_init_number_vector to xdf1b2_init_number_vector
>
> in the cpp and htp files and compile with debug and safe mode.
> When you run the model you will ifnd that it runs out of an array
> in
> void df1b2_init_vector set_value(const init_df1b2vector& _x,const int&
> _ii,
> const df1b2variable& pen);
>
> The reason is that it is using the starting phase number from that class.
> To change that behaviour we just need override the set_value function
> with a new one in the derived class. It looks like this.
>
>
>
> void xdf1b2_init_number_vector::**set_value(const init_df1b2vector& x,
> const int& _ii,const df1b2variable& pen)
> {
> ADUNCONST(int,ii)
> int mmin=indexmin();
> int mmax=indexmax();
> for (int i=mmin;i<=mmax;i++)
> {
> if (withinbound(0,ad_integer((***it)(i)),current_phase))
> (*this)(i) = (x(ii++));
> }
> }
>
> The change is
>
> if (withinbound(0,ad_integer((***it)(i)),current_phase)
>
> which has been added to the function.
> The class declaration is extended to
>
> class xdf1b2_init_number_vector : public df1b2_init_vector
> {
> index_type * it;
> public:
> xdf1b2_init_number_vector(**void);
>
> void allocate(int imin,int imax,const index_type& ps,char * s)
> {
> df1b2_init_vector::allocate(**imin,imax,s);
> it=new index_type(ps);
> }
> virtual void set_value(const init_df1b2vector& _x,const int& _ii,
> const df1b2variable& pen);
> };
>
> It seems to work, although there may be some other functions which will
> need
> to be overridden as well.
>
> What's my point? Well no planning or committees were needed. All I had
> to do was to run the code with the debugger and it told me what to do.
> Entire
> process took about two hours.
>
> Time for a drink.
>
>
> ______________________________**_________________
> Developers mailing list
> Developers at admb-project.org
> http://lists.admb-project.org/**mailman/listinfo/developers<http://lists.admb-project.org/mailman/listinfo/developers>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.admb-project.org/pipermail/developers/attachments/20120404/06e476d1/attachment.html>
More information about the Developers
mailing list