SAS code for solving dynamic non-linear models - sas

Could anyone suggest some SAS code to solve a small non-linear dynamic model? The model endogenous variables are:
log(consumption)
log(investment)
log(price level)
short term interest rate
long term interest rate
output.
I have tried to use the proc model but I'm having convergence problems due to the fact that the output identity is in level terms and the equations for the demand components are in log terms.
thank you
===========
thank you everybody for the answers/comments. The code I'm using for the estimation is:
proc model outmodel=fair_model;
var py rs delta_log_e rb log_pm ys DUM1997 e rs_us pop py_us y i t c x im stat;
parms c0-c3 i0-i2 p0-p4 r0-r4 b0-b4 e0-e3;
eq.Consumption = c0 + c1*lag(log(c/pop)) + c2*rb + c3*log(y/pop) - log(c/pop);
eq.Investment = i0 + i1*lag(log(i/y)) + i2*rb - log(i/y);
eq.Price = p0 + p1*lag(log(py)) + p2*log_pm + p3*(y/ys-1) + p4*t - log(py);
eq.Interest_Rate = r0 + r1*lag(rs) + r2*((py-lag4(py))/lag4(py)) + r3*(y/ys-1) + r4*DUM1997 - rs;
eq.Int_Rate = b0 + b1*(lag1(rb)- lag2(rs)) + b2*(rs-lag2(rs)) + b3*(lag1(rs)- lag2(rs)) +b4*(lag2(rs)) - rb;
eq.Exchange_Rate = e0 + e1*lag(delta_log_e) + e2*(log(py/py_us)-log(lag(e))) + e3*(log((1+rs/100)/(1+rs_us/100))) - delta_log_e;
eq.income = c + i + g + x - im + stat - y;
run;
quit;
*Fitting the data with the model, getting the estimates;
proc model model=fair_model outmodel=fair_model;
fit Consumption Investment Price Interest_Rate Int_Rate Exchange_Rate/data=fair2 outest=outest2 n2sls;
instruments log_pm del_y del_py g x im del_log_i;
run;
quit;
and then just using the solve command for solving the model and running simulations. One problem appears to be related to the income identity that is specified in levels while the other equation are specified in log terms. I have tried to respecified the c and i in the income equation as exp(log(c)) and exp(log(i)) and even tried to used an approximated income identity in log terms but it has not helped with the convergence issue. Any further thought would be much appreciated.

PROC MODEL from SAS/ETS handles dynamic non-linear systems. Try doing a log transform on the variable output if you are having convergence issues. In addition, consider how your equations relate to each other. Below is just a hypothetical, but be sure that you are using the right fitting method. Are they SUR models, or do they need 2SLS? Could FIML be a good method to fit it? If ITOLS is not working, you'll want to reconsider the model structure and how you go about fitting it.
proc model data=have;
endo log_consumption log_investment
log_price_level short_term_int
long_term_int log_output;
log_consumption = int1 + b1*log_investment b2*log_price_level + b3*short_term_int;
log_investment = int2 + b3*log_consumption + b4*log_price_level;
<other models>;
log_output = int6 + b20*log_consumption + b21*log_price_level + b22*short_term_int;
fit / FIML;
solve / dynamic;
run;

Related

SaS Scenario Generation

Can someone please help with the scenario below? I am very new to SaS and am not sure how to get this to work?
Simulate 200 observations from the following linear model:
Y = alpha + beta1 * X1 + beta2 * X2 + noise
where:
• alpha=1, beta1=2, beta2=-1.5
• X1 ~ N(1, 4), X2 ~ N(3,1), noise ~ N(0,1)
I have tried this code but not sure its completely accurate:
DATA ONE;
alpha = 1;
beta1 = 2;
beta2 = -1.5;
RUN;
DATA CALC;
SET ONE;
DO i = 1 to 200;
Y=alpha+beta1*X1+beta2*X2+Noise;
X1=Rannor(1);
X2=rannor(3);
Noise=ranuni(0);
OUTPUT;
END;
RUN;
PROC PRINT DATA=CALC;
RUN;
You need to have a look in the SAS help for the topics
"rannor","ranuni","generating random numbers",...
rannor: generating standard normal distributed RVs.
ranuni: uniform distributed RVs.
The argument in rannor is the seed number, not the expected value.
If N(x,y) in your example means that the random variable is normally distributed with expected value x and standard deviation y (or do you mean the variance???) then the code could be (have a look on the changed order of the statements; the definition of Y has to be after the definition of the random numbers...):
DATA ONE;
alpha = 1;
beta1 = 2;
beta2 = -1.5;
RUN;
DATA CALC;
SET ONE;
seed = 1234;
DO i = 1 to 200;
X1=1+4*Rannor(seed);
X2=3+rannor(seed);
Noise=rannor(seed);
Y=alpha+beta1*X1+beta2*X2+Noise;
OUTPUT;
END;
RUN;
PROC PRINT DATA=CALC;
RUN;
There are also variants for generating random numbers, e.g. "call rannor". There are different concepts to deal with seed numbers in SAS. See the SAS help for these topics, e.g. here

