kriging.grid()差值转java算法

生成工具类

package com.wyx.utils;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

public class GridTool {
	//格点数据生成方法
	public static Variogram grid(Double[][][] world,Double[] ts,Double[] xs,Double[] ys,Double width) {
		Variogram variogram = train(ts, xs, ys);
		variogram.setMax((double) Collections.max(Arrays.asList(variogram.t))); 
		variogram.setMin((double) Collections.min(Arrays.asList(variogram.t))); 
    	int i, j, k, n = world.length;
        if(n==0) return null;
        // Boundaries of polygons space
        Double[] xlim = {world[0][0][0], world[0][0][0]};
        Double[] ylim = {world[0][0][1], world[0][0][1]};
        for(i=0;i<n;i++) // Polygons
          for(j=0;j<world[i].length;j++) { // Vertices
            if(world[i][j][0]<xlim[0])
              xlim[0] = world[i][j][0];
            if(world[i][j][0]>xlim[1])
              xlim[1] = world[i][j][0];
            if(world[i][j][1]<ylim[0])
              ylim[0] = world[i][j][1];
            if(world[i][j][1]>ylim[1])
              ylim[1] = world[i][j][1];
          }

        // Alloc for O(n^2) space
        Double xtarget, ytarget;
        Integer[] a = new Integer[2]; Integer[] b = new Integer[2];
        Double[] lxlim = new Double[2]; // Local dimensions
        Double[] lylim = new Double[2]; // Local dimensions
        Integer x = (int) Math.ceil((xlim[1]-xlim[0])/width);
        Integer y = (int) Math.ceil((ylim[1]-ylim[0])/width);

        Double[][] A = new Double[x+1][];
        for(i=0;i<=x;i++) A[i] = new Double[y+1];
        for(i=0;i<n;i++) {
          // Range for polygons[i]
          lxlim[0] = world[i][0][0];
          lxlim[1] = lxlim[0];
          lylim[0] = world[i][0][1];
          lylim[1] = lylim[0];
          for(j=1;j<world[i].length;j++) { // Vertices
            if(world[i][j][0]<lxlim[0])
              lxlim[0] = world[i][j][0];
            if(world[i][j][0]>lxlim[1])
              lxlim[1] = world[i][j][0];
            if(world[i][j][1]<lylim[0])
              lylim[0] = world[i][j][1];
            if(world[i][j][1]>lylim[1])
              lylim[1] = world[i][j][1];
          }

          // Loop through polygon subspace
          a[0] = (int) Math.floor(((lxlim[0]-((lxlim[0]-xlim[0])%width)) - xlim[0])/width);
          a[1] = (int) Math.ceil(((lxlim[1]-((lxlim[1]-xlim[1])%width)) - xlim[0])/width);
          b[0] = (int) Math.floor(((lylim[0]-((lylim[0]-ylim[0])%width)) - ylim[0])/width);
          b[1] = (int) Math.ceil(((lylim[1]-((lylim[1]-ylim[1])%width)) - ylim[0])/width);
          for(j=a[0];j<=a[1];j++)
            for(k=b[0];k<=b[1];k++) {
              xtarget = xlim[0] + j*width;
              ytarget = ylim[0] + k*width;
              if(pip(world[i],xtarget, ytarget)){        	  
            	  A[j][k] = predict(xtarget,
                  ytarget,
                  variogram);
            	 if(A[j][k]>variogram.getMax()){
            		 A[j][k]= variogram.getMax();
            	 }
              }
            }
        }
        
        Variogram  variogram1 = new Variogram();
        variogram1.re_A=A;
        variogram1.re_xlim=xlim;
        variogram1.re_ylim=ylim;
        Double[] zlim1 = {variogram.getMin(), variogram.getMax()};
        variogram1.re_zlim=zlim1;
        variogram1.re_width=width;
        return variogram1;
	}
	
