Exemplo n.º 1
0
 /// <summary>
 /// Initializes static members of the Control class.
 /// </summary>
 static Control()
 {
     CheckDistributionParameters      = true;
     ThreadSafeRandomNumberGenerators = true;
     DisableParallelization           = false;
     LinearAlgebraProvider            = new ManagedLinearAlgebraProvider();
 }
Exemplo n.º 2
0
        /// <summary>
        /// Initializes static members of the Control class.
        /// </summary>
        static Control()
        {
            CheckDistributionParameters = true;
            ThreadSafeRandomNumberGenerators = true;
            DisableParallelization = false;

            #if PORTABLE
            LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
            #else
            try
            {
                const string name = "MathNetNumericsLAProvider";
                var value = Environment.GetEnvironmentVariable(name);
                switch (value != null ? value.ToUpper() : string.Empty)
                {
                    case "MKL":
                        LinearAlgebraProvider = new MathNet.Numerics.Algorithms.LinearAlgebra.Mkl.MklLinearAlgebraProvider();
                        break;
                    default:
                        LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
                        break;
                }
            }
            catch
            {
                // We don't care about any failures here at all
                LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
            }
            #endif
        }
Exemplo n.º 3
0
 /// <summary>
 /// Initializes static members of the Control class.
 /// </summary>
 static Control()
 {
     CheckDistributionParameters = true;
     ThreadSafeRandomNumberGenerators = true;
     DisableParallelization = false;
     LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
 }
Exemplo n.º 4
0
        public static void ConfigureAuto()
        {
            // Random Numbers & Distributions
            CheckDistributionParameters = true;

            // Parallelization & Threading
            ThreadSafeRandomNumberGenerators = true;
            _maxDegreeOfParallelism          = Environment.ProcessorCount;
            _blockSize           = 512;
            _parallelizeOrder    = 64;
            _parallelizeElements = 300;
            TaskScheduler        = TaskScheduler.Default;

            // Linear Algebra Provider
#if PORTABLE
            LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
#else
            try
            {
                var value = Environment.GetEnvironmentVariable(EnvVarLAProvider);
                switch (value != null ? value.ToUpperInvariant() : string.Empty)
                {
#if NATIVE
                case "MKL":
                    UseNativeMKL();
                    break;

                case "CUDA":
                    UseNativeCUDA();
                    break;

                case "OPENBLAS":
                    UseNativeOpenBLAS();
                    break;

                default:
#if NATIVE
                    if (!TryUseNative())
#endif
                    {
                        UseManaged();
                    }
                    break;
#else
                default:
                    UseManaged();
                    break;
#endif
                }
            }
            catch
            {
                // We don't care about any failures here at all (because "auto")
                UseManaged();
            }
#endif
        }
Exemplo n.º 5
0
        /// <summary>
        /// Maximum of the absolute value of all Eigenvalues of <paramref name="H"/>.
        /// </summary>
        static public double MaxAbsEigen(double[,] H)
        {
            var linalg = new ManagedLinearAlgebraProvider();

            double Eigen;
            int    N = H.GetLength(0);

            double[] Matrix    = H.Resize(false);
            double[] EigenVect = new double[Matrix.Length];
            double[] diagM     = new double[Matrix.Length];
            System.Numerics.Complex[] EigenValues = new System.Numerics.Complex[N];
            linalg.EigenDecomp(false, N, Matrix, EigenVect, EigenValues, diagM);
            Eigen = EigenValues.Select(ev => Complex.Abs(ev)).Max();
            return(Eigen);
        }
Exemplo n.º 6
0
        public static void ConfigureAuto()
        {
            // Random Numbers & Distributions
            CheckDistributionParameters = true;

            // Parallelization & Threading
            ThreadSafeRandomNumberGenerators = true;
            _maxDegreeOfParallelism          = Environment.ProcessorCount;
            _blockSize           = 512;
            _parallelizeOrder    = 64;
            _parallelizeElements = 300;
            TaskScheduler        = TaskScheduler.Default;

            // Linear Algebra Provider
            LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
        }
