コード例 #1
0
        public object Multiply(object x, object y)
        {
            if (x == null)
            {
                throw new ArgumentNullException(nameof(x));
            }
            if (y == null)
            {
                throw new ArgumentNullException(nameof(y));
            }

            if (x is KalkVector vx && y is KalkVector vy)
            {
                return(KalkVector.Dot(vx, vy));
            }

            if (x is KalkVector vx1 && y is KalkMatrix my)
            {
                return(KalkMatrix.Multiply(vx1, my));
            }
            if (x is KalkMatrix mx && y is KalkVector vy1)
            {
                return(KalkMatrix.Multiply(mx, vy1));
            }

            if (x is KalkMatrix mx1 && y is KalkMatrix my2)
            {
                return(KalkMatrix.Multiply(mx1, my2));
            }

            throw new ArgumentException($"Unsupported type for matrix multiplication. The combination of {Engine.GetTypeName(x)} * {Engine.GetTypeName(y)} is not supported.", nameof(x));
        }
コード例 #2
0
        public object Diagonal(object x)
        {
            if (x == null)
            {
                throw new ArgumentNullException(nameof(x));
            }

            if (x is KalkMatrix m)
            {
                return(KalkMatrix.Diagonal(m));
            }

            if (x is KalkVector v)
            {
                return(KalkVector.Diagonal(v));
            }

            throw new ArgumentException($"Invalid argument type {Engine.GetTypeName(x)}. Expecting a matrix or a vector type.", nameof(x));
        }
コード例 #3
0
        public object ReverseBits(object value)
        {
            if (value == null)
            {
                return(0);
            }

            switch (value)
            {
            case byte vbyte:
                return(ReverseBytes[vbyte]);

            case sbyte vsbyte:
                return(ReverseBytes[(byte)vsbyte]);

            case short vshort:
                return((short)((ReverseBytes[(byte)vshort] << 8) | ReverseBytes[(byte)(vshort >> 8)]));

            case ushort vushort:
                return((short)((ReverseBytes[(byte)vushort] << 8) | ReverseBytes[(byte)(vushort >> 8)]));

            case int vint:
                return((ReverseBytes[(byte)vint] << 24) |
                       (ReverseBytes[(byte)(vint >> 8)] << 16) |
                       (ReverseBytes[(byte)(vint >> 16)] << 8) |
                       ReverseBytes[(byte)(vint >> 24)]);

            case uint vuint:
                return((ReverseBytes[(byte)vuint] << 24) |
                       (ReverseBytes[(byte)(vuint >> 8)] << 16) |
                       (ReverseBytes[(byte)(vuint >> 16)] << 8) |
                       ReverseBytes[(byte)(vuint >> 24)]);

            case long vlong:
                return(((long)ReverseBytes[(byte)vlong] << 56) |
                       ((long)ReverseBytes[(byte)(vlong >> 8)] << 48) |
                       ((long)ReverseBytes[(byte)(vlong >> 16)] << 40) |
                       ((long)ReverseBytes[(byte)(vlong >> 24)] << 32) |
                       ((long)ReverseBytes[(byte)(vlong >> 32)] << 24) |
                       ((long)ReverseBytes[(byte)(vlong >> 40)] << 16) |
                       ((long)ReverseBytes[(byte)(vlong >> 48)] << 8) |
                       (long)ReverseBytes[(byte)(vlong >> 56)]);

            case ulong vulong:
                return(((ulong)ReverseBytes[(byte)vulong] << 56) |
                       ((ulong)ReverseBytes[(byte)(vulong >> 8)] << 48) |
                       ((ulong)ReverseBytes[(byte)(vulong >> 16)] << 40) |
                       ((ulong)ReverseBytes[(byte)(vulong >> 24)] << 32) |
                       ((ulong)ReverseBytes[(byte)(vulong >> 32)] << 24) |
                       ((ulong)ReverseBytes[(byte)(vulong >> 40)] << 16) |
                       ((ulong)ReverseBytes[(byte)(vulong >> 48)] << 8) |
                       (ulong)ReverseBytes[(byte)(vulong >> 56)]);

            case BigInteger bigInt:
            {
                var array = bigInt.ToByteArray();
                int mid   = array.Length / 2;
                for (int i = 0; i < mid; i++)
                {
                    var highIndex = array.Length - i - 1;
                    var high      = ReverseBytes[array[highIndex]];
                    var low       = ReverseBytes[array[i]];
                    array[i]         = high;
                    array[highIndex] = low;
                }

                if ((array.Length & 1) != 0)
                {
                    array[mid] = ReverseBytes[array[mid]];
                }
                return(new BigInteger(array));
            }

            case KalkVector vector:
                var outVector = vector.Clone();
                for (int i = 0; i < vector.Length; i++)
                {
                    var result = ReverseBits(vector.GetComponent(i));
                    outVector.SetComponent(i, result);
                }
                return(outVector);

            case KalkNativeBuffer nativeBuffer:
            {
                var buffer = new KalkNativeBuffer(nativeBuffer.Count);
                int mid    = nativeBuffer.Count / 2;
                for (int i = 0; i < mid; i++)
                {
                    var highIndex = nativeBuffer.Count - i - 1;
                    var high      = ReverseBytes[nativeBuffer[highIndex]];
                    var low       = ReverseBytes[nativeBuffer[i]];
                    buffer[i]         = high;
                    buffer[highIndex] = low;
                }

                if ((buffer.Count & 1) != 0)
                {
                    buffer[mid] = ReverseBytes[nativeBuffer[mid]];
                }

                return(buffer);
            }

            case KalkMatrix matrix:
                var uintMatrix = new KalkMatrix <int>(matrix.RowCount, matrix.ColumnCount);
                for (int y = 0; y < matrix.RowCount; y++)
                {
                    uintMatrix.SetRow(y, (KalkVector <int>)ReverseBits(matrix.GetRow(y)));
                }
                return(uintMatrix);

            default:
                throw new ArgumentException($"The type {Engine.GetTypeName(value)} is not supported.", nameof(value));
            }
        }
