Differences between revisions 1 and 17 (spanning 16 versions)
Revision 1 as of 2008-05-19 08:51:57
Size: 1189
Comment:
Revision 17 as of 2010-03-01 14:31:31
Size: 4660
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
= Treatment of Unknown Functions = This page documents the implementation of external functions in Dynare 4. We call ''external functions'' those functions that are not part of the small set of functions natively supported by Dynare (e.g., log, exp, etc). Essentially, this feature allows Dynare 4 to operate on any user-defined (or built-in Matlab) function. For the remainder of this wiki, we assume that the user wants to use a function called {{{funcname}}} in her model.
Line 3: Line 3:
 I. Functions and their derivatives are declared by user via a keyword
 I. Functions are *.m files or Matlab primitives or the the function is declared by the user but the derivative isn't provided
 we must call a numerical derivator
  a. these functions have an arbitrary number of arguments
  a. this can only be implemented for first or second order derivatives
  a. it is necessary to know if we are dealing with first or second derivatives to call the right numerical derivator
  a. the numerical derivator (jacobian or hessian) returns an array
  a. each derivative is function of the derivatives of the arguments and the derivatives of the function
   Example:
   {{{
    F(y_1,y_2,...,y_k)
    D(F,x_i) = D(F,y_1)*D(y_1,x_i)+D(F,y_2)*D(y_2,x_i)+...D(F,y_k)*D(y_k,x_i)
    D^2(F,x_i,x_j) = D^2(F,y_1,y_1)*D(y_1,x_i)*D(y_1,x_j)+...+D^2(F,y_1,y_k)*D(y_1,x_i)*D(y_k,x_j)+..+D^2(F,y_k,y_k)*D(y_k,x_i)*D(y_k,x_j)
                     +D(F,y_1)*D^2(y_1,x_i,x_j)+...+D(F,y_k)*D^2(y_k,x_i,x_j)
   }}}
  a. because the number of arguments and derivatives are arbitrary, it is necessary to introduce some sort of array type in the parser
= The External Function =
The function can be implemented through a M-file or a MEX file (hereafter, M-/MEX file) located on the MATLAB path. '''NB:''' This includes built-in MATLAB functions.

From the mathematical point of view, this function is supposed to be of type <<latex(\usepackage{amsfonts} % $\mathbb{R}^n \rightarrow \mathbb{R}$)>>. In other words, it can accept any number of real arguments, but returns only one real argument.

There are two ways in which the user can provide the derivative of {{{funcname}}} to Dynare:

 1. '''Provide the first (and possibly second) derivatives in the same M-/MEX file as the function itself:''' The first derivative will be the second return argument (the Jacobian, in a vector) and the second derivative will be the third return argument (the Hessian, in a matrix).
 1. '''Provide the first (and possibly second) derivatives in separate M-/MEX files:''' In this case, the only return argument to these functions will be a vector in the case of the Jacobian and a matrix in the case of the Hessian.

