File: Utils\VectorUtils.cs
Web Access
Project: src\src\Microsoft.ML.FastTree\Microsoft.ML.FastTree.csproj (Microsoft.ML.FastTree)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using System.Text;
 
namespace Microsoft.ML.Trainers.FastTree
{
    [BestFriend]
    internal class VectorUtils
    {
        public static double GetVectorSize(double[] vector)
        {
            double sum = GetDotProduct(vector, vector);
            sum /= Math.Sqrt(sum);
            return sum;
        }
 
        // Normalizes the vector to have size of 1
        public static unsafe void NormalizeVectorSize(double[] vector)
        {
            double size = GetVectorSize(vector);
            int length = vector.Length;
            unsafe
            {
                fixed (double* pVector = vector)
                {
                    for (int i = 0; i < length; i++)
                    {
                        pVector[i] /= size;
                    }
                }
            }
        }
 
        // Center vector to have mean = 0
        public static unsafe void CenterVector(double[] vector)
        {
            double mean = GetMean(vector);
            int length = vector.Length;
            unsafe
            {
                fixed (double* pVector = vector)
                {
                    for (int i = 0; i < length; i++)
                    {
                        pVector[i] = (pVector[i] - mean);
                    }
                }
            }
        }
 
        // Normalizes the vector to have mean = 0 and std = 1
        public static unsafe void NormalizeVector(double[] vector)
        {
            double mean = GetMean(vector);
            double std = GetStandardDeviation(vector, mean);
            NormalizeVector(vector, mean, std);
        }
 
        // Normalizes the vector to have mean = 0 and std = 1
        public static unsafe void NormalizeVector(double[] vector, double mean, double std)
        {
            int length = vector.Length;
            unsafe
            {
                fixed (double* pVector = vector)
                {
                    for (int i = 0; i < length; i++)
                    {
                        pVector[i] = (pVector[i] - mean) / std;
                    }
                }
            }
        }
 
        public static unsafe double GetDotProduct(double[] vector1, double[] vector2)
        {
            return GetDotProduct(vector1, vector2, vector1.Length);
        }
 
        public static unsafe double GetDotProduct(float[] vector1, float[] vector2)
        {
            return GetDotProduct(vector1, vector2, vector1.Length);
        }
 
        public static unsafe double GetDotProduct(double[] vector1, double[] vector2, int length)
        {
            double product = 0;
            unsafe
            {
                fixed (double* pVector1 = vector1)
                fixed (double* pVector2 = vector2)
                {
                    for (int i = 0; i < length; i++)
                    {
                        product += pVector1[i] * pVector2[i];
                    }
                }
            }
            return product;
        }
 
        public static unsafe double GetDotProduct(float[] vector1, float[] vector2, int length)
        {
            double product = 0;
            unsafe
            {
                fixed (float* pVector1 = vector1)
                fixed (float* pVector2 = vector2)
                {
                    for (int i = 0; i < length; i++)
                    {
                        product += pVector1[i] * pVector2[i];
                    }
                }
            }
            return product;
        }
 
        public static unsafe double GetMean(double[] vector)
        {
            double sum = 0;
            int length = vector.Length;
            unsafe
            {
                fixed (double* pVector = vector)
                {
                    for (int i = 0; i < length; i++)
                    {
                        sum += pVector[i];
                    }
                }
            }
            return sum / length;
        }
 
        public static unsafe double GetMean(float[] vector)
        {
            double sum = 0;
            int length = vector.Length;
            unsafe
            {
                fixed (float* pVector = vector)
                {
                    for (int i = 0; i < length; i++)
                    {
                        sum += pVector[i];
                    }
                }
            }
            return sum / length;
        }
 
        public static double GetStandardDeviation(double[] vector)
        {
            return GetStandardDeviation(vector, GetMean(vector));
        }
 
        public static unsafe double GetStandardDeviation(double[] vector, double mean)
        {
            double sum = 0;
            int length = vector.Length;
            double tmp;
            unsafe
            {
                fixed (double* pVector = vector)
                {
                    for (int i = 0; i < length; i++)
                    {
                        tmp = pVector[i] - mean;
                        sum += tmp * tmp;
                    }
                }
            }
            return Math.Sqrt(sum / length);
        }
 