	public static boolean pip(Double[][] array, Double x,Double y){
    	Integer i, j; boolean c = false;
    	  for(i=0,j=array.length-1;i<array.length;j=i++) {
    	    if( ((array[i][1]>y) != (array[j][1]>y)) &&
    	      (x<(array[j][0]-array[i][0]) * (y-array[i][1]) / (array[j][1]-array[i][1]) + array[i][0]) ) {
    	      c = !c;
    	    }
    	  }
    	  return c;
    }
	public static double predict(Double x, Double y,Variogram variogram){
    	Integer i; Double[] k = new Double[variogram.n];
        for(i=0;i<variogram.n;i++)
          k[i] = variogram.model(Math.pow(Math.pow(x-variogram.x[i], 2)+
            Math.pow(y-variogram.y[i], 2), 0.5),
            variogram.nugget, variogram.range,
            variogram.sill, variogram.A);
        return kriging_matrix_multiply(k, variogram.M, 1, variogram.n, 1)[0];
    }
	public static Double[] kriging_matrix_multiply(Double[] X, Double[] Y,Integer n,Integer m,Integer p){
    	Integer i, j, k;Double[] Z = new Double[n*p];
        for(i=0;i<n;i++) {
          for(j=0;j<p;j++) {
            Z[i*p+j] = 0d;
            for(k=0;k<m;k++)
              Z[i*p+j] += X[i*m+k]*Y[k*p+j];
          }
        }
        return Z;
    }
    
	public static Double[] kriging_matrix_transpose(Double[] X,Integer n,Integer m){
    	Integer i, j; Double[] Z = new Double[m*n];
        for(i=0;i<n;i++)
          for(j=0;j<m;j++)
            Z[j*n+i] = X[i*m+j];
        return Z;
    }
    
	public static Double[] kriging_matrix_diag(Double c,Integer n){
    	Integer i;Double[] Z = rep(new Double[n*n],0d);
        for(i=0;i<n;i++) Z[i*n+i] = c;
        return Z;
    }
    
	public static Double[] kriging_matrix_add(Double[] X, Double[] Y,Integer n,Integer m){
    	Integer i, j; Double[] Z = new Double[n*m];
        for(i=0;i<n;i++)
          for(j=0;j<m;j++)
            Z[i*m+j] = X[i*m+j] + Y[i*m+j];
        return Z;
    }
    
	public static boolean kriging_matrix_chol(Double[] X,Integer n){
    	Integer i, j, k, sum; Double[] p = new Double[n];
        for(i=0;i<n;i++) p[i] = X[i*n+i];
        for(i=0;i<n;i++) {
          for(j=0;j<i;j++)
            p[i] -= X[i*n+j]*X[i*n+j];
          if(p[i]<=0) return false;
          p[i] = Math.sqrt(p[i]);
          for(j=i+1;j<n;j++) {
            for(k=0;k<i;k++)
              X[j*n+i] -= X[j*n+k]*X[i*n+k];
            X[j*n+i] /= p[i];
          }
        }
        for(i=0;i<n;i++) X[i*n+i] = p[i];
        return true;
    }
    
	public static void kriging_matrix_chol2inv(Double[] X,Integer n){
    	Integer i, j, k;Double sum;
        for(i=0;i<n;i++) {
          X[i*n+i] = 1/X[i*n+i];
          for(j=i+1;j<n;j++) {
            sum = 0d;
            for(k=i;k<j;k++)
              sum -= X[j*n+k]*X[k*n+i];
            X[j*n+i] = sum/X[j*n+j];
          }
        }
        for(i=0;i<n;i++)
          for(j=i+1;j<n;j++)
            X[i*n+j] = 0d;
        for(i=0;i<n;i++) {
          X[i*n+i] *= X[i*n+i];
          for(k=i+1;k<n;k++)
            X[i*n+i] += X[k*n+i]*X[k*n+i];
          for(j=i+1;j<n;j++)
            for(k=j;k<n;k++)
              X[i*n+j] += X[k*n+i]*X[k*n+j];
        }
        for(i=0;i<n;i++)
          for(j=0;j<i;j++)
            X[i*n+j] = X[j*n+i];
    }
    