Exemplo n.º 7
0
        public static void ConfigureAuto()
        {
            // Random Numbers & Distributions
            CheckDistributionParameters      = true;
            ThreadSafeRandomNumberGenerators = true;

            // ToString & Formatting
            MaxToStringColumns = 6;
            MaxToStringRows    = 8;

            // Parallelization & Threading
            _numberOfThreads       = Environment.ProcessorCount;
            DisableParallelization = _numberOfThreads < 2;
            _blockSize             = 512;
            _parallelizeOrder      = 64;
            _parallelizeElements   = 300;

            // Linear Algebra Provider
#if PORTABLE
            // GetEnvironmentVariable is not available in portable!
            LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
#else
            try
            {
                const string name  = "MathNetNumericsLAProvider";
                var          value = Environment.GetEnvironmentVariable(name);
                switch (value != null ? value.ToUpperInvariant() : string.Empty)
                {
#if NATIVEMKL
                case "MKL":
                    LinearAlgebraProvider = new Providers.LinearAlgebra.Mkl.MklLinearAlgebraProvider();
                    break;
#endif
                default:
                    LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
                    break;
                }
            }
            catch
            {
                // We don't care about any failures here at all
                LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
            }
#endif
        }
Exemplo n.º 8
0
        public static void ConfigureAuto()
        {
            // Random Numbers & Distributions
            CheckDistributionParameters = true;

            // Parallelization & Threading
            ThreadSafeRandomNumberGenerators = true;
            _maxDegreeOfParallelism          = Environment.ProcessorCount;
            _blockSize           = 512;
            _parallelizeOrder    = 64;
            _parallelizeElements = 300;
            TaskScheduler        = TaskScheduler.Default;

            // Linear Algebra Provider
#if PORTABLE
            LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
#else
            try
            {
                const string name  = "MathNetNumericsLAProvider";
                var          value = Environment.GetEnvironmentVariable(name);
                switch (value != null ? value.ToUpperInvariant() : string.Empty)
                {
#if NATIVE
                case "MKL":
                    LinearAlgebraProvider = new Providers.LinearAlgebra.Mkl.MklLinearAlgebraProvider();
                    break;

                case "CUDA":
                    LinearAlgebraProvider = new Providers.LinearAlgebra.Cuda.CudaLinearAlgebraProvider();
                    break;
#endif
                default:
                    LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
                    break;
                }
            }
            catch
            {
                // We don't care about any failures here at all (because "auto")
                LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
            }
#endif
        }
Exemplo n.º 9
0
        public static void ConfigureAuto()
        {
            // Random Numbers & Distributions
            CheckDistributionParameters = true;
            ThreadSafeRandomNumberGenerators = true;

            // ToString & Formatting
            MaxToStringColumns = 6;
            MaxToStringRows = 8;

            // Parallelization & Threading
            _numberOfThreads = Environment.ProcessorCount;
            DisableParallelization = _numberOfThreads < 2;
            _blockSize = 512;
            _parallelizeOrder = 64;
            _parallelizeElements = 300;

            // Linear Algebra Provider
#if NATIVEMKL
            try
            {
                const string name = "MathNetNumericsLAProvider";
                var value = Environment.GetEnvironmentVariable(name);
                switch (value != null ? value.ToUpperInvariant() : string.Empty)
                {
                    case "MKL":
                        LinearAlgebraProvider = new Algorithms.LinearAlgebra.Mkl.MklLinearAlgebraProvider();
                        break;
                    default:
                        LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
                        break;
                }
            }
            catch
            {
                // We don't care about any failures here at all
                LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
            }
#else
            LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
#endif
        }
