Files
matlab/RBM/UFLDL/common/minFunc_2012/minFunc/mex/lbfgsProdC.c
T
jens 7b34529b24 imported RBM
git-svn-id: http://moon:8086/svn/matlab/trunk@91 801c6759-fa7c-4059-a304-17956f83a07c
2016-07-12 11:24:12 +00:00

94 lines
2.2 KiB
C

#include <math.h>
#include "mex.h"
/* See lbfgsProd.m for details */
/* This function will not exit gracefully on bad input! */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
/* Variable Declarations */
double *S, *Y, *YS, *g, Hdiag, *d, *alpha, *beta;
int i,j,nVars,nCor,maxCor,lbfgs_start,lbfgs_end;
/* Get Input Pointers */
g = mxGetPr(prhs[0]);
S = mxGetPr(prhs[1]);
Y = mxGetPr(prhs[2]);
YS= mxGetPr(prhs[3]);
lbfgs_start = (int)mxGetScalar(prhs[4]);
lbfgs_end = (int)mxGetScalar(prhs[5]);
Hdiag = mxGetScalar(prhs[6]);
if (!mxIsClass(prhs[4],"int32")||!mxIsClass(prhs[5],"int32"))
mexErrMsgTxt("lbfgs_start and lbfgs_end must be int32");
/* Compute number of variables, maximum number of corrections */
nVars = mxGetDimensions(prhs[1])[0];
maxCor = mxGetDimensions(prhs[1])[1];
/* Compute number of corrections available */
if (lbfgs_start == 1)
nCor = lbfgs_end-lbfgs_start+1;
else
nCor = maxCor;
/* Allocate Memory for Local Variables */
alpha = mxCalloc(nCor,sizeof(double));
beta = mxCalloc(nCor,sizeof(double));
/* Set-up Output Vector */
plhs[0] = mxCreateDoubleMatrix(nVars,1,mxREAL);
d = mxGetPr(plhs[0]);
for(j=0;j<nVars;j++)
d[j] = -g[j];
for(i = lbfgs_end-1;i >= 0;i--) {
alpha[i] = 0;
for(j=0;j<nVars;j++)
alpha[i] += S[j + nVars*i]*d[j];
alpha[i] /= YS[i];
for(j=0;j<nVars;j++)
d[j] -= alpha[i]*Y[j + nVars*i];
}
if(lbfgs_start != 1) {
for(i = maxCor-1;i >= lbfgs_start-1;i--) {
alpha[i] = 0;
for(j=0;j<nVars;j++)
alpha[i] += S[j + nVars*i]*d[j];
alpha[i] /= YS[i];
for(j=0;j<nVars;j++)
d[j] -= alpha[i]*Y[j + nVars*i];
}
}
for(j=0;j<nVars;j++)
d[j] *= Hdiag;
if(lbfgs_start != 1) {
for(i = lbfgs_start-1; i < maxCor; i++) {
beta[i] = 0;
for(j=0;j<nVars;j++)
beta[i] += Y[j + nVars*i]*d[j];
beta[i] /= YS[i];
for(j=0;j<nVars;j++)
d[j] += S[j+nVars*i]*(alpha[i]-beta[i]);
}
}
for(i = 0; i < lbfgs_end; i++) {
beta[i] = 0;
for(j=0;j<nVars;j++)
beta[i] += Y[j + nVars*i]*d[j];
beta[i] /= YS[i];
for(j=0;j<nVars;j++)
d[j] += S[j+nVars*i]*(alpha[i]-beta[i]);
}
mxFree(alpha);
mxFree(beta);
}