예제 #1
0
        public LArray <T> cummul(int dim)
        {
            if (dim < 0 || dim >= _rank)
            {
                throw new ArgumentException("Cannot sum over due to invalid dimension");
            }
            var result      = new LArray <T>(_sizes);
            var index_start = "";
            var index_end   = "";

            for (var i = 0; i < dim; i++)
            {
                index_start += ":,";
            }
            for (var i = dim + 1; i < _rank; i++)
            {
                index_end += ",:";
            }
            string index_1;
            string index_2;

            index_1         = index_start + "0" + index_end;
            result[index_1] = this[index_1];
            for (var i = 1; i < _sizes[dim]; i++)
            {
                index_1         = index_start + i.ToString() + index_end;
                index_2         = index_start + (i - 1).ToString() + index_end;
                result[index_1] = this[index_1] * result[index_2];
            }
            return(result);
        }
예제 #2
0
        // operations
        public LArray <T> sum(int dim)
        {
            if (dim < 0 || dim >= _rank)
            {
                throw new ArgumentException("Cannot sum over due to invalid dimension");
            }
            var dims = new int[_rank];

            _sizes.CopyTo(dims, 0);
            dims[dim] = 1;
            var result      = new LArray <T>(dims);
            var index_start = "";
            var index_end   = "";

            for (var i = 0; i < dim; i++)
            {
                index_start += ":,";
            }
            for (var i = dim + 1; i < _rank; i++)
            {
                index_end += ",:";
            }
            string index;

            for (var i = 0; i < _sizes[dim]; i++)
            {
                index   = index_start + i.ToString() + index_end;
                result += this[index];
            }
            return(result);
        }
예제 #3
0
 public LArray(LArray <T> other)
 {
     _rank  = other._rank;
     _sizes = new int[other._sizes.Length];
     other._sizes.CopyTo(_sizes, 0);
     _data = new T[other._data.Length];
     other._data.CopyTo(_data, 0);
     _scalar = other._scalar;
 }
예제 #4
0
        public static LArray <T> operator /(T b, LArray <T> a)
        {
            var c = new LArray <T>(a._sizes);

            for (var i = 0; i < c._data.Length; i++)
            {
                c[i] = (dynamic)b / a[i];
            }
            return(c);
        }
예제 #5
0
        public static LArray <T> operator *(LArray <T> a, T b)
        {
            var c = new LArray <T>(a._sizes);

            for (var i = 0; i < c._data.Length; i++)
            {
                c[i] = (dynamic)a[i] * b;
            }
            return(c);
        }
예제 #6
0
        public static LArray <T> operator /(LArray <T> a, LArray <T> b)
        {
            if (!a._sizes.SequenceEqual(b._sizes))
            {
                throw new ArgumentException("Cannot divide 2 arrays with different shapes");
            }
            var c = new LArray <T>(a._sizes);

            for (var i = 0; i < c._data.Length; i++)
            {
                c[i] = (dynamic)a[i] / b[i];
            }
            return(c);
        }
예제 #7
0
        public LArray <T> reshape(params int[] dims)
        {
            var len = 1;

            for (var i = 0; i < dims.Length; i++)
            {
                len *= dims[i];
            }
            if (len != _data.Length)
            {
                throw new ArgumentException("Cannot reshape array due to mismatching length");
            }
            var new_array = new LArray <T>(dims);

            _data.CopyTo(new_array._data, 0);
            return(new_array);
        }
예제 #8
0
        // reverse dimension order
        public LArray <T> reverse(int dim)
        {
            if (dim < 0 || dim >= _rank)
            {
                throw new ArgumentException("Cannot reverse array due to invalid dimension.");
            }
            var result = new LArray <T>(_sizes);
            var idxs   = new int[_rank];

            //var result_idxs = new int[_rank];
            if (dim < _rank - 1)
            {
                idxs[dim] = _sizes[dim] - 1;
            }
            int end_0;

            if (dim == 0)
            {
                end_0 = -1;
            }
            else
            {
                end_0 = _sizes[0];
            }
            var result_idx = 0;
            var len        = _sizes[_rank - 1];

            while (true)
            {
                if (idxs[0] == end_0)
                {
                    break;
                }
                int idx;
                var buf = new T[len];
                idx = _get_index(idxs);
                if (dim == _rank - 1)
                {
                    Array.Copy(_data, idx, buf, 0, len);
                    Array.Copy(buf.Reverse().ToArray(), 0, result._data, result_idx, len);
                }
                else
                {
                    Array.Copy(_data, idx, result._data, result_idx, len);
                }
                // update index
                result_idx += len;
                if (dim == _rank - 2)
                {
                    idxs[_rank - 2]--;
                }
                else
                {
                    idxs[_rank - 2]++;
                }
                for (var i = _rank - 2; i > 0; i--)
                {
                    if (dim == i)
                    {
                        if (idxs[i] < 0)
                        {
                            idxs[i] = _sizes[i] - 1;
                            idxs[i - 1]++;
                        }
                    }
                    else
                    {
                        if (idxs[i] >= _sizes[i])
                        {
                            idxs[i] = 0;
                            if (i - 1 == dim)
                            {
                                idxs[i - 1]--;
                            }
                            else
                            {
                                idxs[i - 1]++;
                            }
                        }
                    }
                }
            }
            return(result);
        }