        public static unsafe int GetIndexOfMax(double[] vector)
        {
            int length = vector.Length;
            double max = vector[0];
            int maxIdx = 0;
            unsafe
            {
                fixed (double* pVector = vector)
                {
                    for (int i = 1; i < length; i++)
                    {
                        if (pVector[i] > max)
                        {
                            max = pVector[i];
                            maxIdx = i;
                        }
                    }
                }
            }
            return maxIdx;
        }
 
        // Subtracts the second vector from the first one (vector1[i] -= vector2[i])
        public static unsafe void SubtractInPlace(double[] vector1, double[] vector2)
        {
            int length = vector1.Length;
            unsafe
            {
                fixed (double* pVector1 = vector1)
                fixed (double* pVector2 = vector2)
                {
                    for (int i = 0; i < length; i++)
                    {
                        pVector1[i] -= pVector2[i];
                    }
                }
            }
        }
 
        public static unsafe double[] Subtract(double[] vector1, double[] vector2)
        {
            int length = vector1.Length;
            double[] result = new double[length];
            unsafe
            {
                fixed (double* pResult = result)
                fixed (double* pVector1 = vector1)
                fixed (double* pVector2 = vector2)
                {
                    for (int i = 0; i < length; i++)
                    {
                        pResult[i] = pVector1[i] - pVector2[i];
                    }
                }
            }
            return result;
        }
 
        // Subtracts the second vector from the first one (vector1[i] += vector2[i])
        public static unsafe void AddInPlace(double[] vector1, double[] vector2)
        {
            int length = vector1.Length;
            unsafe
            {
                fixed (double* pVector1 = vector1)
                fixed (double* pVector2 = vector2)
                {
                    for (int i = 0; i < length; i++)
                    {
                        pVector1[i] += pVector2[i];
                    }
                }
            }
        }
 
        // Mutiplies the second vector from the first one (vector1[i] /= val)
        public static unsafe void MutiplyInPlace(double[] vector, double val)
        {
            int length = vector.Length;
            unsafe
            {
                fixed (double* pVector = vector)
                {
                    for (int i = 0; i < length; i++)
                    {
                        pVector[i] *= val;
                    }
                }
            }
        }
 
        // Divides the second vector from the first one (vector1[i] /= val)
        public static unsafe void DivideInPlace(double[] vector, double val)
        {
            int length = vector.Length;
            unsafe
            {
                fixed (double* pVector = vector)
                {
                    for (int i = 0; i < length; i++)
                    {
                        pVector[i] /= val;
                    }
                }
            }
        }
 
        // Divides the second vector from the first one (vector1[i] /= val)
        public static unsafe void DivideInPlace(float[] vector, float val)
        {
            int length = vector.Length;
            unsafe
            {
                fixed (float* pVector = vector)
                {
                    for (int i = 0; i < length; i++)
                    {
                        pVector[i] /= val;
                    }
                }
            }
        }
 
        public static unsafe double GetEuclideanDistance(double[] vector1, double[] vector2)
        {
            double sum = 0;
            double diff;
            int length = vector1.Length;
            unsafe
            {
                fixed (double* pVector1 = vector1)
                fixed (double* pVector2 = vector2)
                {
                    for (int i = 0; i < length; i++)
                    {
                        diff = pVector1[i] - pVector2[i];
                        sum += diff * diff;
                    }
                }
            }
            return Math.Sqrt(sum);
        }
 
        public static double[][] AllocateDoubleMatrix(int m, int n)
        {
            double[][] mat = new double[m][];
            for (int i = 0; i < m; i++)
            {
                mat[i] = new double[n];
            }
            return mat;
        }
 
        public static string ToString(double[] vector)
        {
            StringBuilder sb = new StringBuilder();
            for (int f = 0; f < vector.Length; f++)
            {
                if (f > 0)
                {
                    sb.Append(", ");
                }
                sb.Append(vector[f]);
            }
            return sb.ToString();
        }
    }
}