    public static boolean kriging_matrix_solve(Double[] X,Integer n){
    	Integer m = n;
        Double[] b = new Double[n*n];
        Integer[] indxc = new Integer[n];
        Integer[] indxr = new Integer[n];
        Integer[] ipiv = new Integer[n];
        Integer i =0, icol=0, irow=0, j, k, l, ll;
        Double big, dum, pivinv, temp;

        for(i=0;i<n;i++)
          for(j=0;j<n;j++) {
            if(i==j) b[i*n+j] = 1d;
            else b[i*n+j] = 0d;
          }
        for(j=0;j<n;j++) ipiv[j] = 0;
        for(i=0;i<n;i++) {
          big = 0d;
          for(j=0;j<n;j++) {
            if(ipiv[j]!=1) {
              for(k=0;k<n;k++) {
                if(ipiv[k]==0) {
                  if(Math.abs(X[j*n+k])>=big) {
                    big = Math.abs(X[j*n+k]);
                    irow = j;
                    icol = k;
                  }
                }
              }
            }
          }
          ++(ipiv[icol]);

          if(irow!=icol) {
            for(l=0;l<n;l++) {
              temp = X[irow*n+l];
              X[irow*n+l] = X[icol*n+l];
              X[icol*n+l] = temp;
            }
            for(l=0;l<m;l++) {
              temp = b[irow*n+l];
              b[irow*n+l] = b[icol*n+l];
              b[icol*n+l] = temp;
            }
          }
          indxr[i] = irow;
          indxc[i] = icol;

          if(X[icol*n+icol]==0) return false; // Singular

          pivinv = 1 / X[icol*n+icol];
          X[icol*n+icol] = 1d;
          for(l=0;l<n;l++) X[icol*n+l] *= pivinv;
          for(l=0;l<m;l++) b[icol*n+l] *= pivinv;

          for(ll=0;ll<n;ll++) {
            if(ll!=icol) {
              dum = X[ll*n+icol];
              X[ll*n+icol] = 0d;
              for(l=0;l<n;l++) X[ll*n+l] -= X[icol*n+l]*dum;
              for(l=0;l<m;l++) b[ll*n+l] -= b[icol*n+l]*dum;
            }
          }
        }
        for(l=(n-1);l>=0;l--)
          if(indxr[l]!=indxc[l]) {
            for(k=0;k<n;k++) {
              temp = X[k*n+indxr[l]];
              X[k*n+indxr[l]] = X[k*n+indxc[l]];
              X[k*n+indxc[l]] = temp;
            }
          }

        return true;
    }
    
    public static Double[] rep(Double[] X,Double init){
    	for(int i=0;i<X.length;i++) {
            X[i] = init;
          }
    	return X;
    }
    