예제 #9
0
        public LArray <T> this[string index]
        {
            get
            {
                var tokens = index.Split(',');
                // slice support
                if (tokens.Length > _rank)
                {
                    throw new ArgumentException("Index out of dimension.");
                }
                if (tokens.Length != _rank && tokens.Length != 1)
                {
                    throw new ArgumentException("Index dimensions mismatch with data dimensions");
                }
                if (tokens.Length == 1)
                {
                    var token = tokens[0];
                    // slice expression
                    if (token.Contains(':'))
                    {
                        var tmp   = _parse_slice_expression(token);
                        var start = tmp.Item1;
                        var end   = tmp.Item2;
                        if (end == start)
                        {
                            return(new LArray <T>());
                        }
                        var slice = new LArray <T>(Math.Abs(end - start));
                        if (end > start)
                        {
                            Array.Copy(_data, start, slice._data, 0, end - start);
                        }
                        else
                        {
                            Array.Copy(_data, end, slice._data, 0, start - end);
                            slice._data = slice._data.Reverse().ToArray();
                        }
                        return(slice);
                    }
                    else// single index
                    {
                        var idx = _trim_index(int.Parse(token));
                        return(new LArray <T>(_data[idx]));
                    }
                }
                else// multi-dimensional array situation
                {
                    int rank   = tokens.Length;
                    var starts = new List <int>(rank);
                    var ends   = new List <int>(rank);
                    var dims   = new List <int>(rank);

                    for (var i = 0; i < rank; i++)
                    {
                        var token = tokens[i];
                        // slice expression
                        if (token.Contains(':'))
                        {
                            var tmp = _parse_slice_expression(token, i);
                            starts.Add(tmp.Item1);
                            ends.Add(tmp.Item2);
                            dims.Add(Math.Abs(ends[i] - starts[i]));
                        }
                        else// single index
                        {
                            var idx = _trim_index(int.Parse(token), i);
                            if (idx == _sizes[i])
                            {
                                throw new IndexOutOfRangeException();
                            }
                            starts.Add(idx);
                            ends.Add(idx + 1);
                            dims.Add(1);
                        }
                    }

                    rank = dims.Count;
                    var subarray = new LArray <T>(dims.ToArray());
                    // idxs[k] stores the current working index of k-th dimension of _data
                    var idxs          = new int[rank];
                    var subarray_idxs = new int[rank];
                    // initialize idxs
                    starts.CopyTo(0, idxs, 0, rank);
                    int len = subarray._sizes[rank - 1];
                    var buf = new T[len];
                    while (true)
                    {
                        // check if we are done copying slices
                        if (idxs[0] == ends[0])
                        {
                            break;
                        }
                        int start = _get_index(idxs);

                        int subarray_start = subarray._get_index(subarray_idxs);
                        // copy slice
                        if (starts[rank - 1] < ends[rank - 1])
                        {
                            Array.Copy(_data, start, subarray._data, subarray_start, len);
                        }
                        else
                        {
                            // reverse order
                            Array.Copy(_data, start - len + 1, buf, 0, len);
                            Array.Copy(buf.Reverse().ToArray(), 0, subarray._data, subarray_start, len);
                        }
                        // increment (or decrement)
                        if (starts[rank - 2] < ends[rank - 2])
                        {
                            idxs[rank - 2]++;
                        }
                        else
                        {
                            idxs[rank - 2]--;
                        }
                        subarray_idxs[rank - 2]++;

                        // make sure all indices are updated
                        for (var i = rank - 2; i > 0; i--)
                        {
                            // if we are done looping i-th dimension
                            if (idxs[i] == ends[i])
                            {
                                idxs[i] = starts[i];
                                if (starts[i - 1] < ends[i - 1])
                                {
                                    idxs[i - 1]++;
                                }
                                else
                                {
                                    idxs[i - 1]--;
                                }
                            }
                            if (subarray_idxs[i] == subarray._sizes[i])
                            {
                                subarray_idxs[i] = 0;
                                subarray_idxs[i - 1]++;
                            }
                        }
                    }
                    return(subarray);
                }
            }
            set
            {
                var tokens = index.Split(',');
                // slice support
                if (tokens.Length > _rank)
                {
                    throw new ArgumentException("Index out of dimension.");
                }
                if (tokens.Length != _rank && tokens.Length != 1)
                {
                    throw new ArgumentException("Index dimensions mismatch with data dimensions");
                }
                // flat assignment
                if (tokens.Length == 1)
                {
                    var token = tokens[0];
                    // slice expression
                    if (token.Contains(':'))
                    {
                        var tmp   = _parse_slice_expression(token);
                        var start = tmp.Item1;
                        var end   = tmp.Item2;
                        if (value._data.Length != Math.Abs(end - start))
                        {
                            throw new ArgumentException("Assigned array length mismatches with slice length.");
                        }
                        if (start == end)
                        {
                            throw new ArgumentException("Empty sclice, useless assignment.");
                        }
                        if (start < end)
                        {
                            Array.Copy(value._data, 0, _data, start, end - start);
                        }
                        else
                        {
                            Array.Copy(value._data.Reverse().ToArray(), 0, _data, end, start - end);
                        }
                    }
                    else// single index
                    {
                        // verify value is indeed scalar
                        if (value._rank != 0)
                        {
                            throw new ArgumentException("Value is not scalar but index indicates scalar assignment.");
                        }
                        var idx = _trim_index(int.Parse(token));
                        _data[idx] = value._scalar;
                    }
                }
                else// sub-array support
                {
                    int rank   = tokens.Length;
                    var starts = new List <int>(rank);
                    var ends   = new List <int>(rank);
                    var dims   = new List <int>(rank);

                    for (var i = 0; i < rank; i++)
                    {
                        var token = tokens[i];
                        // slice expression
                        if (token.Contains(':'))
                        {
                            var tmp = _parse_slice_expression(token, i);
                            starts.Add(tmp.Item1);
                            ends.Add(tmp.Item2);
                            dims.Add(Math.Abs(ends[i] - starts[i]));
                        }
                        else// single index
                        {
                            var idx = _trim_index(int.Parse(token), i);
                            if (idx == _sizes[i])
                            {
                                throw new IndexOutOfRangeException();
                            }
                            starts.Add(idx);
                            ends.Add(idx + 1);
                            dims.Add(1);
                        }
                    }
                    // Verify that assigned array has the same shape with sub-array
                    for (var i = 0; i < rank; i++)
                    {
                        if (dims[i] != value._sizes[i])
                        {
                            throw new ArgumentException("Assigned array mismatches sub-array in shape.");
                        }
                    }
                    // idxs[k] stores the current working index of k-th dimension of _data
                    var idxs          = new int[rank];
                    var subarray_idxs = new int[rank];
                    // initialize idxs
                    starts.CopyTo(0, idxs, 0, rank);
                    int len = value._sizes[rank - 1];
                    var buf = new T[len];
                    while (true)
                    {
                        // check if we are done copying slices
                        if (idxs[0] == ends[0])
                        {
                            break;
                        }

                        int start          = _get_index(idxs);
                        int subarray_start = value._get_index(subarray_idxs);
                        // copy slice
                        if (starts[rank - 1] < ends[rank - 1])
                        {
                            Array.Copy(value._data, subarray_start, _data, start, len);
                        }
                        else
                        {
                            // reverse order
                            Array.Copy(value._data, subarray_start, buf, 0, len);
                            Array.Copy(buf.Reverse().ToArray(), 0, _data, start - len + 1, len);
                        }
                        // increment (or decrement)
                        if (starts[rank - 2] < ends[rank - 2])
                        {
                            idxs[rank - 2]++;
                        }
                        else
                        {
                            idxs[rank - 2]--;
                        }
                        subarray_idxs[rank - 2]++;

                        // make sure all indices are updated
                        for (var i = rank - 2; i > 0; i--)
                        {
                            // if we are done looping i-th dimension
                            if (idxs[i] == ends[i])
                            {
                                idxs[i] = starts[i];
                                if (starts[i - 1] < ends[i - 1])
                                {
                                    idxs[i - 1]++;
                                }
                                else
                                {
                                    idxs[i - 1]--;
                                }
                            }
                            if (subarray_idxs[i] == value._sizes[i])
                            {
                                subarray_idxs[i] = 0;
                                subarray_idxs[i - 1]++;
                            }
                        }
                    }
                }
            }
        }