git-svn-id: http://moon:8086/svn/matlab/trunk@91 801c6759-fa7c-4059-a304-17956f83a07c
116 lines
2.4 KiB
C
116 lines
2.4 KiB
C
#include <math.h>
|
|
#include "mex.h"
|
|
|
|
/* See lbfgs.m for details! */
|
|
/* This function may not exit gracefully on bad input! */
|
|
|
|
|
|
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|
{
|
|
/* Variable Declarations */
|
|
|
|
double *s, *y, *g, *H, *d, *ro, *alpha, *beta, *q, *r;
|
|
int nVars,nSteps,lhs_dims[2];
|
|
double temp;
|
|
int i,j;
|
|
|
|
/* Get Input Pointers */
|
|
|
|
g = mxGetPr(prhs[0]);
|
|
s = mxGetPr(prhs[1]);
|
|
y = mxGetPr(prhs[2]);
|
|
H = mxGetPr(prhs[3]);
|
|
|
|
/* Compute number of variables (p), rank of update (d) */
|
|
|
|
nVars = mxGetDimensions(prhs[1])[0];
|
|
nSteps = mxGetDimensions(prhs[1])[1];
|
|
|
|
/* Allocated Memory for Function Variables */
|
|
ro = mxCalloc(nSteps,sizeof(double));
|
|
alpha = mxCalloc(nSteps,sizeof(double));
|
|
beta = mxCalloc(nSteps,sizeof(double));
|
|
q = mxCalloc(nVars*(nSteps+1),sizeof(double));
|
|
r = mxCalloc(nVars*(nSteps+1),sizeof(double));
|
|
|
|
/* Set-up Output Vector */
|
|
|
|
lhs_dims[0] = nVars;
|
|
lhs_dims[1] = 1;
|
|
|
|
plhs[0] = mxCreateNumericArray(2,lhs_dims,mxDOUBLE_CLASS,mxREAL);
|
|
d = mxGetPr(plhs[0]);
|
|
|
|
/* ro = 1/(y(:,i)'*s(:,i)) */
|
|
for(i=0;i<nSteps;i++)
|
|
{
|
|
temp = 0;
|
|
for(j=0;j<nVars;j++)
|
|
{
|
|
temp += y[j+nVars*i]*s[j+nVars*i];
|
|
}
|
|
ro[i] = 1/temp;
|
|
}
|
|
|
|
/* q(:,k+1) = g */
|
|
for(i=0;i<nVars;i++)
|
|
{
|
|
q[i+nVars*nSteps] = g[i];
|
|
}
|
|
|
|
for(i=nSteps-1;i>=0;i--)
|
|
{
|
|
/* alpha(i) = ro(i)*s(:,i)'*q(:,i+1) */
|
|
alpha[i] = 0;
|
|
for(j=0;j<nVars;j++)
|
|
{
|
|
alpha[i] += s[j+nVars*i]*q[j+nVars*(i+1)];
|
|
}
|
|
alpha[i] *= ro[i];
|
|
|
|
/* q(:,i) = q(:,i+1)-alpha(i)*y(:,i) */
|
|
for(j=0;j<nVars;j++)
|
|
{
|
|
q[j+nVars*i]=q[j+nVars*(i+1)]-alpha[i]*y[j+nVars*i];
|
|
}
|
|
}
|
|
|
|
/* r(:,1) = q(:,1) */
|
|
for(i=0;i<nVars;i++)
|
|
{
|
|
r[i] = H[0]*q[i];
|
|
}
|
|
|
|
for(i=0;i<nSteps;i++)
|
|
{
|
|
/* beta(i) = ro(i)*y(:,i)'*r(:,i) */
|
|
beta[i] = 0;
|
|
for(j=0;j<nVars;j++)
|
|
{
|
|
beta[i] += y[j+nVars*i]*r[j+nVars*i];
|
|
}
|
|
beta[i] *= ro[i];
|
|
|
|
/* r(:,i+1) = r(:,i) + s(:,i)*(alpha(i)-beta(i)) */
|
|
for(j=0;j<nVars;j++)
|
|
{
|
|
r[j+nVars*(i+1)]=r[j+nVars*i]+s[j+nVars*i]*(alpha[i]-beta[i]);
|
|
}
|
|
}
|
|
|
|
/* d = r(:,k+1) */
|
|
for(i=0;i<nVars;i++)
|
|
{
|
|
d[i]=r[i+nVars*nSteps];
|
|
}
|
|
|
|
/* Free Memory */
|
|
|
|
mxFree(ro);
|
|
mxFree(alpha);
|
|
mxFree(beta);
|
|
mxFree(q);
|
|
mxFree(r);
|
|
|
|
}
|