コード例 #4
0
        public object FirstBitLow(object value)
        {
            if (value == null)
            {
                return(0);
            }

            switch (value)
            {
            case sbyte vsbyte:
            {
                var result = BitOperations.TrailingZeroCount(vsbyte);
                if (result >= 32)
                {
                    return(-1);
                }
                return(result);
            }

            case byte vbyte:
            {
                var result = BitOperations.TrailingZeroCount(vbyte);
                if (result >= 32)
                {
                    return(-1);
                }
                return(result);
            }

            case short vshort:
            {
                var result = BitOperations.TrailingZeroCount(vshort);
                if (result >= 32)
                {
                    return(-1);
                }
                return(result);
            }

            case ushort vushort:
            {
                var result = BitOperations.TrailingZeroCount(vushort);
                if (result >= 32)
                {
                    return(-1);
                }
                return(result);
            }

            case int vint:
            {
                var result = BitOperations.TrailingZeroCount(vint);
                if (result >= 32)
                {
                    return(-1);
                }
                return(result);
            }

            case uint vuint:
            {
                var result = BitOperations.TrailingZeroCount(vuint);
                if (result >= 32)
                {
                    return(-1);
                }
                return(result);
            }

            case long vlong:
            {
                var result = BitOperations.TrailingZeroCount(vlong);
                if (result >= 64)
                {
                    return(-1);
                }
                return(result);
            }

            case ulong vulong:
            {
                var result = BitOperations.TrailingZeroCount(vulong);
                if (result >= 64)
                {
                    return(-1);
                }
                return(result);
            }

            case BigInteger bigint:
                if (bigint >= 0 && bigint <= ulong.MaxValue)
                {
                    var result = BitOperations.TrailingZeroCount((ulong)bigint);
                    if (result >= 64)
                    {
                        return(-1);
                    }
                    return(result);
                }
                else if (bigint < 0 && bigint >= long.MinValue)
                {
                    var result = BitOperations.TrailingZeroCount((long)bigint);
                    if (result >= 64)
                    {
                        return(-1);
                    }
                    return(result);
                }
                // TODO: implement this case for bigint
                goto default;

            case KalkVector vector:
                var uintVector = new KalkVector <int>(vector.Length);
                for (int i = 0; i < vector.Length; i++)
                {
                    var result = FirstBitLow(vector.GetComponent(i));
                    if (result is int intv)
                    {
                        uintVector[i] = (int)intv;
                    }
                    else
                    {
                        uintVector[i] = (int)(long)result;
                    }
                }
                return(uintVector);

            case KalkMatrix matrix:
                var uintMatrix = new KalkMatrix <int>(matrix.RowCount, matrix.ColumnCount);
                for (int y = 0; y < matrix.RowCount; y++)
                {
                    uintMatrix.SetRow(y, (KalkVector <int>)FirstBitLow(matrix.GetRow(y)));
                }
                return(uintMatrix);

            default:
                throw new ArgumentException($"The type {Engine.GetTypeName(value)} is not supported.", nameof(value));
            }
        }
