コード例 #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 Length(object x)
 {
     if (x == null)
     {
         throw new ArgumentNullException(nameof(x));
     }
     if (_mathModule == null)
     {
         throw new InvalidOperationException($"The module {Name} is not initialized.");
     }
     if (x is KalkVector v)
     {
         return(_mathModule.Sqrt(new KalkDoubleValue(KalkVector.Dot(v, v))));
     }
     return(_mathModule.Abs(new KalkCompositeValue(x)));
 }
コード例 #3
0
        public object Dot(object x, object y)
        {
            if (x is KalkVector vx)
            {
                if (y is KalkVector vy)
                {
                    return(KalkVector.Dot(vx, vy));
                }
                return(KalkVector.Dot(vx, vx.FromValue(Engine.ToObject(1, y, vx.ElementType))));
            }
            else if (y is KalkVector vy)
            {
                return(KalkVector.Dot(vy.FromValue(Engine.ToObject(1, x, vy.ElementType)), vy));
            }

            return(ScriptBinaryExpression.Evaluate(Engine, Engine.CurrentSpan, ScriptBinaryOperator.Multiply, x, y));
        }
コード例 #4
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));
        }
コード例 #5
0
 public object Cross(KalkVector x, KalkVector y)
 {
     if (x == null)
     {
         throw new ArgumentNullException(nameof(x));
     }
     if (y == null)
     {
         throw new ArgumentNullException(nameof(y));
     }
     if (x.Length != 3 || (x.ElementType != typeof(float) && x.ElementType != typeof(double)))
     {
         throw new ArgumentOutOfRangeException(nameof(x), "Expecting a float3 or double3 vector.");
     }
     if (y.Length != 3 || (y.ElementType != typeof(float) && y.ElementType != typeof(double)))
     {
         throw new ArgumentOutOfRangeException(nameof(y), "Expecting a float3 or double3 vector.");
     }
     return(KalkVector.Cross(x, y));
 }
コード例 #6
0
ファイル: IntrinsicsModuleBase.cs プロジェクト: xoofx/kalk
        private object ToResult <TBase, T>(T result) where T : unmanaged where TBase : unmanaged
        {
            var targetSize      = Unsafe.SizeOf <T>();
            var baseElementSize = Unsafe.SizeOf <TBase>();
            var dimension       = targetSize / baseElementSize;
            var span            = MemoryMarshal.Cast <T, TBase>(MemoryMarshal.CreateSpan(ref result, 1));

            if (dimension == 1)
            {
                return(span[0]);
            }
            else
            {
                var vector = new KalkVector <TBase>(dimension);
                for (int i = 0; i < dimension; i++)
                {
                    vector[i] = span[i];
                }
                return(vector);
            }
        }
コード例 #7
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));
            }
        }
コード例 #8
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));
            }
        }
コード例 #9
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));
            }
        }