private calculatedPoint findMostDistantPoint(double[][] allPoints, double[] refPoint)
        {
            calculatedPoint mostDistantPoint = new calculatedPoint();
            mostDistantPoint.pointValue = new double[refPoint.Length];
            mostDistantPoint.pointID = 0;

            double maxDist = 0;

            //from ref point find the most distant point
            for (int i = 0; i < allPoints.Length; i++)
            {
                double d = 0;
                for (int j = 0; j < allPoints[i].Length; j++)
                    d += (refPoint[j] - allPoints[i][j]) * (refPoint[j] - allPoints[i][j]);
                d = Math.Sqrt(d);
                if (d > maxDist)
                {
                    maxDist = d;
                    mostDistantPoint.pointValue = allPoints[i];
                    mostDistantPoint.pointID = i;
                }
            }
            return mostDistantPoint;
        }
        private calculatedPoint findMostDistantPointFromMult(double[][] allPoints, double[][] refPoints)
        {
            calculatedPoint mostDistantPoint = new calculatedPoint();
            mostDistantPoint.pointValue = new double[refPoints[0].Length];
            mostDistantPoint.pointID = 0;

            double maxDist = 0;
            bool isTheSamePoint = false;

            //from ref point find the most distant point
            for (int i = 0; i < allPoints.Length; i++)
            {
                double sumPointDist = 0;
                // check to not compare with point that has already been used
                isTheSamePoint = false;
                for (int j = 0; j < refPoints.Length; j++)
                    if (allPoints[i] == refPoints[j]) isTheSamePoint = true;
                if (!isTheSamePoint)
                {
                    for (int j = 0; j < refPoints.Length; j++)
                    {
                        if (allPoints[i] != refPoints[j])
                        {
                            double d = 0;
                            for (int k = 0; k < refPoints[j].Length; k++)
                                d += (refPoints[j][k] - allPoints[i][k]) * (refPoints[j][k] - allPoints[i][k]);
                            d = Math.Sqrt(d);
                            sumPointDist = d;
                        }
                    }
                    if (sumPointDist > maxDist)
                    {
                        maxDist = sumPointDist;
                        mostDistantPoint.pointValue = allPoints[i];
                        mostDistantPoint.pointID = i;
                    }
                }   
            }
            return mostDistantPoint;
        }
        private double[][] SIVM_algorithm(double[][] points)
        {
            //number of points for the volume is 2^number of dimensions. i.e: 2D = square, 3D = cube, 4D = no idea how its called!
            int dimensions = System.Convert.ToInt16(points[0].Length);
            int numberOfPoints = System.Convert.ToInt16(Math.Pow(2, dimensions));
            double[][] volumePoints = new double[numberOfPoints][];
            double[] volumePointsID = new double[numberOfPoints];

            //normalize data
            double[][] normalizedData = normalizeData(points);

            //find a random P1 point in the sample
            Random rnd = new Random();
            double[] P1 = normalizedData[rnd.Next(0, normalizedData.Length)];          

            //from P1, find the most distant point -> P2
            calculatedPoint P2 = findMostDistantPoint(normalizedData, P1);

            //from P2, find the most distant point -> P3 (first volume coordinate)
            volumePoints[0] = new double[dimensions];
            calculatedPoint P3 = findMostDistantPoint(normalizedData, P2.pointValue);
            volumePoints[0] = P3.pointValue;
            volumePointsID[0] = P3.pointID;

            //from P3, find the most distant point -> P4 (second volume coordinate)
            volumePoints[1] = new double[dimensions];
            calculatedPoint P4 = findMostDistantPoint(normalizedData, P3.pointValue);
            volumePoints[1] = P4.pointValue;
            volumePointsID[1] = P4.pointID;

            //Calculate the most distant point from all points
            for(int i = 2; i < numberOfPoints; i++) //two first points are already allocated
            {
                calculatedPoint PI = new calculatedPoint();
                volumePoints[i] = new double[dimensions]; 
                double[][] currentPoints = new double[i][];
                for(int j = 0; j < i; j++)
                {
                    currentPoints[j] = new double[dimensions];
                    currentPoints[j] = volumePoints[j];
                }
                PI = findMostDistantPointFromMult(normalizedData, currentPoints);
                volumePoints[i] = PI.pointValue;
                volumePointsID[i] = PI.pointID;
            }

            //the calculation was made with normalized data, now we need to get the ids and save the actual points values
            double[][] nonNormalizedVolPoints = new double[numberOfPoints][];

            for (int i = 0; i < points.Length; i++)
            {
                for(int k = 0; k < volumePointsID.Length; k++)
                {
                    if(i == volumePointsID[k])
                       nonNormalizedVolPoints[k] = points[i];
                }               
            }

            return nonNormalizedVolPoints;
        }