IML correlation from different matrices

given a matrix X(n * p), I want to split X into Y1(n * p-k) and Y2(n * k), where Y1 is composed by the first k columns of X and Y2 the others.
Now, in R I can get the "crossed" correlation between the columns of Y1 and Y2 calling cor(Y1,Y2, use="pairwise.complete.obs"), how can I get the same result in SAS IML where the corr function admits only 1 dataset?
I tried to find an appropriate solution or algorithm to implement it but with bad results.
Can anyone help with this? Also pointing me some literature about this kind or correlation would be great! I don't want you to code it for me, simply some help or hint on existing functions or algorithms to translate.
Thank you.
EDIT: don't search on the web for crossed correlation, I wrote it simply for trying to explain myself.
Looking up "crossed correlation" leads you to a series of literature on signal processing and a function much like the autocorrelation function. In fact, in R it is documented with acf https://stat.ethz.ch/R-manual/R-devel/library/stats/html/acf.html.
But that is not what your code is doing. In R:
n = 100
p = 6
k = 2
set.seed(1)
r = rnorm(n*p)
x= matrix(r,n,p)
y1 = x[,1:k]
y2 = x[,(k+1):p]
cor.ys = cor(y1,y2,use="pairwise.complete.obs")
cor.x = cor(x)
(cor.ys - cor.x[1:k,(k+1):p])
You see the result from cor(y1,y2) is just a piece of the correlation matrix from x.
You should be able to put this in IML easily.
I can think of a few ways to do this. The simplest is to compute the full matrix of Pearson correlations (using the pairwise option) and then subset the result. (What DomPazz said.) If you have hundreds of variables and you only want a few of the correlations, it will be inefficient, but it is very simple to program:
proc iml;
n = 100; p = 6; k = 2;
call randseed(1);
x = randfun(n//p, "Normal");
varNames = "x1":"x6";
corr = corr(x, "pearson", "pairwise"); /* full matrix */
idx1 = 1:k; /* specify VAR */
idx2 = (k+1):p; /* specify WITH */
withCorr = corr[idx2, idx1]; /* extract submatrix */
print withcorr[r=(varNames[idx2]) c=(varNames[idx1])];
Outside of SAS/IML you can use PROC CORR and the WITH statement to do the same computation, thereby validating your SAS/IML program:
proc corr data=test noprob nosimple;
var x1-x2;
with x3-x6;
run;

Solving for polynomial roots in Stata

I am trying to solve for the roots of a function in Stata. There is the "polyeval" command under Mata, but I am not sure how to apply it here. It seems to me as if under polyeval functions must follow a very clear structure of x^2 + x + c.
I would like to find out more about how to use Stata to solve this type of problem in general. But here is my current one, if that provides some idea of what I am working with.
I am currently trying to solve the Black (1976) American Options pricing model:
C = e^{-rt} [ F N(d1) - E N(d2)]
where,
d1 = [ln(F/E) + 1/2 simga^2 t] / [sigma sqrt{t}]
d2 = d1 - sigma sqrt{t}
where C is the price of call option, t is time to expiration, r is interest rate, F is current futures price of contract, E is strike price, sigma is the annualized standard deviation of the futures contract. N(d1) and N(d2) are cumulative normal probability functions. All variables are known except for sigma.
As an aside, this seems to be really easy to do in R:
fun <- function(sigma) exp(-int.rate* T) * (futures * pnorm((log(futures/Strike)+ sigma^2 * T/2) / sigma * sqrt(T),0,1)- Strike * pnorm((log(futures/Strike)+ sigma^2 * T/2) / sigma * sqrt(T)- sigma * sqrt(T),0,1) ) - Option
uni <- uniroot(fun, c(0, 1), tol = 0.001 )
uni$root
Does anyone have any ideas/pointers on how to use Stata to solve this type of function?

Polynomial fitting using L1-norm

I have n points (x0,y0),(x1,y1)...(xn,yn). n is small (10-20). I want to fit these points with a low order (3-4) polynomial: P(x)=a0+a1*x+a2*x^2+a3*x^3.
I have accomplished this using least squares as error metric, i.e. minimize f=(p0-y0)^2+(p1-y1)^2+...+(pn-yn)^2. My solution is utilizing singular value decomposition (SVD).
Now I want to use L1 norm (absolute value distance) as error metric, i.e. minimize f=|p0-y0|+|p1-y1|+...+|pn-yn|.
Are there any libraries (preferably open source) which can do this, and that can be called from C++? Is there any source code available which can be quickly modified to suit my needs?
L_1 regression is actually quite simply formulated as a linear program. You want to
minimize error
subject to x_1^4 * a_4 + x_1^3 * a_3 + x_1^2 * a_2 + x_1 * a_1 + a_0 + e_1 >= y_1
x_1^4 * a_4 + x_1^3 * a_3 + x_1^2 * a_2 + x_1 * a_1 + a_0 - e_1 <= y_1
.
.
.
x_n^4 * a_4 + x_n^3 * a_3 + x_n^2 * a_2 + x_n * a_1 + a_0 + e_n >= y_n
x_n^4 * a_4 + x_n^3 * a_3 + x_n^2 * a_2 + x_n * a_1 + a_0 - e_n <= y_n
error - e_1 - e_2 - ... - e_n = 0.
Your variables are a_0, a_1, a_2, a_3, a_4, error, and all of the e variables. x and y are the data of your problem, so it's no problem that x appears to second, third, and fourth powers.
You can solve linear programming problems with GLPK (GPL) or lp_solve (LGPL) or any number of commercial packages. I like GLPK and I recommend using it if its licence is not a problem.
Yes, it should be doable. A standard way of formulating polynomial fitting problems as a multiple linear regression is to define variables x1, x2, etc., where xn is defined as x.^n (element-wise exponentiation in Matlab notation). Then you can concatenate all these vectors, including an intercept, into a design matrix X:
X = [ 1 x1 x2 x3 ]
Then your polynomial fitting problem is a regression problem:
argmin_a ( | y - X * a| )
where the | | notation is your desired cost function (for your case, L1 norm) and a is a vector of weights (sorry, SO doesn't have good math markups as far as I can tell). Regressions of this sort are known as "robust regressions," and Numerical Recipes has a routine to compute them: http://www.aip.de/groups/soe/local/numres/bookfpdf/f15-7.pdf
Hope this helps!
The problem with the L1 norm is that it's not differentiable, so any minimisers which rely on derivatives may fail. When I've tried to minimise those kinds of functions using e.g. conjugate gradient minimisation, I find that the answer gets stuck at the kink, i.e. x=0 in the function y=|x|.
I often solve these mathematical computing problems from first principles. One idea that might work here is that the target function is going to be piecewise linear in the coefficients of your low-order polynomial. So it might be possible to solve by starting from the polynomial that comes out of least squares, and then improving the solution by solving a series of linear problems, but each time only stepping from your current best solution to the nearest kink.

Precision of cos(atan2(y,x)) versus using complex <double>, C++

I'm writing some coordinate transformations (more specifically the Joukoswky Transform, Wikipedia Joukowsky Transform), and I'm interested in performance, but of course precision. I'm trying to do the coordinate transformations in two ways:
1) Calculating the real and complex parts in separate, using double precision, as below:
double r2 = chi.x*chi.x + chi.y*chi.y;
//double sq = pow(r2,-0.5*n) + pow(r2,0.5*n); //slow!!!
double sq = sqrt(r2); //way faster!
double co = cos(atan2(chi.y,chi.x));
double si = sin(atan2(chi.y,chi.x));
Z.x = 0.5*(co*sq + co/sq);
Z.y = 0.5*si*sq;
where chi and Z are simple structures with double x and y as members.
2) Using complex :
Z = 0.5 * (chi + (1.0 / chi));
Where Z and chi are complex . There interesting part is that indeed the case 1) is faster (about 20%), but the precision is bad, giving error in the third decimal number after the comma after the inverse transform, while the complex gives back the exact number.
So, the problem is on the cos(atan2), sin(atan2)? But if it is, how the complex handles that?
EDIT: Just figured out that this was not exactly the question that I had in mind. I have to do the general transformation, as
Z = 1/2*(chi^n + (1/chi)^n), and so far the code above was the way I've figured to do it. More precisely,
double sq = pow(sqrt(r2),n); //way faster!
double co = cos(n*atan2(chi.y,chi.x));
double si = sin(n*atan2(chi.y,chi.x));
Z.x = 0.5*(co*sq + co/sq);
Z.y = 0.5*(si*sq - sq/si);
Also correcting the bug on Z.y.
Given r = sqrt(x*x+y*y):
cos(atan2(y,x)) == x/r
sin(atan2(y,x)) == y/r
Calculating it this way should be more accurate and faster.
When you plug these values into the formulas for Z.x and Z.y, the square root will cancel out as well, so you'll be left with only basic arithmetic operations.
I think that in 1) it should be
Z.y = 0.5*(si*sq - si/sq);
If you want really good performance you may want to go back to first principles and observe that
1/(a+ib) = (a-ib)/(a*a+b*b)
No sqrt(), atan2() or cos() or sin().