'''Further, the user has the option to provide neither the first nor the second derivative of {{{funcname}}}.''' In this case (and in the case when the first derivative is provided but the second is not), Dynare will calculate the missing derivatives numerically using finite differences methods (central differences for the Jacobian and eqs. 25.3.24 and 25.3.27 from [[http://mintaka.sdsu.edu/faculty/wfw/ABRAMOWITZ-STEGUN/page_884.htm|Abramowitz and Stegun (1965), pg 884]] for the Hessian);

=== Example ===
1. The case when one M-/MEX file contains the function output, its Jacobian and Hessian:
{{{
function [y df d2f]=funcname(a,b)
y=a*(b^2);

da=b^2;
db=2*a*b;
df=[da db];

d2f=[0 2*b; 2*b 2*a];
end
}}}

2. The case when there is a separate M-/MEX file for {{{funcname}}} and its derivative, {{{funcname_deriv}}}:
{{{
function y=funcname(a,b)
y=a*(b^2);
end

function df=funcname_deriv(a,b)
da=b^2;
db=2*a*b;
df=[da db];
end
}}}

= User Syntax in the .mod file =

The keyword {{{external_function}}} is reserved for the declaration of external functions. It accepts the following options:
 * {{{name = STRING}}}: the name of the function, which must also be the name of the M-/MEX file implementing it.
 * {{{nargs = INTEGER}}}: the number of arguments of the function. If this option is not provided, Dynare assumes {{{nargs = 1}}}.
 * {{{first_deriv_provided}}}: tells Dynare that the M-/MEX file specified by the argument passed to {{{name}}} returns the Jacobian as its second output argument.
 * {{{first_deriv_provided = STRING}}}: tells Dynare that the Jacobian is provided as the only output of the M-/MEX file given as the option argument.
 * {{{second_deriv_provided}}}: tells Dynare that the M-/MEX file specified by the argument passed to {{{name}}} returns the Hessian as its third output argument.
 * {{{second_deriv_provided = STRING}}}: tells Dynare that the Hessian is provided as the only output of the M-/MEX file given as the option argument.

An {{{external_function}}} statement must be used once for every external function referenced in the {{{model_block}}}. Further, the statement must be issued somewhere before the {{{model_block}}}. The user does not need to include an {{{external_function}}} statement for external functions referenced outside of the {{{model_block}}}.

=== Examples ===

1. Declare an external function with name {{{funcname}}}, accepting only one argument, whose derivatives must be computed numerically by Dynare:
{{{
external_function(name = funcname);
}}}
2. Declare an external function with name {{{funcname}}}, accepting two arguments, whose derivatives are returned as the second and third output arguments of the M-/MEX file {{{funcname}}}:
{{{
external_function(name = funcname, nargs = 2, first_deriv_provided, second_deriv_provided);
}}}
3. Declare an external function with three arguments, whose first derivative is provided by the M-/MEX file {{{funcname_deriv}}}, and whose second derivative must be computed numerically by Dynare:
{{{
external_function(name = funcname, nargs = 3, first_deriv_provided = funcname_deriv);
}}}

This page documents the implementation of external functions in Dynare 4. We call external functions those functions that are not part of the small set of functions natively supported by Dynare (e.g., log, exp, etc). Essentially, this feature allows Dynare 4 to operate on any user-defined (or built-in Matlab) function. For the remainder of this wiki, we assume that the user wants to use a function called funcname in her model.

The External Function

The function can be implemented through a M-file or a MEX file (hereafter, M-/MEX file) located on the MATLAB path. NB: This includes built-in MATLAB functions.

From the mathematical point of view, this function is supposed to be of type  $\mathbb{R}^n \rightarrow \mathbb{R}$. In other words, it can accept any number of real arguments, but returns only one real argument.

There are two ways in which the user can provide the derivative of funcname to Dynare:

  1. Provide the first (and possibly second) derivatives in the same M-/MEX file as the function itself: The first derivative will be the second return argument (the Jacobian, in a vector) and the second derivative will be the third return argument (the Hessian, in a matrix).

  2. Provide the first (and possibly second) derivatives in separate M-/MEX files: In this case, the only return argument to these functions will be a vector in the case of the Jacobian and a matrix in the case of the Hessian.

Further, the user has the option to provide neither the first nor the second derivative of funcname. In this case (and in the case when the first derivative is provided but the second is not), Dynare will calculate the missing derivatives numerically using finite differences methods (central differences for the Jacobian and eqs. 25.3.24 and 25.3.27 from Abramowitz and Stegun (1965), pg 884 for the Hessian);

Example

1. The case when one M-/MEX file contains the function output, its Jacobian and Hessian:

function [y df d2f]=funcname(a,b)
y=a*(b^2);

da=b^2;
db=2*a*b;
df=[da db];

d2f=[0 2*b; 2*b 2*a];
end

2. The case when there is a separate M-/MEX file for funcname and its derivative, funcname_deriv:

function y=funcname(a,b)
y=a*(b^2);
end

function df=funcname_deriv(a,b)
da=b^2;
db=2*a*b;
df=[da db];
end

User Syntax in the .mod file

The keyword external_function is reserved for the declaration of external functions. It accepts the following options:

  • name = STRING: the name of the function, which must also be the name of the M-/MEX file implementing it.

  • nargs = INTEGER: the number of arguments of the function. If this option is not provided, Dynare assumes nargs = 1.

  • first_deriv_provided: tells Dynare that the M-/MEX file specified by the argument passed to name returns the Jacobian as its second output argument.

  • first_deriv_provided = STRING: tells Dynare that the Jacobian is provided as the only output of the M-/MEX file given as the option argument.

  • second_deriv_provided: tells Dynare that the M-/MEX file specified by the argument passed to name returns the Hessian as its third output argument.

  • second_deriv_provided = STRING: tells Dynare that the Hessian is provided as the only output of the M-/MEX file given as the option argument.

An external_function statement must be used once for every external function referenced in the model_block. Further, the statement must be issued somewhere before the model_block. The user does not need to include an external_function statement for external functions referenced outside of the model_block.

Examples

1. Declare an external function with name funcname, accepting only one argument, whose derivatives must be computed numerically by Dynare:

external_function(name = funcname);

2. Declare an external function with name funcname, accepting two arguments, whose derivatives are returned as the second and third output arguments of the M-/MEX file funcname:

external_function(name = funcname, nargs = 2, first_deriv_provided, second_deriv_provided);

3. Declare an external function with three arguments, whose first derivative is provided by the M-/MEX file funcname_deriv, and whose second derivative must be computed numerically by Dynare:

external_function(name = funcname, nargs = 3, first_deriv_provided = funcname_deriv);

DynareWiki: ExternalFunctions (last edited 2010-03-01 14:31:31 by HoutanBastani)