예제 #1
0
        /// <summary>
        ///     Performs a binary function on lhs and rhs on a specific property (axis).
        /// </summary>
        /// <param name="rhs"></param>
        /// <param name="property">Which property from <see cref="DoubleArray.Properties"/> dimension to select and apply <paramref name="function"/> on.</param>
        /// <param name="function">The function to call for every value in this array.</param>
        /// <returns></returns>
        public virtual DoubleArray Function(DoubleArray rhs, int property, BinaryFunctionHandler function)
        {
            var lhs = this;

            if (lhs.IsScalar && lhs.Properties > property && rhs.IsScalar && rhs.Properties > property)
            {
                return(lhs[property] * rhs[property]);
            }

            int         offset = property;
            DoubleArray ret;
            int         len;

            if (lhs.IsScalar && lhs.Properties > property)
            {
                ret = rhs.Clone();
                len = ret.Count;
                var propsRhs = rhs.Properties;
                var lhs_val  = lhs[property];

                fixed(double *rhs_ptr = rhs, ret_ptr = ret)
                for (int i = 0; i < len; i++, offset += propsRhs)
                {
                    ret_ptr[offset] = function(lhs_val, rhs_ptr[offset]);
                }

                return(ret);
            }
            else if (rhs.IsScalar && rhs.Properties > property)
            {
                ret = lhs.Clone();
                len = ret.Count;
                var propsLhs = lhs.Properties;
                var rhsVal   = rhs[property];

                fixed(double *lhs_ptr = lhs, ret_ptr = ret)
                for (int i = 0; i < len; i++, offset += propsLhs)
                {
                    ret_ptr[offset] = function(lhs_ptr[offset], rhsVal);
                }

                return(ret);
            }
            else
            {
                ret = lhs.Clone();
                len = ret.Count;
                var propsLhs  = lhs.Properties;
                var propsRhs  = rhs.Properties;
                var rhsOffset = property;

                fixed(double *lhs_ptr = rhs, rhs_ptr = rhs, ret_ptr = ret)
                for (int i = 0; i < len; i++, offset += propsLhs, rhsOffset += propsRhs)
                {
                    ret_ptr[offset] = function(lhs_ptr[offset], rhs_ptr[rhsOffset]);
                }

                return(ret);
            }
        }
예제 #2
0
        /// <summary>
        ///     Performs a binary function on lhs and rhs.
        /// </summary>
        /// <param name="rhs">The rhs of the equation, 'this' is lhs.</param>
        /// <param name="function">The function to call for every value in this array.</param>
        /// <returns></returns>
        public virtual DoubleArray Function(DoubleArray rhs, BinaryFunctionHandler function)
        {
            var lhs = this;

            if (lhs.IsScalar && lhs.Properties == 1 && rhs.IsScalar && lhs.Properties == 1)
            {
                return(function(lhs.Value, rhs.Value));
            }

            DoubleArray ret;
            int         len;

            if (lhs.IsScalar && lhs.Properties == 1)
            {
                ret = rhs.Clone();
                len = ret.LinearLength;
                var lhs_val = lhs.Value;

                fixed(double *rhs_ptr = rhs, ret_ptr = ret)
                for (int i = 0; i < len; i++)
                {
                    ret_ptr[i] = function(lhs_val, rhs_ptr[i]);
                }

                return(ret);
            }
            else if (rhs.IsScalar && rhs.Properties == 1)
            {
                ret = lhs.Clone();
                len = ret.LinearLength;
                var rhsVal = rhs.Value;

                fixed(double *lhs_ptr = lhs, ret_ptr = ret)
                for (int i = 0; i < len; i++)
                {
                    ret_ptr[i] = function(lhs_ptr[i], rhsVal);
                }

                return(ret);
            }
            else
            {
                var propsLhs = lhs.LinearLength;
                var propsRhs = rhs.LinearLength;
                ret = propsLhs >= propsRhs?lhs.Clone() : rhs.Clone();

                len = ret.LinearLength;

                if (propsRhs % propsLhs != 0)
                    throw new ReshapeException($"Unable to broadcast lhs against rhs, ({propsLhs}, {propsRhs}).");
                fixed(double *lhs_ptr = rhs, rhs_ptr = rhs, ret_ptr = ret)
                if (propsRhs != propsLhs)
                {
                    for (int i = 0; i < len; i++)
                    {
                        ret_ptr[i] = function(lhs_ptr[i % propsLhs], rhs_ptr[i % propsRhs]);
                    }
                }

                else
                {
                    for (int i = 0; i < len; i++)
                    {
                        ret_ptr[i] = function(lhs_ptr[i], rhs_ptr[i]);
                    }
                }

                return(ret);
            }
        }