    public static Variogram train( Double[] t,Double[] x,Double[] y) {
    			Variogram  variogram = new Variogram();
    			variogram.t =t;
    			variogram.x =x;
    			variogram.y =y;
    			variogram.nugget =0.0;
    			variogram.range =0.0;
    			variogram.sill =0.0;
    			variogram.A =1d/3;
    			variogram.n =0;
    			String model = "spherical";
    			Double sigma2 = 0d;
    			Double alpha = 0.01d;
    		    // Lag distance/semivariance
    		    Integer i, j, k, l, n = t.length;
    		    Double[][] distance = new Double[(n*n-n)/2][];
    		    for(i=0,k=0;i<n;i++)
    		      for(j=0;j<i;j++,k++) {
    		        distance[k] = new Double[2];
    		        distance[k][0] = Math.pow(
    		          Math.pow(x[i]-x[j], 2)+
    		          Math.pow(y[i]-y[j], 2), 0.5);
    		        distance[k][1] = Math.abs(t[i]-t[j]);
    		      }
    		    Arrays.sort(distance, new Comparator<Double[]>() {
    		    	@Override
    		    	public int compare(Double[] o1, Double[] o2) {    	
    		    	
    		    	if((o1[0]-o2[0])>0d) {
    		    		return 1;
    		    	}
    		    	if((o1[0]-o2[0])<0d) {
    		    		return -1;
    		    	}
    		    	return 0;
    		    	}
    		    	});
    		    variogram.range = distance[(n*n-n)/2-1][0];

    		    // Bin lag distance
    		    Integer lags = ((n*n-n)/2)>30?30:(n*n-n)/2;
    		    Double tolerance = variogram.range/lags;
    		    Double[] lag = rep(new Double[lags],0d);
    		    Double[] semi = rep(new Double[lags],0d);
    		    if(lags<30) {
    		      for(l=0;l<lags;l++) {
    		        lag[l] = distance[l][0];
    		        semi[l] = distance[l][1];
    		      }
    		    }
    		    else {
    		      for(i=0,j=0,k=0,l=0;i<lags&&j<((n*n-n)/2);i++,k=0) {
    		        while( distance[j][0]<=((i+1)*tolerance) ) {
    		          lag[l] += distance[j][0];
    		          semi[l] += distance[j][1];
    		          j++;k++;
    		          if(j>=((n*n-n)/2)) break;
    		        }
    		        if(k>0) {
    		          lag[l] /= k;
    		          semi[l] /= k;
    		          l++;
    		        }
    		      }
    		      if(l<2) return variogram; // Error: Not enough points
    		    }

    		    // Feature transformation
    		    n = l;
    		    variogram.range = lag[n-1]-lag[0];
    		    Double[] X = rep(new Double[2*n],1d);    		    		
    		    Double[] Y = new Double[n];
    		    Double A = variogram.A;
    		    for(i=0;i<n;i++) {
    		      if(model.equals("gaussian")) {
    		       
    		          X[i*2+1] = 1.0-Math.exp(-(1.0/A)*Math.pow(lag[i]/variogram.range, 2));
    		      }else if(model.equals("exponential")) {

    		          X[i*2+1] = 1.0-Math.exp(-(1.0/A)*lag[i]/variogram.range);

    		      }else if(model.equals("spherical")) {
    		          X[i*2+1] = 1.5*(lag[i]/variogram.range)-
    		            0.5*Math.pow(lag[i]/variogram.range, 3);

    		      };
    		      Y[i] = semi[i];
    		    }

    		    // Least squares
    		    Double[] Xt = kriging_matrix_transpose(X, n, 2);
    		    Double[] Z = kriging_matrix_multiply(Xt, X, 2, n, 2);
    		    Z = kriging_matrix_add(Z, kriging_matrix_diag(1/alpha, 2), 2, 2);
    		    Double[] cloneZ = Z.clone();
    		    if(kriging_matrix_chol(Z, 2))
    		      kriging_matrix_chol2inv(Z, 2);
    		    else {
    		      kriging_matrix_solve(cloneZ, 2);
    		      Z = cloneZ;
    		    }
    		    Double[] W = kriging_matrix_multiply(kriging_matrix_multiply(Z, Xt, 2, 2, n), Y, 2, n, 1);

    		    // Variogram parameters
    		    variogram.nugget = W[0];
    		    variogram.sill = W[1]*variogram.range+variogram.nugget;
    		    variogram.n = x.length;

    		    // Gram matrix with prior
    		    n = x.length;
    		    Double[] K = new Double[n*n];
    		    for(i=0;i<n;i++) {
    		      for(j=0;j<i;j++) {
    		        K[i*n+j] = variogram.model(Math.pow(Math.pow(x[i]-x[j], 2)+
    		          Math.pow(y[i]-y[j], 2), 0.5),
    		          variogram.nugget,
    		          variogram.range,
    		          variogram.sill,
    		          variogram.A);
    		        K[j*n+i] = K[i*n+j];
    		      }
    		      K[i*n+i] = variogram.model(0d, variogram.nugget,
    		        variogram.range,
    		        variogram.sill,
    		        variogram.A);
    		    }

    		    // Inverse penalized Gram matrix projected to target vector
    		    Double[] C = kriging_matrix_add(K, kriging_matrix_diag(sigma2, n), n, n);
    		    Double[] cloneC = C.clone();
    		    if(kriging_matrix_chol(C, n))
    		      kriging_matrix_chol2inv(C, n);
    		    else {
    		      kriging_matrix_solve(cloneC, n);
    		      C = cloneC;
    		    }

    		    // Copy unprojected inverted matrix as K
    		    K = C.clone();
    		    Double[] M = kriging_matrix_multiply(C, t, n, n, 1);
    		    variogram.K = K;
    		    variogram.M = M;

    		    return variogram;
    		  };
		
    		  
    
}