Exemplo n.º 10
0
        public Vector3D[] identifyMajorAxes()
        {
            Vector3D[] majorAxes        = new Vector3D[3];
            double[]   covarianceMatrix = covariance();

            double[]  eigenVectors  = new double[9];
            Complex[] eigenValues   = new Complex[3];
            double[]  eigenVectorsM = new double[9];

            ManagedLinearAlgebraProvider pca = new ManagedLinearAlgebraProvider();

            pca.EigenDecomp(true, 3, covarianceMatrix, eigenVectors, eigenValues, eigenVectorsM);

            // major axis
            majorAxes[0]   = new Vector3D();
            majorAxes[0].X = eigenVectors[6];
            majorAxes[0].Y = eigenVectors[7];
            majorAxes[0].Z = eigenVectors[8];

            majorAxes[1]   = new Vector3D();
            majorAxes[1].X = eigenVectors[3];
            majorAxes[1].Y = eigenVectors[4];
            majorAxes[1].Z = eigenVectors[5];

            majorAxes[2]   = new Vector3D();
            majorAxes[2].X = eigenVectors[0];
            majorAxes[2].Y = eigenVectors[1];
            majorAxes[2].Z = eigenVectors[2];

            _transformMatrix = new Matrix3D(majorAxes[0].X, majorAxes[1].X, majorAxes[2].X, 0,
                                            majorAxes[0].Y, majorAxes[1].Y, majorAxes[2].Y, 0,
                                            majorAxes[0].Z, majorAxes[1].Z, majorAxes[2].Z, 0,
                                            -Centroid.X, -Centroid.Y, -Centroid.Z, 1);

            List <Point3D> trOBBV = transformPointSet();
            BoundingBox3D  trOBB  = new BoundingBox3D(trOBBV);

            OBB = transformBackPointSet(trOBB.BBVertices);
            return(majorAxes);
        }
Exemplo n.º 11
0
 public static void UseManaged()
 {
     LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
 }
Exemplo n.º 12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LinearAlgebraProviderTests"/> class.
 /// </summary>
 public LinearAlgebraProviderTests()
 {
     Provider = new ManagedLinearAlgebraProvider();
 }
