0

Before I start, please accept my apologies that I'm a starter developer.

What I want is a grid with data. Only I have a list of an array with 7 points (x, y, value). I want to do this in a grid of 5x5. Only I miss a lot of values. I want to generate the missing values with help of an interpolation function. An algorithm to search through multi-dimension(or interpolation) (x, y) to generate a value for the other grids.

Grid example:

18 - 0 - 0 - 35 - 0
0 - 20 - 0 - 0 - 29
25 - 0 - 0 - 30 - 0
0 - 25 - 0 - 32 - 35
0 - 0 - 28 - 0 - 0

I used the method(from the numerical methods, algorithms and tools in c# book) and it's working, but i don't understand how to pass my values to the function and generate the random 5x5 missing values, because the functions and methods aren't explained in the book.

what is a zdata[,] double 2D array?, is this the values from the points? What are the xdate and the ydata?

Example, i have a array of 7 points (x,y,value)=> 0,0,18 etc. How can i pass correctly to this method to generate the missing values ?

Here is the whole function:

class InterpolationTest
{
    static void Main(string[] args)
    {
        double[] xdata = new double[] { 0, 2 };  //x-coordinate 0 and 2?
        double[] ydata = new double[] { 0, 2 };  //y-coordinate 0 and 2?
        double[,] zdata = new double[,] { { 0, 20 }, { 20, 10 } }; //what is a zdata??
        double[] x = new double[5]; 
        double[] y = new double[5];
        RMatrix z = new RMatrix(5, 5);
        for (int i = 0; i < 4; i++)
        {
            x[i] = (i + 2.0) / 20.0;
            y[i] = (i + 2.0) / 20.0;
        }
        RVector xvec = new RVector(x);
        RVector yvec = new RVector(y);
        for (int i = 0; i < 5; i++)
        {
            for (int j = 0; j < 5; j++)
            {
                z[i, j] = BilinearInterpolation(xdata, ydata, zdata, x[i], y[j]);
            }
        }
        Console.Clear();
        Console.WriteLine("Running Bilinear Interpolation Test\n\n");
        Console.WriteLine("x = " + xvec.ToString());
        Console.WriteLine("y = " + yvec.ToString());
        Console.WriteLine("\nResults z = \n" + z.ToString() + "\n\n");
        Console.WriteLine("Press ENTER key to continue...");
        Console.ReadLine();

    }

    public static double BilinearInterpolation(double[] x, double[] y, double[,] z, double xval, double yval)
    {
        double zval = 0.0;
        for (int i = 0; i < x.Length - 1; i++)
        {
            for (int j = 0; j < y.Length - 1; j++)
            {
                if (xval >= x[i] && xval < x[i + 1] && yval >= y[j] && yval < y[j + 1])
                {
                    zval = z[i, j] * (x[i + 1] - xval) * (y[j + 1] - yval) / (x[i + 1] - x[i]) / (y[j + 1] - y[j]) +
                    z[i + 1, j] * (xval - x[i]) * (y[j + 1] - yval) / (x[i + 1] - x[i]) / (y[j + 1] - y[j]) +
                    z[i, j + 1] * (x[i + 1] - xval) * (yval - y[j]) / (x[i + 1] - x[i]) / (y[j + 1] - y[j]) +
                    z[i + 1, j + 1] * (xval - x[i]) * (yval - y[j]) / (x[i + 1] - x[i]) / (y[j + 1] - y[j]);
                }
            }
        }
        return zval;
    }

    public static double[] BilinearInterpolation(double[] x, double[] y, double[,] z, double[] xvals, double[] yvals)
    {
        double[] zvals = new double[xvals.Length];
        for (int i = 0; i < xvals.Length; i++)
            zvals[i] = BilinearInterpolation(x, y, z, xvals[i], yvals[i]);
        return zvals;
    }
}

public struct RMatrix
{
    private int nRows;
    private int nCols;
    private double[,] matrix;

    public RMatrix(int nCols, int nRows)
    {
        this.nRows = nRows;
        this.nCols = nCols;
        this.matrix = new double[nRows, nCols];
        for (int i = 0; i < nRows; i++)
        {
            for (int j = 0; j < nCols; j++)
            {
                matrix[i, j] = 0.0;
            }
        }
    }

    public RMatrix(double[,] matrix)
    {
        this.nRows = matrix.GetLength(0);
        this.nCols = matrix.GetLength(1);
        this.matrix = matrix;
    }

    public RMatrix(RMatrix m)
    {
        nRows = m.GetnRows;
        nCols = m.GetnCols;
        matrix = m.matrix;
    }

    public RMatrix IdentityMatrix()
    {
        RMatrix m = new RMatrix(nRows, nCols);
        for (int i = 0; i < nRows; i++)
        {
            for (int j = 0; j < nCols; j++)
            {
                if (i == j)
                {
                    m[i, j] = 1;
                }
            }
        }
        return m;
    }

    public int GetnRows
    {
        get { return nRows; }
    }
    public int GetnCols
    {
        get { return nCols; }
    }

    public override string ToString()
    {
        string strMatrix = "(";
        for (int i = 0; i < nRows; i++)
        {
            string str = "";
            for (int j = 0; j < nCols - 1; j++)
            {
                str += matrix[i, j].ToString() + ", ";
            }
            str += matrix[i, nCols - 1].ToString();
            if (i != nRows - 1 && i == 0)
                strMatrix += str + "\n";
            else if (i != nRows - 1 && i != 0)
                strMatrix += " " + str + "\n";
            else
                strMatrix += " " + str + ")";
        }
        return strMatrix;
    }
}

public struct RVector
{
    private int ndim;
    private double[] vector;

    public RVector(int ndim)
    {
        this.ndim = ndim;
        this.vector = new double[ndim];
        for (int i = 0; i < ndim; i++)
        {
            vector[i] = 0.0;
        }
    }

    public RVector(double[] vector)
    {
        this.ndim = vector.Length;
        this.vector = vector;
    }

    public override string ToString()
    {
        string str = "(";
        for (int i = 0; i < ndim - 1; i++)
        {
            str += vector[i].ToString() + ", ";
        }
        str += vector[ndim - 1].ToString() + ")";
        return str;
    }
}

Thanks

E75
  • 153
  • 3
  • 13
  • Not sure what an RMatrix is, but why are you running two loops from 0 to 18 and populating a matrix that looks like it was declared to be 5x5? – Kolichikov Sep 22 '16 at 18:17
  • @Kolichikov edited and added RVector and RMatrix classes – E75 Sep 22 '16 at 18:29
  • Bilinear interpolation is probably not the right approach for your problem. `z` is the actual value that is interpolated in the code. – Nico Schertler Sep 22 '16 at 18:48
  • @NicoSchertler Thanks, can you give a another solution if you know how to generate missing values? – E75 Sep 22 '16 at 18:53
  • That depends on your assumptions of the data. In general, this is [Scattered Data Interpolation](http://scribblethink.org/Courses/ScatteredInterpolation/scatteredinterpcoursenotes.pdf). One simple solution might be [Shepard Interpolation](https://en.wikipedia.org/wiki/Inverse_distance_weighting). But you need to pick an interpolation method that matches your assumptions about the behavior of the data in the blank areas. – Nico Schertler Sep 22 '16 at 18:59
  • take a look at this [Interpolating elements of a color matrix on the basis of some given reference elements](http://stackoverflow.com/a/39506280/2521214) The second approach is much easier to code... – Spektre Sep 23 '16 at 07:44
  • @Spektre :D Thats exactly what i'm looking for. But it's writting in c++. Have you an "simple" example for C# ? – E75 Sep 23 '16 at 07:48
  • @E75 no I do not code in **C#** I can add more detailed description there if it helps but in nutshell you just need to write a simple smooth filter that will average valid pixels/cells and after each smoothing refresh the known points so they stay constant. – Spektre Sep 23 '16 at 07:52
  • @E75 I added [edit2] to that linked answer of mine – Spektre Sep 23 '16 at 08:17

0 Answers0