Example #1
0
File: rk4.c Project: Ajaxels/MIB
//__inline void interpgrad3d(double *Ireturn, double *I, int *Isize, double *point) {
static __inline void interpgrad3d(double *Ireturn, double *I, int *Isize, double *point) {    
    /*  Linear interpolation variables */
    int xBas0, xBas1, yBas0, yBas1, zBas0, zBas1;
    double perc[8];
    double xCom, yCom, zCom;
    double xComi, yComi, zComi;
    double fTlocalx, fTlocaly, fTlocalz;
    int f0, f1;
    int index[8];
    double temp;
    
    fTlocalx = floor(point[0]); fTlocaly = floor(point[1]); fTlocalz = floor(point[2]);
    xBas0=(int) fTlocalx; yBas0=(int) fTlocaly; zBas0=(int) fTlocalz;
    xBas1=xBas0+1; yBas1=yBas0+1; zBas1=zBas0+1;
    
    /* Linear interpolation constants (percentages) */
    xCom=point[0]-fTlocalx;  yCom=point[1]-fTlocaly;   zCom=point[2]-fTlocalz;
    xComi=(1-xCom); yComi=(1-yCom); zComi=(1-zCom);
    perc[0]=xComi * yComi; perc[1]=perc[0] * zCom; perc[0]=perc[0] * zComi;
    perc[2]=xComi * yCom;  perc[3]=perc[2] * zCom; perc[2]=perc[2] * zComi;
    perc[4]=xCom * yComi;  perc[5]=perc[4] * zCom; perc[4]=perc[4] * zComi;
    perc[6]=xCom * yCom;   perc[7]=perc[6] * zCom; perc[6]=perc[6] * zComi;
    
    /* Stick to boundary */
    if(xBas0<0) { xBas0=0; if(xBas1<0) { xBas1=0; }}
    if(yBas0<0) { yBas0=0; if(yBas1<0) { yBas1=0; }}
    if(zBas0<0) { zBas0=0; if(zBas1<0) { zBas1=0; }}
    if(xBas1>(Isize[0]-1)) { xBas1=Isize[0]-1; if(xBas0>(Isize[0]-1)) { xBas0=Isize[0]-1; }}
    if(yBas1>(Isize[1]-1)) { yBas1=Isize[1]-1; if(yBas0>(Isize[1]-1)) { yBas0=Isize[1]-1; }}
    if(zBas1>(Isize[2]-1)) { zBas1=Isize[2]-1; if(zBas0>(Isize[2]-1)) { zBas0=Isize[2]-1; }}
    
   /*Get the neighbour intensities */
    index[0]=mindex3(xBas0, yBas0, zBas0, Isize[0], Isize[1]);
    index[1]=mindex3(xBas0, yBas0, zBas1, Isize[0], Isize[1]);
    index[2]=mindex3(xBas0, yBas1, zBas0, Isize[0], Isize[1]);
    index[3]=mindex3(xBas0, yBas1, zBas1, Isize[0], Isize[1]);
    index[4]=mindex3(xBas1, yBas0, zBas0, Isize[0], Isize[1]);
    index[5]=mindex3(xBas1, yBas0, zBas1, Isize[0], Isize[1]);
    index[6]=mindex3(xBas1, yBas1, zBas0, Isize[0], Isize[1]);
    index[7]=mindex3(xBas1, yBas1, zBas1, Isize[0], Isize[1]);
    f0=Isize[0]*Isize[1]*Isize[2];
    f1=f0+f0;
    
   /*the interpolated color */
    temp=I[index[0]]*perc[0]+I[index[1]]*perc[1]+I[index[2]]*perc[2]+I[index[3]]*perc[3];
    Ireturn[0]=temp+I[index[4]]*perc[4]+I[index[5]]*perc[5]+I[index[6]]*perc[6]+I[index[7]]*perc[7];
    temp=I[index[0]+f0]*perc[0]+I[index[1]+f0]*perc[1]+I[index[2]+f0]*perc[2]+I[index[3]+f0]*perc[3];
    Ireturn[1]=temp+I[index[4]+f0]*perc[4]+I[index[5]+f0]*perc[5]+I[index[6]+f0]*perc[6]+I[index[7]+f0]*perc[7];
    temp=I[index[0]+f1]*perc[0]+I[index[1]+f1]*perc[1]+I[index[2]+f1]*perc[2]+I[index[3]+f1]*perc[3];
    Ireturn[2]=temp+I[index[4]+f1]*perc[4]+I[index[5]+f1]*perc[5]+I[index[6]+f1]*perc[6]+I[index[7]+f1]*perc[7];
}
/* The matlab mex function */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    float *Fx, *Fy, *Fz, *Bx, *By, *Bz, *H, *Num;
    
    /* Size of input transformation fields */
    mwSize  Bsizex, Bsizey, Bsizez;
    const mwSize *Bdims;

    /* Size of the input kernel */
    mwSize  Hsizex, Hsizey, Hsizez;
    const mwSize *Hdims;
    int hx_center,  hy_center, hz_center;
     
    /* Variables to store 1D index */
    int index;

    /* Variable to store vector */
    float valx, valy, valz;
    
    /* Loop variables */
    int i, t, iHx, iHy, iHz;
        
    /* Linear interpolation variables */
    int xBas0, xBas1,yBas0,yBas1,zBas0,zBas1;
    float perc[8], perct;
    float xCom, yCom, zCom;
    float Tlocalx, Tlocaly, Tlocalz;
    
    /* X,Y coordinates of current pixel */
    int x,y, z, tx, ty, tz;
    
    /* Check for proper number of arguments. */
    if(nrhs!=4) {
        mexErrMsgTxt("Four inputs are required.");
    } else if(nlhs!=3) {
        mexErrMsgTxt("Three outputs are required");
    }
  
  /* Get the sizes of the kernel  */
  Hdims = mxGetDimensions(prhs[3]);   
  Hsizex = Hdims[0]; Hsizey = Hdims[1]; Hsizez = Hdims[2];
  
  /* Get the sizes of the input transformation fields */
  Bdims = mxGetDimensions(prhs[0]);   
  Bsizex = Bdims[0]; Bsizey = Bdims[1]; Bsizez = Bdims[2];
    
  /* Create output arrays */
  plhs[0] = mxCreateNumericArray(3, Bdims, mxSINGLE_CLASS, mxREAL);
  plhs[1] = mxCreateNumericArray(3, Bdims, mxSINGLE_CLASS, mxREAL);
  plhs[2] = mxCreateNumericArray(3, Bdims, mxSINGLE_CLASS, mxREAL);

  /* Create array to count number of kernels added */
  Num = (float *)malloc(Bsizex*Bsizey*Bsizez*sizeof(float));  
  for (i=0; i<(Bsizex*Bsizey*Bsizez); i++){ Num[i] = 0;}    
  /* Assign pointers to each input. */
  Bx=(float *)mxGetData(prhs[0]);
  By=(float *)mxGetData(prhs[1]);
  Bz=(float *)mxGetData(prhs[2]);
  H=(float *)mxGetData(prhs[3]);
 
  /* Assign pointer to output. */
  Fx = (float *)mxGetData(plhs[0]);
  Fy = (float *)mxGetData(plhs[1]);
  Fz = (float *)mxGetData(plhs[2]);
    
  /* Gaussian kernel center */
  hx_center=(int)-floor((double)Hsizex/2); 
  hy_center=(int)-floor((double)Hsizey/2); 
  hz_center=(int)-floor((double)Hsizez/2); 
  
  /* Loop through all image pixel coordinates */
  for (z=0; z<Bsizez; z++)
  {
      for (y=0; y<Bsizey; y++)
      {
        for (x=0; x<Bsizex; x++)
        {
            valx=-Bx[mindex3(x,y,z,Bsizex,Bsizey)];
            valy=-By[mindex3(x,y,z,Bsizex,Bsizey)];
            valz=-Bz[mindex3(x,y,z,Bsizex,Bsizey)];
            
            Tlocalx =x-valx;
            Tlocaly =y-valy;
            Tlocalz =z-valz;
            
            /* Determine the coordinates of the pixel(s) which will be come the current pixel */
            /* (using linear interpolation)   */
            xBas0=(int) floor(Tlocalx); 
            yBas0=(int) floor(Tlocaly);
            zBas0=(int) floor(Tlocalz);
            xBas1=xBas0+1;      
            yBas1=yBas0+1;
            zBas1=zBas0+1;

            /* Linear interpolation constants (percentages) */
            xCom=Tlocalx-(float)floor((double)Tlocalx); yCom=Tlocaly-(float)floor((double)Tlocaly);  zCom=Tlocalz-(float)floor((double)Tlocalz);
            perc[0]=(1-xCom) * (1-yCom) * (1-zCom);
            perc[1]=(1-xCom) * (1-yCom) * zCom;
            perc[2]=(1-xCom) * yCom * (1-zCom);
            perc[3]=(1-xCom) * yCom * zCom;
            perc[4]=xCom * (1-yCom) * (1-zCom);
            perc[5]=xCom * (1-yCom) * zCom;
            perc[6]=xCom * yCom * (1-zCom);
            perc[7]=xCom * yCom * zCom;

            /* Loop through the whole kernel */
            for (iHx=0; iHx<Hsizex; iHx++)
            {
                for (iHy=0; iHy<Hsizey; iHy++)
                {
                    for (iHz=0; iHz<Hsizez; iHz++)
                    {
                        /* Process all 4 neighbors                 */
                        for(t=0; t<8; t++)
                        {
                           if(t==0){
                                tx=xBas0+iHx+hx_center; ty=yBas0+iHy+hy_center; tz=zBas0+iHz+hz_center; 
                                perct=perc[0]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)];
                           }
                           else if(t==1){
                                tx=xBas0+iHx+hx_center; ty=yBas0+iHy+hy_center; tz=zBas1+iHz+hz_center; 
                                perct=perc[1]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)];
                           }
                           else if(t==2){
                                tx=xBas0+iHx+hx_center; ty=yBas1+iHy+hy_center; tz=zBas0+iHz+hz_center; 
                                perct=perc[2]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)];
                           }
                           else if(t==3){
                                tx=xBas0+iHx+hx_center; ty=yBas1+iHy+hy_center; tz=zBas1+iHz+hz_center; 
                                perct=perc[3]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)];
                           }
                           else if(t==4){
                                tx=xBas1+iHx+hx_center; ty=yBas0+iHy+hy_center; tz=zBas0+iHz+hz_center; 
                                perct=perc[4]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)];
                           }
                           else if(t==5){
                                tx=xBas1+iHx+hx_center; ty=yBas0+iHy+hy_center; tz=zBas1+iHz+hz_center; 
                                perct=perc[5]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)];
                           }
                           else if(t==6){
                                tx=xBas1+iHx+hx_center; ty=yBas1+iHy+hy_center; tz=zBas0+iHz+hz_center; 
                                perct=perc[6]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)];
                           }
                           else{
                                tx=xBas1+iHx+hx_center; ty=yBas1+iHy+hy_center; tz=zBas1+iHz+hz_center; 
                                perct=perc[7]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)];
                           }

                           if((tx>=0)&&(ty>=0)&&(tz>=0)&&(tx<Bsizex)&&(ty<Bsizey)&&(tz<Bsizez))
                           {
                                index=mindex3(tx,ty,tz,Bsizex,Bsizey);
                                Fx[index]+=valx*perct; 
                                Fy[index]+=valy*perct;
                                Fz[index]+=valz*perct;
                                Num[index]=Num[index]+perct;
                           }
                        }
                   }
                }
            }
        }
      }
  }
  for (z=0; z<Bsizez; z++)
  {
      for (y=0; y<Bsizey; y++)
      {
          for (x=0; x<Bsizex; x++)
          {
            index=mindex3(x,y,z,Bsizex,Bsizey);
            Fx[index]/=(Num[index]+(float)0.00000001); 
            Fy[index]/=(Num[index]+(float)0.00000001);
            Fz[index]/=(Num[index]+(float)0.00000001);
          }
      }
  }
  free(Num);
}
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
    float *u, *Dxx, *Dyy, *Dzz, *Dxy, *Dxz, *Dyz;
    float *u_new;
	float *j1, *j2, *j3, *ud, *du;
    const mwSize *dimsu_const;
    int dimsu[3], npixels;
    float dt=0.5f;
	double *dt_d;
	int i;
    int x, y,z,index;
   
    /* Check number of inputs */
    if(nrhs<8) { mexErrMsgTxt("8 input variables are required."); }
    
    /* Check if inputs are of Single type */
    for(i=0; i<7; i++) {
        if(!mxIsSingle(prhs[i])){ mexErrMsgTxt("Inputs u,Dxx,Dxy,Dxz,Dyy,Dyz and Dzz must be single"); }
    }    
    
    /* Get time stepsize */
	if(!mxIsDouble(prhs[7])){ mexErrMsgTxt("Input dt must be double"); }
    dt_d=(double *)mxGetData(prhs[7]); 
	dt=(float) dt_d[0];
    
     /* Check properties of image I */
    if(mxGetNumberOfDimensions(prhs[0])!=3) { mexErrMsgTxt("Image must be 3D"); }
    /* Get the sizes of the image */
    dimsu_const = mxGetDimensions(prhs[0]);
	dimsu[0]=dimsu_const[0];
    dimsu[1]=dimsu_const[1];
    dimsu[2]=dimsu_const[2];
    npixels=dimsu[0]*dimsu[1]*dimsu[2];
	
    /* Assign pointers to each input. */
    u=(float *)mxGetData(prhs[0]); 
    Dxx=(float *)mxGetData(prhs[1]); /* Dxx */
    Dyy=(float *)mxGetData(prhs[4]); /* Dyy */
    Dzz=(float *)mxGetData(prhs[6]); /* Dzz */
    Dxy=(float *)mxGetData(prhs[2]); /* Dxy */
    Dxz=(float *)mxGetData(prhs[3]); /* Dxz */
    Dyz=(float *)mxGetData(prhs[5]); /* Dyz */

 	j1 =(float *)malloc(dimsu[0]*dimsu[1]*dimsu[2]*sizeof(float));
	j2 =(float *)malloc(dimsu[0]*dimsu[1]*dimsu[2]*sizeof(float));
	j3 =(float *)malloc(dimsu[0]*dimsu[1]*dimsu[2]*sizeof(float));
	ud =(float *)malloc(dimsu[0]*dimsu[1]*dimsu[2]*sizeof(float));
	

	/* 3 : Calculate the flux components */
	/* j1 = Dxx .* ux + Dxy .*uy + Dxz .*uz; */
	/* j2 = Dxy .* ux + Dyy .*uy + Dyz .*uz; */
	/* j3 = Dxz .* ux + Dyz .*uy + Dzz .*uz; */

	gradient3Dx_float(u, dimsu, ud);
	for (i=0; i<npixels; i++) 
	{ 
		j1[i]=Dxx[i]*ud[i]; j2[i]=Dxy[i]*ud[i]; j3[i]=Dxz[i]*ud[i];
	}
	gradient3Dy_float(u, dimsu, ud);
	for (i=0; i<npixels; i++) 
	{ 
		j1[i]+=Dxy[i]*ud[i]; j2[i]+=Dyy[i]*ud[i]; j3[i]+=Dyz[i]*ud[i];
	}
	gradient3Dz_float(u, dimsu, ud);
	for (i=0; i<npixels; i++) 
	{ 
		j1[i]+=Dxz[i]*ud[i]; j2[i]+=Dyz[i]*ud[i]; j3[i]+=Dzz[i]*ud[i];
	}
    
    /*j1(:,:,1)=0; j1(:,:,end)=0; j1(:,1,:)=0; j1(:,end,:)=0; j1(1,:,:)=0; j1(end,:,:)=0; */
    /*j2(:,:,1)=0; j2(:,:,end)=0; j2(:,1,:)=0; j2(:,end,:)=0; j2(1,:,:)=0; j2(end,:,:)=0; */
    /*j3(:,:,1)=0; j3(:,:,end)=0; j3(:,1,:)=0; j3(:,end,:)=0; j3(1,:,:)=0; j3(end,:,:)=0; */

    
	for (y=0; y<dimsu[1]; y++) { 
        for (x=0; x<dimsu[0]; x++) { 
            index=mindex3(x,y,0,dimsu[0],dimsu[1]);
            j1[index]=0; j2[index]=0; j3[index]=0; 
            index=mindex3(x,y,dimsu[2]-1,dimsu[0],dimsu[1]);
            j1[index]=0; j2[index]=0; j3[index]=0;
        }
    }
        
    for (z=0; z<dimsu[2]; z++) { 
        for (x=0; x<dimsu[0]; x++) { 
            index=mindex3(x,0,z,dimsu[0],dimsu[1]);
            j1[index]=0; j2[index]=0; j3[index]=0; 
            index=mindex3(x,dimsu[1]-1,z,dimsu[0],dimsu[1]);
            j1[index]=0; j2[index]=0; j3[index]=0;
        }
    }
    
    for (z=0; z<dimsu[2]; z++) { 
        for (y=0; y<dimsu[1]; y++) { 
            index=mindex3(0,y,z,dimsu[0],dimsu[1]);
            j1[index]=0; j2[index]=0; j3[index]=0; 
            index=mindex3(dimsu[0]-1,y,z,dimsu[0],dimsu[1]);
            j1[index]=0; j2[index]=0; j3[index]=0;
        }
    }
    
    
    /* 4 : Calculate ... by means of the optimized derivative filters */
	/* du = derivatives(j1,'x')+derivatives(j2,'y')+derivatives(j3,'z'); */
	du =(float *)malloc(dimsu[0]*dimsu[1]*dimsu[2]*sizeof(float));	
	gradient3Dx_float(j1, dimsu, du);
	gradient3Dy_float(j2, dimsu, ud);
	for (i=0; i<npixels; i++) { du[i]+=ud[i]; }
	gradient3Dz_float(j3, dimsu, ud);
	for (i=0; i<npixels; i++) { du[i]+=ud[i]; }
	
	/* Free memory */
	free(j1);
	free(j2);
	free(j3);
	free(ud);
	
	/* 5 : Update in an explicit way. */
	/* u=u+du*dt; */

	/* Create output array */
    plhs[0] = mxCreateNumericArray(3, dimsu, mxSINGLE_CLASS, mxREAL);

	/* Assign pointer to output. */
    u_new = (float *)mxGetData(plhs[0]);
	
	for (i=0; i<npixels; i++) 
	{ 
		u_new[i]+=u[i]+du[i]*dt; 
	}
	
	/* Free memory */
	free(du);
}
float CalculateDiffusionNewGreyValue(float *u,float *a,float *b,float *c,float *d,float *e,float *f,int x,int y,int z,int nx,int ny,int nz,int px,int py,int pz, float dt, int *dimsu)
{
	float A2, A4, A5, A6, A8,B1, B2,B3,B4,B5,B6,B7,B8,B9,C2,C4,C5,C6,C8;
 	float u_new;
    float du;
    float di;
    float eps=(float)1e-35;
	int index;

	/* Compute tensor-driven diffusion (as in [1] pp. 80-82) */
	A2 = -f[mindex3(x,y,nz,dimsu[0],dimsu[1])]-f[mindex3(x,py,z,dimsu[0],dimsu[1])]; 
	A4 =  e[mindex3(x,y,nz,dimsu[0],dimsu[1])]+e[mindex3(nx,y,z,dimsu[0],dimsu[1])];
	A6 = -e[mindex3(x,y,nz,dimsu[0],dimsu[1])]-e[mindex3(px,y,z,dimsu[0],dimsu[1])];
	A8 =  f[mindex3(x,y,nz,dimsu[0],dimsu[1])]+f[mindex3(x,ny,z,dimsu[0],dimsu[1])];
	B1 = -d[mindex3(nx,y,z,dimsu[0],dimsu[1])]-d[mindex3(x,py,z,dimsu[0],dimsu[1])];
	B3 =  d[mindex3(px,y,z,dimsu[0],dimsu[1])]+d[mindex3(x,py,z,dimsu[0],dimsu[1])];
	B7 =  d[mindex3(nx,y,z,dimsu[0],dimsu[1])]+d[mindex3(x,ny,z,dimsu[0],dimsu[1])];
	B9 = -d[mindex3(px,y,z,dimsu[0],dimsu[1])]-d[mindex3(x,ny,z,dimsu[0],dimsu[1])];
	C2 =  f[mindex3(x,y,pz,dimsu[0],dimsu[1])]+f[mindex3(x,py,z,dimsu[0],dimsu[1])];
	C4 = -e[mindex3(x,y,pz,dimsu[0],dimsu[1])]-e[mindex3(nx,y,z,dimsu[0],dimsu[1])];
	C6 =  e[mindex3(x,y,pz,dimsu[0],dimsu[1])]+e[mindex3(px,y,z,dimsu[0],dimsu[1])];
	C8 = -f[mindex3(x,y,pz,dimsu[0],dimsu[1])]-f[mindex3(x,ny,z,dimsu[0],dimsu[1])];
	
	A5 = c[mindex3(x,y,nz,dimsu[0],dimsu[1])]+c[mindex3(x,y,z,dimsu[0],dimsu[1])];
	B2 = b[mindex3(x,py,z,dimsu[0],dimsu[1])]+b[mindex3(x,y,z,dimsu[0],dimsu[1])];
	B4 = a[mindex3(nx,y,z,dimsu[0],dimsu[1])]+a[mindex3(x,y,z,dimsu[0],dimsu[1])];
	B5 =  -(a[mindex3(nx,y,z,dimsu[0],dimsu[1])] + 2*a[mindex3(x,y,z,dimsu[0],dimsu[1])] + a[mindex3(px,y,z,dimsu[0],dimsu[1])]);
	B5 += -(b[mindex3(x,ny,z,dimsu[0],dimsu[1])] + 2*b[mindex3(x,y,z,dimsu[0],dimsu[1])] + b[mindex3(x,py,z,dimsu[0],dimsu[1])]);
	B5 += -(c[mindex3(x,y,nz,dimsu[0],dimsu[1])] + 2*c[mindex3(x,y,z,dimsu[0],dimsu[1])] + c[mindex3(x,y,pz,dimsu[0],dimsu[1])]);
	B6 = a[mindex3(px,y,z,dimsu[0],dimsu[1])]+a[mindex3(x,y,z,dimsu[0],dimsu[1])];
	B8 = b[mindex3(x,ny,z,dimsu[0],dimsu[1])]+b[mindex3(x,y,z,dimsu[0],dimsu[1])];
	C5 = c[mindex3(x,y,pz,dimsu[0],dimsu[1])]+c[mindex3(x,y,z,dimsu[0],dimsu[1])];

	du=0;
	du+=A2*u[mindex3(x,py,nz,dimsu[0],dimsu[1])];
	du+=A4*u[mindex3(nx,y,nz,dimsu[0],dimsu[1])]; 
	du+=A6*u[mindex3(px,y,nz,dimsu[0],dimsu[1])]; 
	du+=A8*u[mindex3(x,ny,nz,dimsu[0],dimsu[1])]; 
	
	du+=B1*u[mindex3(nx,py,z,dimsu[0],dimsu[1])]; 
	du+=B3*u[mindex3(px,py,z,dimsu[0],dimsu[1])]; 
	du+=B7*u[mindex3(nx,ny,z,dimsu[0],dimsu[1])]; 
	du+=B9*u[mindex3(px,ny,z,dimsu[0],dimsu[1])]; 
	
	du+=C2*u[mindex3(x,py,pz,dimsu[0],dimsu[1])];
	du+=C4*u[mindex3(nx,y,pz,dimsu[0],dimsu[1])]; 
	du+=C6*u[mindex3(px,y,pz,dimsu[0],dimsu[1])]; 
	du+=C8*u[mindex3(x,ny,pz,dimsu[0],dimsu[1])];

	du*=0.5;
	
	du+=A5*u[mindex3(x,y,nz,dimsu[0],dimsu[1])];  
	du+=B2*u[mindex3(x,py,z,dimsu[0],dimsu[1])]; 
	du+=B4*u[mindex3(nx,y,z,dimsu[0],dimsu[1])]; 
	du+=B6*u[mindex3(px,y,z,dimsu[0],dimsu[1])]; 
	du+=B8*u[mindex3(x,ny,z,dimsu[0],dimsu[1])];  
	du+=C5*u[mindex3(x,y,pz,dimsu[0],dimsu[1])];  
	
	du*=0.5f*dt;

	/* Perform the edge preserving diffusion filtering on the image */
	index = mindex3(x,y,z,dimsu[0],dimsu[1]);
	di=(1-0.5f*dt*B5); if((di<eps)&&(di>-eps)) { di=eps; }
	u_new = (u[index] + du )/di;  
	return u_new;
}
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
    float *u, *a, *b, *c, *d, *e, *f;
    float *u_new;
    const mwSize *dimsu_const;
    int dimsu[3];
    float dt=0.5f;
	double *dt_d;
    int index;
    int i;
    int x,y,z, nx, ny, nz, px, py, pz;
    
    /* Check number of inputs */
    if(nrhs<8) { mexErrMsgTxt("8 input variables are required."); }
    
    /* Check if inputs are of Single type */
    for(i=0; i<7; i++) {
        if(!mxIsSingle(prhs[i])){ mexErrMsgTxt("Inputs u,Dxx,Dxy,Dxz,Dyy,Dyz and Dzz must be single"); }
    }    
    
    /* Get time stepsize */
	if(!mxIsDouble(prhs[7])){ mexErrMsgTxt("Input dt must be double"); }
    dt_d=(double *)mxGetData(prhs[7]); 
	dt=(float) dt_d[0];
	
    
     /* Check properties of image I */
    if(mxGetNumberOfDimensions(prhs[0])!=3) { mexErrMsgTxt("Image must be 3D"); }
    /* Get the sizes of the image */
    dimsu_const = mxGetDimensions(prhs[0]);
	dimsu[0]=dimsu_const[0];
    dimsu[1]=dimsu_const[1];
    dimsu[2]=dimsu_const[2];
    
    /* Assign pointers to each input. */
    u=(float *)mxGetData(prhs[0]); 
    a=(float *)mxGetData(prhs[1]); /* Dxx */
    b=(float *)mxGetData(prhs[4]); /* Dyy */
    c=(float *)mxGetData(prhs[6]); /* Dzz */
    d=(float *)mxGetData(prhs[2]); /* Dxy */
    e=(float *)mxGetData(prhs[3]); /* Dxz */
    f=(float *)mxGetData(prhs[5]); /* Dyz */

    /* Create output array */
    plhs[0] = mxCreateNumericArray(3, dimsu, mxSINGLE_CLASS, mxREAL);
    /* Assign pointer to output. */
    u_new = (float *)mxGetData(plhs[0]);

    
    
    /* Loop through all pixels in the volume */
    for (z=0; z<dimsu[2]; z++) {
        /* Neighbor coordinates */
        nz=z-1; if(nz<0) {nz=0; }
        pz=z+1; if(pz>(dimsu[2]-1)) { pz=dimsu[2]-1; }
        for (y=0; y<dimsu[1]; y++) {
            ny=y-1; if(ny<0) {ny=0; }
            py=y+1; if(py>(dimsu[1]-1)) { py=dimsu[1]-1; }
            for (x=0; x<dimsu[0]; x++) {
                nx=x-1; if(nx<0) {nx=0; }
                px=x+1; if(px>(dimsu[0]-1)) { px=dimsu[0]-1; }

				index = mindex3(x,y,z,dimsu[0],dimsu[1]);
				u_new[index] = CalculateDiffusionNewGreyValue(u,a,b,c,d,e,f,x,y,z,nx,ny,nz,px,py,pz,dt,dimsu);
            }
        }
    }

    
    
    
}