Exemplo n.º 13
0
        /// <summary>
        /// Execute the expression.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void executeExpression_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                uint   variableSize = 0U;
                double result       = 0.0;
                Dictionary <string, double> variables = new Dictionary <string, double>();

                // Execute the expression.
                string expression        = expressionWindowText.Text;
                string expressionReplace = expression;
                string expressionResult  = "";

                // Create the math object.
                Nequeo.Math.MathGenerics <bool> math = new Nequeo.Math.MathGenerics <bool>();

                string[] names  = null;
                string[] values = null;

                // Get the variables.
                if (!String.IsNullOrEmpty(variableNamesText.Text) &&
                    !String.IsNullOrEmpty(variableValuesText.Text))
                {
                    names  = variableNamesText.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    values = variableValuesText.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                    // For each variable.
                    for (int i = 0; i < names.Length; i++)
                    {
                        try
                        {
                            // Add variables.
                            variables.Add(names[i].Trim(), Double.Parse(values[i].Trim()));

                            // Replace variable with value.
                            //expressionReplace = expressionReplace.Replace(names[i].Trim(), "(" + values[i].Trim() + ")");
                        }
                        catch { }
                    }

                    // If multi variable.
                    if (variables.Count > 1)
                    {
                        variableSize = 2U;
                    }
                    else
                    {
                        variableSize = 1U;
                    }
                }

                // Select the extra operation index.
                switch (customExceuteOp.SelectedIndex)
                {
                case 10:
                    // Exponential Integral Function
                    string[] exponential = expression.Trim().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    double   xExp        = Double.Parse(exponential[0].ToString().Trim());
                    int      nExp        = Int32.Parse(exponential[1].ToString().Trim());

                    result            = Nequeo.Science.Math.SpecialFunctions.ExponentialIntegral(xExp, nExp);
                    expressionResult  = result.ToString();
                    expressionReplace = "Exponential Integral Function : \r\n" +
                                        "x = " + xExp.ToString() + ", n = " + nExp.ToString();
                    break;

                case 9:
                    // Regularized Lower Incomplete Beta Function.
                    // I_x(a,b) = 1/ Beta(a,b) * int(t^(a-1)*(1-t)^(b-1),t=0..x) for real a > 0, b > 0, 1 >= x >= 0.
                    string[] beta  = expression.Trim().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    double   aBeta = Double.Parse(beta[0].ToString().Trim());
                    double   bBeta = Double.Parse(beta[1].ToString().Trim());
                    double   xBeta = Double.Parse(beta[2].ToString().Trim());

                    result            = Nequeo.Science.Math.SpecialFunctions.BetaRegularized(aBeta, bBeta, xBeta);
                    expressionResult  = result.ToString();
                    expressionReplace = "Regularized Lower Incomplete Beta Function : \r\n" +
                                        "I_x(a,b) = 1/ Beta(a,b) * int(t^(a-1)*(1-t)^(b-1),t=0..x) for real a > 0, b > 0, 1 >= x >= 0\r\n" +
                                        "a = " + aBeta.ToString() + ", b = " + bBeta.ToString() + ", x = " + xBeta.ToString();
                    break;

                case 8:
                    // Binomial n choose k
                    string[] binomial = expression.Trim().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    int      nB       = Int32.Parse(binomial[0].ToString().Trim());
                    int      kB       = Int32.Parse(binomial[1].ToString().Trim());

                    result            = Nequeo.Science.Math.SpecialFunctions.Binomial(nB, kB);
                    expressionResult  = result.ToString();
                    expressionReplace = "Binomial n choose k : \r\n" + nB.ToString() + " choose " + kB.ToString();
                    break;

                case 7:
                    // Factorial n!
                    System.Numerics.BigInteger nF     = new System.Numerics.BigInteger(Double.Parse(expression.Trim()));
                    System.Numerics.BigInteger bitInt = Nequeo.Science.Math.SpecialFunctions.Factorial(nF);
                    expressionResult  = bitInt.ToString();
                    expressionReplace = "Factorial n! : \r\n" + nF.ToString() + "!";
                    break;

                case 6:
                    // Cubic Roots a*x^3 + b*x^2 + c*x + d = 0.
                    Tuple <Complex, Complex, Complex> cubicRoots = Nequeo.Science.Math.FindRoots.Cubic(variables["b"], variables["c"], variables["b"], variables["a"]);
                    expressionResult  = "Real = " + cubicRoots.Item1.Real.ToString() + ", Imaginary = " + cubicRoots.Item1.Imaginary.ToString() + "\r\n";
                    expressionResult += "Real = " + cubicRoots.Item2.Real.ToString() + ", Imaginary = " + cubicRoots.Item2.Imaginary.ToString() + "\r\n";
                    expressionResult += "Real = " + cubicRoots.Item3.Real.ToString() + ", Imaginary = " + cubicRoots.Item3.Imaginary.ToString();
                    expressionReplace = "Cubic Roots a*x^3 + b*x^2 + c*x + d = 0 : \r\n" + expressionReplace;
                    break;

                case 5:
                    // Quadratic Roots a*x^2 + b*x + c = 0.
                    Tuple <Complex, Complex> quadraticRoots = Nequeo.Science.Math.FindRoots.Quadratic(variables["c"], variables["b"], variables["a"]);
                    expressionResult  = "Real = " + quadraticRoots.Item1.Real.ToString() + ", Imaginary = " + quadraticRoots.Item1.Imaginary.ToString() + "\r\n";
                    expressionResult += "Real = " + quadraticRoots.Item2.Real.ToString() + ", Imaginary = " + quadraticRoots.Item2.Imaginary.ToString();
                    expressionReplace = "Quadratic Roots a*x^2 + b*x + c = 0 : \r\n" + expressionReplace;
                    break;

                case 4:
                    // Equation Root f(x) = 0.
                    object[] expressionParameters = (variables.Count > 0 ? new object[variables.Count] : null);
                    int      varIndex             = 0;

                    // Replace the expression.
                    string hidedExpression = ReplaceExpressionHide(expression.Trim());

                    // For each variable.
                    foreach (KeyValuePair <string, double> item in variables)
                    {
                        // Replace the variable names.
                        hidedExpression = hidedExpression.Replace(item.Key, "@" + varIndex++.ToString());

                        // Add the variable parameter.
                        expressionParameters[varIndex - 1] = item.Value;
                    }

                    // Replace the expression.
                    string replacedExpression = ReplaceExpression(hidedExpression.Trim());

                    // A parameter for the lambda expression.
                    System.Linq.Expressions.ParameterExpression paramExpr = System.Linq.Expressions.Expression.Parameter(typeof(double), "x");
                    ParameterExpression[] pe = new List <ParameterExpression>()
                    {
                        paramExpr
                    }.ToArray();
                    LambdaExpression lambda = Nequeo.Linq.DynamicExpression.ParseLambda(pe, typeof(double), replacedExpression.Trim(), expressionParameters);

                    // Get the function.
                    Func <double, double> function = (Func <double, double>)lambda.Compile();
                    result = Nequeo.Science.Math.FindRoots.OfFunction(function, Double.Parse(aVariableEquationRoot.Text), Double.Parse(bVariableEquationRoot.Text));

                    expressionReplace = "Equation Root f(x) = 0 : \r\n" + expressionReplace + " = 0";
                    expressionResult  = result.ToString();
                    break;

                case 3:
                    // Linear Algebra.
                    // Use managed provider to solver system.
                    ILinearAlgebraProvider <double> provider = new ManagedLinearAlgebraProvider();

                    // Variable names.
                    names = variableNamesText.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                    // Get row and column lengths.
                    string[] aRowColumn = aColumnsRowsLinearAlgebra.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    int      aRow       = Int32.Parse(aRowColumn[0].Trim());
                    int      aColumn    = Int32.Parse(aRowColumn[1].Trim());
                    int      bColumn    = Int32.Parse(bColumnsLinearAlgebra.Text.Trim());

                    // Variables.
                    double[] a = new double[aRow * aColumn];
                    double[] b = new double[aRow * bColumn];

                    // Get the equation.
                    string[] equations = expression.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                    for (int eq = 0; eq < equations.Length; eq++)
                    {
                        // Current equation.
                        string[] eqAB = equations[eq].Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);

                        // Assign B vector.
                        b[eq] = Double.Parse(eqAB[1].Trim());

                        // Get each variable.
                        string[] eqA = eqAB[0].Replace("-", "+ -").Replace("+ - ", "+ -").Split(new char[] { '+' }, StringSplitOptions.RemoveEmptyEntries);
                        for (int equa = 0; equa < eqA.Length; equa++)
                        {
                            // Get current value.
                            string currentRowColumnValue = eqA[equa];

                            // Replace variable names.
                            for (int v = 0; v < names.Length; v++)
                            {
                                // Remove variable name.
                                currentRowColumnValue = currentRowColumnValue.Replace(names[v].Trim(), "");
                            }

                            // Convert to double.
                            double aRCValue = Double.Parse(
                                (String.IsNullOrEmpty(currentRowColumnValue.Trim()) ? "1" :
                                 (currentRowColumnValue.Trim() == "-" ? "-1" : currentRowColumnValue.Trim()))
                                );

                            // Assign the A matrix.
                            a[(eq * aRow) + equa] = aRCValue;
                        }
                    }

                    // Re-arrage A.
                    double[] ax = new double[aRow * aColumn];
                    for (int row = 0; row < aRow; row++)
                    {
                        for (int column = 0; column < aColumn; column++)
                        {
                            // Assign
                            ax[(row * aRow) + column] = a[row + (column * aColumn)];
                        }
                    }

                    // The result.
                    double[] x = new double[names.Length];

                    // Solver the system.
                    provider.SvdSolve(ax, aRow, aColumn, b, bColumn, x);

                    // The result.
                    for (int z = 0; z < x.Length; z++)
                    {
                        // Result string.
                        expressionResult += names[z].Trim() + " = " + x[z].ToString() + "\r\n";
                    }
                    expressionReplace = "System Linear Equation Solver : \r\n" + expressionReplace;
                    break;

                case 2:
                    // Derivative.
                    result            = math.ExpressionDerivative <double>(expression, Double.Parse(xVariableDerivative.Text), "x", variables);
                    expressionReplace = "Derivative at (" + xVariableDerivative.Text + ") : " + expressionReplace;
                    expressionResult  = result.ToString();
                    break;

                case 1:
                    // Integrate.
                    result            = math.ExpressionIntegrate <double>(expression, 0.0, "x", Double.Parse(aVariableIntegrate.Text), Double.Parse(bVariableIntegrate.Text), variables);
                    expressionReplace = "Integral at (x) interval [" + aVariableIntegrate.Text + ", " + bVariableIntegrate.Text + "] : " + expressionReplace;
                    expressionResult  = result.ToString();
                    break;

                case 0:
                default:
                    // Select the variable number.
                    switch (variableSize)
                    {
                    case 2U:
                        result           = math.ExpressionMulti <double>(expression, variables);
                        expressionResult = result.ToString();
                        break;

                    case 1U:
                        result           = math.Expression <double>(expression, variables.Values.First(), variables.Keys.First());
                        expressionResult = result.ToString();
                        break;

                    case 0U:
                    default:
                        result           = math.Expression <double>(expression);
                        expressionResult = result.ToString();
                        break;
                    }
                    break;
                }

                // Display the result.
                UI.ResultWindow resultWindow = new UI.ResultWindow(expressionResult, expressionReplace);
                resultWindow.Show();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Scientific Calculator", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        public static Plane PlaneFromDepthData(Float4[,] Data, Region region)
        {
            int   width  = Data.GetLength(0);
            int   height = Data.GetLength(1);
            Plane P      = new Plane();
            //Area selection
            int     minX   = (region.MinX < 0 ? 0 : region.MinX);
            int     maxX   = (region.MaxX > width ? width : region.MaxX);
            int     minY   = (region.MinY < 0 ? 0 : region.MinY);
            int     maxY   = (region.MaxY > height ? height : region.MaxY);
            int     jumpX  = width - (maxX - minX);
            int     startX = minY * width + minX;
            int     count  = 0;
            Vector3 pos    = Vector3.Zero;

            unsafe
            {
                fixed(Float4 *sData = &Data[0, 0])
                {
                    //Calculate origin
                    Float4 *pData = sData + startX;

                    for (int y = minY; y < maxY; y++)
                    {
                        for (int x = minX; x < maxX; x++)
                        {
                            pData++;
                            if (region.Covered(x, y) && pData->W != 0f)
                            {
                                pos.X += pData->X;
                                pos.Y += pData->Y;
                                pos.Z += pData->Z;
                                count++;
                            }
                        }
                        pData += jumpX;
                    }
                    pos     /= count;
                    P.Origin = new Vector3(pos.X, pos.Y, pos.Z);

                    //Calculate normal
                    double x2, y2, z2, xy, xz, yz;

                    x2 = y2 = z2 = xy = xz = yz = 0;
                    double rx, ry, rz;

                    pData = sData + startX;
                    for (int y = minY; y < maxY; y++)
                    {
                        for (int x = minX; x < maxX; x++)
                        {
                            pData++;
                            if (region.Covered(x, y) && pData->W != 0f)
                            {
                                pos = new Vector3(pData->X, pData->Y, pData->Z);
                                rx  = pos.X - P.Origin.X;
                                ry  = pos.Y - P.Origin.Y;
                                rz  = pos.Z - P.Origin.Z;
                                x2 += rx * rx;
                                y2 += ry * ry;
                                z2 += rz * rz;
                                xy += rx * ry;
                                xz += rx * rz;
                                yz += ry * rz;
                            }
                        }
                        pData += jumpX;
                    }
                    ManagedLinearAlgebraProvider linear = new ManagedLinearAlgebraProvider();

                    double[]  matrix       = new double[] { x2, xy, xz, xy, y2, yz, xz, yz, z2 };
                    double[]  eigenVectors = new double[9];
                    Complex[] eigenValues  = new Complex[3];
                    double[]  matrixD      = new double[9];
                    linear.EigenDecomp(true, 3, matrix, eigenVectors, eigenValues, matrixD);
                    P.Normal = new Vector3(eigenVectors[0], eigenVectors[1], eigenVectors[2]);
                }
            }
            return(P);
        }