[Developers] fixing init_number_vector without a plan
dave fournier
davef at otter-rsch.com
Wed Apr 4 19:42:08 PDT 2012
On 12-04-04 07:28 PM, Johnoel Ancheta wrote:
Well it needs more work first. I just wanted to illustrate an approach.
> 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
> <mailto: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 <mailto:Developers at admb-project.org>
> 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/69c92cd5/attachment-0001.html>
More information about the Developers
mailing list