接收参数bean类

package com.wyx.utils;

import java.util.Arrays;
import java.util.Collections;

public class Variogram {
	public Double A;
	public Double[] K;
	public Double[] M;
	public Integer n;
	public Double nugget;
	public Double range;
	public Double sill;
	public Double[] t;
	public Double[] x;
	public Double[] y;
	
	public Double[][] re_A;
	public Double[] re_xlim;
	public Double[] re_ylim;
	public Double[] re_zlim;
	public Double re_width;
	
	public Double[][][] world;
	public Double width;
	public Double max;
	public Double min;
	
	public static Double model(Double h,Double nugget,Double range,Double sill,Double A) {
		if(h>range) return nugget + (sill-nugget)/range;
	    return nugget + ((sill-nugget)/range)*
	      ( 1.5*(h/range) - 0.5*Math.pow(h/range, 3) );
	}
	
	public void setMax(Double max) {
		this.max = max;
	}

	public void setMin(Double min) {
		this.min = min;
	}

	
	public Double getMax() {
		return max;
	}

	public Double getMin() {
		return min;
	}

	public Double getA() {
		return A;
	}
	public void setA(Double a) {
		A = a;
	}
	public Double[] getK() {
		return K;
	}
	public void setK(Double[] k) {
		K = k;
	}
	public Double[] getM() {
		return M;
	}
	public void setM(Double[] m) {
		M = m;
	}
	public Integer getN() {
		return n;
	}
	public void setN(Integer n) {
		this.n = n;
	}
	public Double getNugget() {
		return nugget;
	}
	public void setNugget(Double nugget) {
		this.nugget = nugget;
	}
	public Double getRange() {
		return range;
	}
	public void setRange(Double range) {
		this.range = range;
	}
	public Double getSill() {
		return sill;
	}
	public void setSill(Double sill) {
		this.sill = sill;
	}
	public Double[] getT() {
		return t;
	}
	public void setT(Double[] t) {
		this.t = t;
	}
	public Double[] getX() {
		return x;
	}
	public void setX(Double[] x) {
		this.x = x;
	}
	public Double[] getY() {
		return y;
	}
	public void setY(Double[] y) {
		this.y = y;
	}
	public Double[][] getRe_A() {
		return re_A;
	}
	public void setRe_A(Double[][] re_A) {
		this.re_A = re_A;
	}
	public Double[] getRe_xlim() {
		return re_xlim;
	}
	public void setRe_xlim(Double[] re_xlim) {
		this.re_xlim = re_xlim;
	}
	public Double[] getRe_ylim() {
		return re_ylim;
	}
	public void setRe_ylim(Double[] re_ylim) {
		this.re_ylim = re_ylim;
	}
	public Double[] getRe_zlim() {
		return re_zlim;
	}
	public void setRe_zlim(Double[] re_zlim) {
		this.re_zlim = re_zlim;
	}
	public Double getRe_width() {
		return re_width;
	}
	public void setRe_width(Double re_width) {
		this.re_width = re_width;
	}
	public Double[][][] getWorld() {
		return world;
	}
	public void setWorld(Double[][][] world) {
		this.world = world;
	}
	public Double getWidth() {
		return width;
	}
	public void setWidth(Double width) {
		this.width = width;
	}
	
}
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值