Statalist


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Re: st: passing optional arguments to functions in Mata


From   Glenn Goldsmith <[email protected]>
To   [email protected]
Subject   RE: Re: st: passing optional arguments to functions in Mata
Date   Tue, 16 Jun 2009 22:28:20 +0100

Hi Nathan,

Stas' solution is good for the specific example you gave (passing
exactly one argument).

More generally, if you want to be able to pass a variable number of
arguments to the inner function, something like the code below may be
useful (omitted code identical to the original except where
indicated):

****************************************************************
scalar NDint(	                                                    	
  pointer(real scalar function) scalar f,
  real scalar lower,
  real scalar higher,
  real scalar m,
  | z1, z2, z3, z4, z5, z6, z7)												
{
...
  for (i=1; i<=n; i++) {
    x = lower + ((i-1)*width)
    if (args()==4) Y[i,1]  = (*f)(x)
    if (args()==5) Y[i,1]  = (*f)(x,z1)
    if (args()==6) Y[i,1]  = (*f)(x,z1, z2)
    if (args()==7) Y[i,1]  = (*f)(x,z1, z2, z3)
    if (args()==8) Y[i,1]  = (*f)(x,z1, z2, z3, z4)
    if (args()==9) Y[i,1]  = (*f)(x,z1, z2, z3, z4, z5)
    if (args()==10) Y[i,1]  = (*f)(x,z1, z2, z3, z4, z5, z6)
    if (args()==11) Y[i,1]  = (*f)(x,z1, z2, z3, z4, z5, z6, z7)
  }
...
}

*********************************************************************

HTH,

Glenn.

Stas Kolenikov <[email protected]> wrote:

Shouldn't just

(*f)(x,z)

work? Of course z needs to be defined in NDint().

A weaker option is to use -external- declarations. That makes the code
messy and occasion-specific, which given your style you probably won't
like :))

On 6/16/09, Nathan Danneman <[email protected]> wrote:
> Hi all,
>
>  I have written a function for a part of a larger program.  This
>  program generates a numeric integral for a function that it calls.  I
>  would like to allow the outter function to pass several optional
>  arguments (between zero and seven) on to the called function which is
>  being integrated, which could then pass those arguments on to another
>  lower-level function...etc.  The code for the integration function is
>  below.  In the pasted example, I integrate the function named "trial"
>  at bottom.  As a very simple example, how could I get the overall
>  function, NDint, to pass the z parameter on to "trial"?
>
>  Thanks,
>  Nathan
>
>
>  //An n-slice integration routine using simpson's approximation
>
>  mata
>  mata clear
>  mata set matalnum off
>
>  scalar NDint(
>    // to perform integration via simpson'sapproximation
>  pointer(real scalar function) scalar f,
>                 //points to the functionto be integrated
>  real scalar lower,
>                  //lower bound of integration
>  real scalar higher,
>                  //upper bound
>  real scalar m)                                                                                          // where m = number of slices, must be an EVEN number
>  {
>
>   if ( (m/2) != (floor(m/2)) ) _error("m must be an EVEN number")
>
>   real scalar width                                                                                              //I like declarations, your mileage may vary
>   real colvector Y
>   real rowvector X
>   real scalar n                                                                                          //slices plus one
>
>   n = m+1
>
>   if (lower > higher) _error("limits of integration reversed")
>                           //make sure upper > lower NB: better to use _error() than
>  return()
>
>   width = (higher-lower) / m
>                //calculates width of each "slice"
>
>   Y = J(n,1,.)
>                //creates an empty 15 x 1 column vector
>   for (i=1; i<=n; i++) {
>     x = lower + ((i-1)*width)
>     Y[i,1]  = (*f)(x)
>                  //places function evaluations directly into Y,
>  avoiding all the copying you were doing previously
>   }
>
>   X = J(1,n,.)
>   for (i=1;i<=n; i++) {
>   if (i==1) X[1,i] = 1
>   if (i==n) X[1,i] = 1
>   if ((i/2) == (floor(i/2))) X[1,i] = 4
>   if ( ((i+1)/2) == (floor( ((i+1)/2)) ) & (i!=1) & (i!=n) ) X[1,i] = 2
>  }
>
>
>  return(X*Y*width/3)                                                       //matrix multiplication makes this quicker
>  and more readable
>
>  }
>
>  scalar trial(real scalar x) {
>                                                                                           //declares the output to be a scalar. otherwise
>  you could run into problems in the main program
>   return(z*exp(x))
>  }
>
>  f = &trial()
>
>  NDint(f, 0, 4, 60)
>
>  end
>
>
>
>  --
>  "Imagination is more important than knowledge..."
>       -- Albert Einstein
>  *
>  *   For searches and help try:
>  *   http://www.stata.com/help.cgi?search
>  *   http://www.stata.com/support/statalist/faq
>  *   http://www.ats.ucla.edu/stat/stata/
>


-- 
Stas Kolenikov, also found at http://stas.kolenikov.name
Small print: I use this email account for mailing lists
*
*   For searches and help try:
*   http://www.stata.com/help.cgi?search
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2024 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index