コード例 #5
0
        public object FirstBitHigh(object value)
        {
            if (value == null)
            {
                return(0);
            }

            switch (value)
            {
            case sbyte vsbyte:
            {
                var result = BitOperations.LeadingZeroCount((byte)(uint)vsbyte);
                if (result >= 32)
                {
                    return(-1);
                }
                return(result - 24);
            }

            case byte vbyte:
            {
                var result = BitOperations.LeadingZeroCount(vbyte);
                if (result >= 32)
                {
                    return(-1);
                }
                return(result - 24);
            }

            case short vshort:
            {
                var result = BitOperations.LeadingZeroCount((ushort)(uint)vshort);
                if (result >= 32)
                {
                    return(-1);
                }
                return(result - 16);
            }

            case ushort vushort:
            {
                var result = BitOperations.LeadingZeroCount((uint)vushort);
                if (result >= 32)
                {
                    return(-1);
                }
                return(result - 16);
            }

            case int vint:
            {
                var result = BitOperations.LeadingZeroCount((uint)vint);
                if (result >= 32)
                {
                    return(-1);
                }
                return(result);
            }

            case uint vuint:
            {
                var result = BitOperations.LeadingZeroCount((uint)vuint);
                if (result >= 32)
                {
                    return(-1);
                }
                return(result);
            }

            case long vlong:
            {
                var result = BitOperations.LeadingZeroCount((ulong)vlong);
                if (result >= 64)
                {
                    return(-1);
                }
                return(result);
            }

            case ulong vulong:
            {
                var result = BitOperations.LeadingZeroCount((ulong)vulong);
                if (result >= 64)
                {
                    return(-1);
                }
                return(result);
            }

            case KalkVector vector:
                var uintVector = new KalkVector <int>(vector.Length);
                for (int i = 0; i < vector.Length; i++)
                {
                    var result = FirstBitHigh(vector.GetComponent(i));
                    if (result is int intv)
                    {
                        uintVector[i] = (int)intv;
                    }
                    else
                    {
                        uintVector[i] = (int)(long)result;
                    }
                }
                return(uintVector);

            case KalkMatrix matrix:
                var uintMatrix = new KalkMatrix <int>(matrix.RowCount, matrix.ColumnCount);
                for (int y = 0; y < matrix.RowCount; y++)
                {
                    uintMatrix.SetRow(y, (KalkVector <int>)FirstBitHigh(matrix.GetRow(y)));
                }
                return(uintMatrix);

            default:
                throw new ArgumentException($"The type {Engine.GetTypeName(value)} is not supported.", nameof(value));
            }
        }
コード例 #6
0
        public object CountBits(object value)
        {
            if (value == null)
            {
                return(0);
            }

            switch (value)
            {
            case byte vbyte:
                return(BitOperations.PopCount(vbyte));

            case sbyte vsbyte:
                return(BitOperations.PopCount((uint)vsbyte));

            case short vshort:
                return(BitOperations.PopCount((uint)vshort));

            case ushort vushort:
                return(BitOperations.PopCount((uint)vushort));

            case int vint:
                return(BitOperations.PopCount((uint)vint));

            case uint vuint:
                return(BitOperations.PopCount((uint)vuint));

            case long vlong:
                return(BitOperations.PopCount((ulong)vlong));

            case ulong vulong:
                return(BitOperations.PopCount((ulong)vulong));

            case BigInteger bigInt:
            {
                // TODO: not optimized, should use 64 bits
                var array = bigInt.ToByteArray();
                int count = 0;
                for (int i = 0; i < array.Length; i++)
                {
                    count += BitOperations.PopCount(array[i]);
                }
                return(count);
            }

            case KalkVector vector:
                var uintVector = new KalkVector <int>(vector.Length);
                for (int i = 0; i < vector.Length; i++)
                {
                    var result = CountBits(vector.GetComponent(i));
                    if (result is int intv)
                    {
                        uintVector[i] = (int)intv;
                    }
                    else
                    {
                        uintVector[i] = (int)(long)result;
                    }
                }
                return(uintVector);

            case KalkNativeBuffer nativeBuffer:
            {
                var span  = nativeBuffer.AsSpan();
                int count = 0;
                for (int i = 0; i < span.Length; i++)
                {
                    count += BitOperations.PopCount(span[i]);
                }
                return(count);
            }

            case KalkMatrix matrix:
                var uintMatrix = new KalkMatrix <int>(matrix.RowCount, matrix.ColumnCount);
                for (int y = 0; y < matrix.RowCount; y++)
                {
                    uintMatrix.SetRow(y, (KalkVector <int>)CountBits(matrix.GetRow(y)));
                }
                return(uintMatrix);

            default:
                throw new ArgumentException($"The type {Engine.GetTypeName(value)} is not supported.", nameof(value));
            }
        }
コード例 #7
0
 public static KalkMatrix Inverse(KalkMatrix m) => KalkMatrix.Inverse(m);
コード例 #8
0
 public static object Determinant(KalkMatrix m) => KalkMatrix.Determinant(m);
コード例 #9
0
 public static KalkMatrix Identity(KalkMatrix m) => KalkMatrix.Identity(m);
コード例 #10
0
 public static KalkMatrix Transpose(KalkMatrix m) => KalkMatrix.Transpose(m);
コード例 #11
0
 public KalkVector GetColumn(KalkMatrix x, int index)
 {
     return(x.GetColumn(index));
 }
コード例 #12
0
 public KalkVector GetRow(KalkMatrix x, int index)
 {
     return(x.GetRow(index));
 }