#include #include #include #include #include #include #include "mex.h" double compute_l2_ot(double *mu, double *nu, double *phi, double *dual, double totalMass, double sigma, int maxIters, int n1, int n2); void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){ double *mu=mxGetPr(prhs[0]); double *nu=mxGetPr(prhs[1]); int maxIters=(int) mxGetScalar(prhs[2]); double sigma =(double) mxGetScalar(prhs[3]); int n1=mxGetM(prhs[0]); int n2=mxGetN(prhs[0]); int pcount=n1*n2; plhs[0] = mxCreateDoubleMatrix(n1,n2,mxREAL); plhs[1] = mxCreateDoubleMatrix(n1,n2,mxREAL); double *phi=mxGetPr(plhs[0]); double *psi=mxGetPr(plhs[1]); double sum=0; for(int i=0;i0)-(x<0); return truth; } void init_hull(convex_hull *hull, int n){ hull->indices=calloc(n,sizeof(double)); hull->hullCount=0; } void destroy_hull(convex_hull *hull){ free(hull->indices); } void transpose_doubles(double *transpose, double *data, int n1, int n2){ for(int i=0;ihullCount<2){ hull->indices[1]=i; hull->hullCount++; }else{ int hc=hull->hullCount; int ic1=hull->indices[hc-1]; int ic2=hull->indices[hc-2]; double oldSlope=(u[ic1]-u[ic2])/(ic1-ic2); double slope=(u[i]-u[ic1])/(i-ic1); if(slope>=oldSlope){ int hc=hull->hullCount; hull->indices[hc]=i; hull->hullCount++; }else{ hull->hullCount--; add_point(u, hull, i); } } } void get_convex_hull(double *u, convex_hull *hull, int n){ hull->indices[0]=0; hull->indices[1]=1; hull->hullCount=2; for(int i=2;ihullCount; for(int i=0;iindices[counter]; int ic2=hull->indices[counter-1]; double slope=n*(u[ic1]-u[ic2])/(ic1-ic2); while(s>slope&&counterindices[counter]; ic2=hull->indices[counter-1]; slope=n*(u[ic1]-u[ic2])/(ic1-ic2); } dualIndicies[i]=hull->indices[counter-1]; } } void compute_dual(double *dual, double *u, int *dualIndicies, convex_hull *hull, int n){ get_convex_hull(u, hull, n); compute_dual_indices(dualIndicies, u, hull, n); for(int i=0;iv2){ dual[i]=v1; }else{ dualIndicies[i]=n-1; dual[i]=v2; } } } void compute_2d_dual(double *dual, double *u, convex_hull *hull, int n1, int n2){ int pcount=n1*n2; int n=fmax(n1,n2); int *argmin=calloc(n,sizeof(int)); double *temp=calloc(pcount,sizeof(double)); memcpy(temp, u, pcount*sizeof(double)); for(int i=0;i0){ double xStretch0=fabs(xMap[i*(n1+1)+j+1]-xMap[i*(n1+1)+j]); double xStretch1=fabs(xMap[(i+1)*(n1+1)+j+1]-xMap[(i+1)*(n1+1)+j]); double yStretch0=fabs(yMap[(i+1)*(n1+1)+j]-yMap[i*(n1+1)+j]); double yStretch1=fabs(yMap[(i+1)*(n1+1)+j+1]-yMap[i*(n1+1)+j+1]); double xStretch=fmax(xStretch0, xStretch1); double yStretch=fmax(yStretch0, yStretch1); int xSamples=2*fmax(n1*xStretch,1); int ySamples=2*fmax(n2*yStretch,1); if(xStretchgradSq*sigma*upper){ return sigma*scaleUp; }else if(diff