1 | ///
|
---|
2 | /// This file is part of ILNumerics Community Edition.
|
---|
3 | ///
|
---|
4 | /// ILNumerics Community Edition - high performance computing for applications.
|
---|
5 | /// Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
|
---|
6 | ///
|
---|
7 | /// ILNumerics Community Edition is free software: you can redistribute it and/or modify
|
---|
8 | /// it under the terms of the GNU General Public License version 3 as published by
|
---|
9 | /// the Free Software Foundation.
|
---|
10 | ///
|
---|
11 | /// ILNumerics Community Edition is distributed in the hope that it will be useful,
|
---|
12 | /// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | /// GNU General Public License for more details.
|
---|
15 | ///
|
---|
16 | /// You should have received a copy of the GNU General Public License
|
---|
17 | /// along with ILNumerics Community Edition. See the file License.txt in the root
|
---|
18 | /// of your distribution package. If not, see <http://www.gnu.org/licenses/>.
|
---|
19 | ///
|
---|
20 | /// In addition this software uses the following components and/or licenses:
|
---|
21 | ///
|
---|
22 | /// =================================================================================
|
---|
23 | /// The Open Toolkit Library License
|
---|
24 | ///
|
---|
25 | /// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
---|
26 | ///
|
---|
27 | /// Permission is hereby granted, free of charge, to any person obtaining a copy
|
---|
28 | /// of this software and associated documentation files (the "Software"), to deal
|
---|
29 | /// in the Software without restriction, including without limitation the rights to
|
---|
30 | /// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
---|
31 | /// the Software, and to permit persons to whom the Software is furnished to do
|
---|
32 | /// so, subject to the following conditions:
|
---|
33 | ///
|
---|
34 | /// The above copyright notice and this permission notice shall be included in all
|
---|
35 | /// copies or substantial portions of the Software.
|
---|
36 | ///
|
---|
37 | /// =================================================================================
|
---|
38 | ///
|
---|
39 |
|
---|
40 | using System;
|
---|
41 | using System.Collections.Generic;
|
---|
42 | using System.Text;
|
---|
43 | using System.IO;
|
---|
44 | using System.Linq.Expressions;
|
---|
45 | using System.Runtime.Serialization;
|
---|
46 | using ILNumerics;
|
---|
47 | using ILNumerics.Misc;
|
---|
48 | using ILNumerics.Data;
|
---|
49 | using ILNumerics.Exceptions;
|
---|
50 |
|
---|
51 | namespace ILNumerics.Storage {
|
---|
52 |
|
---|
53 | [System.Diagnostics.DebuggerTypeProxy(typeof(ILNumerics.Misc.ILArrayDebuggerProxy<>))]
|
---|
54 | [System.Diagnostics.DebuggerDisplay("{ShortInfo(),nq}")]
|
---|
55 | internal partial class ILDenseStorage<ElementType> : ILStorage<ElementType> {
|
---|
56 |
|
---|
57 | #region Constructors
|
---|
58 | /// <summary>
|
---|
59 | /// create new dense storage
|
---|
60 | /// </summary>
|
---|
61 | /// <param name="system_array">countable array</param>
|
---|
62 | /// <param name="dimensions">dimensions</param>
|
---|
63 | internal ILDenseStorage(ElementType[] system_array, ILSize dimensions)
|
---|
64 | : base(dimensions) {
|
---|
65 | if (system_array == null || dimensions == null)
|
---|
66 | throw new ILArgumentException("system array and dimensions parameter may not be null");
|
---|
67 | #if DEBUG
|
---|
68 | //DebuggerTraceHelper.Output.Append("\r\nILDenseStorage(ElementType[],dim) : ");
|
---|
69 | //var m = new System.Diagnostics.StackTrace().GetFrame(1).GetMethod();
|
---|
70 | //DebuggerTraceHelper.Output.Append(String.Format("Called from: {1} - {0}",m.ToString(),m.ReflectedType.Name));
|
---|
71 | #endif
|
---|
72 | m_data = new ILCountableArray<ElementType>(system_array,dimensions.NumberOfElements);
|
---|
73 | m_data.IncreaseReference();
|
---|
74 | }
|
---|
75 | internal ILDenseStorage(ILCountableArray<ElementType> countableArray, ILSize dimensions)
|
---|
76 | : base(dimensions) {
|
---|
77 | if (countableArray == null || dimensions == null)
|
---|
78 | throw new ILArgumentException("countableArray and dimensions parameter may not be null");
|
---|
79 | m_data = countableArray;
|
---|
80 | m_data.IncreaseReference();
|
---|
81 | }
|
---|
82 | internal ILDenseStorage(ILSize dimensions)
|
---|
83 | : base(dimensions) {
|
---|
84 | m_data = new ILCountableArray<ElementType>(dimensions.NumberOfElements,true);
|
---|
85 | m_data.IncreaseReference();
|
---|
86 | }
|
---|
87 | #endregion
|
---|
88 |
|
---|
89 | #region Destructor + Dispose
|
---|
90 |
|
---|
91 | /// <summary>
|
---|
92 | /// dispose this storage
|
---|
93 | /// </summary>
|
---|
94 | /// <remarks><para>Calling Dispose should be the last method called for an ILDenseStorage.</para></remarks>
|
---|
95 | internal override void Dispose(bool manual) {
|
---|
96 |
|
---|
97 | #if VERBOSE
|
---|
98 | System.Diagnostics.Debug.WriteLine("Disposing " + this.GetHashCode() + " called from: " + getCallee() );
|
---|
99 | #endif
|
---|
100 | if (manual) {
|
---|
101 | if (Settings.s_measurePerformanceAtRuntime && m_size.NumberOfElements >= ILMemoryPool.Pool.MinArrayLength<ElementType>()) {
|
---|
102 | ILMemoryPoolInternal<ElementType>.s_performanceCounters.PCDisposedHighIncrement();
|
---|
103 | }
|
---|
104 | }
|
---|
105 | if (!IsDisposed) {
|
---|
106 | if (m_data != null) {
|
---|
107 | #if DEBUG
|
---|
108 | //DebuggerTraceHelper.Output.Append(String.Format("\r\nDenseStorage Dispose HashCode: " + GetHashCode()));
|
---|
109 | #endif
|
---|
110 | m_data.DecreaseReference();
|
---|
111 | m_data = null;
|
---|
112 | }
|
---|
113 | }
|
---|
114 | }
|
---|
115 | /// <summary>
|
---|
116 | /// detach this storage: copy its countable array if necessary
|
---|
117 | /// </summary>
|
---|
118 | protected virtual void Detach() {
|
---|
119 | if (m_data.ReferenceCount <= 1)
|
---|
120 | return;
|
---|
121 | Data = m_data.CreateCopy();
|
---|
122 | }
|
---|
123 | #endregion
|
---|
124 |
|
---|
125 | #region Subarray interface
|
---|
126 | /// <summary>
|
---|
127 | /// Subarray from this array
|
---|
128 | /// </summary>
|
---|
129 | /// <param name="range"> arrays specifying the ranges to create subarray from</param>
|
---|
130 | /// <returns>subarray as specified</returns>
|
---|
131 | internal virtual ILDenseStorage<ElementType> Subarray (params ILBaseArray[] range) {
|
---|
132 | if (range.Length == 0) {
|
---|
133 | return CreateSelf(ILSize.Empty00);
|
---|
134 | } else if (range.Length == 1) {
|
---|
135 | #region sequential index access
|
---|
136 | if (object.Equals(range[0],null)) {
|
---|
137 | return CreateSelf(ILSize.Empty00);
|
---|
138 | } else if (range[0] is ILBaseArray<ILFullRange>) {
|
---|
139 | return CreateSubarrayStorageFull();
|
---|
140 | } else if (range[0] is ILBaseArray<ILRegularRange>) {
|
---|
141 | return CreateRangedSubarray(range[0] as ILBaseArray<ILRegularRange>);
|
---|
142 | } else if (range[0] is ILBaseArray<double>) {
|
---|
143 | return CreateSubarrayStorageSequential((ILBaseArray<double>)range[0]);
|
---|
144 | } else if (range[0] is ILDenseArray<string>) {
|
---|
145 | // special case? A[":;0:3;0:end;..."] -> multiple dimensions given as single string
|
---|
146 | string indStr = (string)(range[0] as ILDenseArray<string>).GetValue(0);
|
---|
147 | string[] dimParts = indStr.Split(';');
|
---|
148 | if (dimParts.Length == 0) {
|
---|
149 | // empty range given
|
---|
150 | return CreateSelf(ILSize.Empty00);
|
---|
151 | } else if (dimParts.Length > 1) {
|
---|
152 | range = new ILBaseArray [dimParts.Length];
|
---|
153 | for (int i = 0; i < dimParts.Length; i++) {
|
---|
154 | range[i] = dimParts[i];
|
---|
155 | } // continue below: multi-dim range specification
|
---|
156 | } else {
|
---|
157 | return Subarray(ILRange.ParseDimension(indStr, Size.NumberOfElements));
|
---|
158 | }
|
---|
159 | } else if (range[0].Storage is ILCellStorage) {
|
---|
160 | ILCellStorage indices = range[0].Storage as ILCellStorage;
|
---|
161 | if (indices.Size.NumberOfElements == 1) {
|
---|
162 | return Subarray(indices.GetScalar(0));
|
---|
163 | } else if (indices.Size.NumberOfElements == 0) {
|
---|
164 | return CreateSelf(ILSize.Empty00);
|
---|
165 | } else {
|
---|
166 | ILRightSideRange rngCell = new ILRightSideRange(Size, range);
|
---|
167 | return CreateSubarrayStorage(rngCell);
|
---|
168 | }
|
---|
169 | } else if (range[0] is ILRetLogical) {
|
---|
170 | return CreateSubarrayStorageSequential(ILNumerics.ILMath.find((ILRetLogical)range[0]));
|
---|
171 | } else if (range[0] is ILLogical) {
|
---|
172 | return CreateSubarrayStorageSequential(ILNumerics.ILMath.find((ILLogical)range[0]));
|
---|
173 | } else if (range[0] is ILBaseArray<float>) {
|
---|
174 | return CreateSubarrayStorageSequential((ILBaseArray<float>)range[0]);
|
---|
175 | } else if (range[0] is ILBaseArray<Int32>) {
|
---|
176 | return CreateSubarrayStorageSequential((ILBaseArray<Int32>)range[0]);
|
---|
177 | } else if (range[0] is ILBaseArray<Int64>) {
|
---|
178 | return CreateSubarrayStorageSequential((ILBaseArray<Int64>)range[0]);
|
---|
179 | } else if (range[0] is ILExpression) {
|
---|
180 | return CreateSubarrayStorageSequential((ILExpression)range[0]);
|
---|
181 | } else
|
---|
182 | throw new ILArgumentException ("specified type of indices array is not supported for sequential addressing!");
|
---|
183 | #endregion sequential index access
|
---|
184 | }
|
---|
185 | ILRightSideRange rng = new ILRightSideRange(m_size, range);
|
---|
186 | if (rng.Size.NumberOfElements == 0)
|
---|
187 | return CreateSelf(ILSize.Empty00);
|
---|
188 | return CreateSubarrayStorage(rng);
|
---|
189 | }
|
---|
190 |
|
---|
191 | /// <summary>
|
---|
192 | /// subarray from single dim, single range
|
---|
193 | /// </summary>
|
---|
194 | /// <returns>subarray (column vector)</returns>
|
---|
195 | private ILDenseStorage<ElementType> CreateRangedSubarray(ILBaseArray<ILRegularRange> range) {
|
---|
196 | System.Diagnostics.Debug.Assert(range.IsScalar);
|
---|
197 | ILRegularRange regRange = range.GetValue(0);
|
---|
198 | regRange.Evaluate(Size.NumberOfElements - 1);
|
---|
199 | bool dummy;
|
---|
200 | ElementType[] retArr = ILMemoryPool.Pool.New<ElementType>(regRange.Length,false, out dummy);
|
---|
201 | regRange.Extract(GetArrayForRead(),retArr, Size.NumberOfElements - 1);
|
---|
202 | return CreateSelf(retArr, new ILSize(regRange.Length, 1));
|
---|
203 | }
|
---|
204 |
|
---|
205 | /// <summary>
|
---|
206 | /// create new subarray storage, sequentially addressed elements
|
---|
207 | /// </summary>
|
---|
208 | /// <param name="indices">sequential indices, arbitrary size</param>
|
---|
209 | /// <returns>new storage, type of this storage, size and shape of indices</returns>
|
---|
210 | private ILDenseStorage<ElementType> CreateSubarrayStorageSequential(ILBaseArray<Expression> indices) {
|
---|
211 | if (indices.Storage is ILDenseStorage<Expression> ) {
|
---|
212 | Expression expr = (indices.Storage as ILDenseStorage<Expression>).GetArrayForRead()[0];
|
---|
213 | int idx = ILExpression.Evaluate(expr,Size.NumberOfElements-1);
|
---|
214 | if (idx < 0 || idx >= Size.NumberOfElements)
|
---|
215 | throw new ILArgumentException("sequential index out of range");
|
---|
216 | return CreateSelf(new ElementType[]{GetArrayForRead()[idx]}, indices.Size);
|
---|
217 | } else {
|
---|
218 | throw new ILArgumentException("Unsupported storage method for indices!");
|
---|
219 | }
|
---|
220 | }
|
---|
221 |
|
---|
222 | |
---|
223 |
|
---|
224 |
|
---|
225 | /// <summary>
|
---|
226 | /// create new subarray storage, sequentially addressed elements
|
---|
227 | /// </summary>
|
---|
228 | /// <param name="indices">sequential indices, arbitrary size</param>
|
---|
229 | /// <returns>new storage, type of this storage, size and shape of indices</returns>
|
---|
230 | private ILDenseStorage<ElementType> CreateSubarrayStorageSequential(ILBaseArray<double> indices) {
|
---|
231 | if (indices.Storage is ILDenseStorage< double > ) {
|
---|
232 | double [] indArr = (indices.Storage as ILDenseStorage< double >).GetArrayForRead();
|
---|
233 | int outLen = indices.Size.NumberOfElements;
|
---|
234 | int myLen = Size.NumberOfElements;
|
---|
235 | ElementType[] outdata = ILMemoryPool.Pool.New<ElementType> (outLen);
|
---|
236 | ElementType[] myData = GetArrayForRead();
|
---|
237 | for (int i = 0; i < outLen; i++) {
|
---|
238 | int targetIndex = (int)indArr[i];
|
---|
239 | if (targetIndex < 0 || targetIndex >= myLen)
|
---|
240 | throw new ILArgumentException(String.Format("sequential index at position {0} out of range: {1}", i, targetIndex));
|
---|
241 | outdata[i] = myData[targetIndex];
|
---|
242 | }
|
---|
243 | return CreateSelf(outdata, indices.Size);
|
---|
244 | } else {
|
---|
245 | throw new ILArgumentException("unsupported storage type for indices");
|
---|
246 | }
|
---|
247 | }
|
---|
248 | |
---|
249 | #region HYCALPER AUTO GENERATED CODE
|
---|
250 | |
---|
251 |
|
---|
252 |
|
---|
253 | /// <summary>
|
---|
254 | /// create new subarray storage, sequentially addressed elements
|
---|
255 | /// </summary>
|
---|
256 | /// <param name="indices">sequential indices, arbitrary size</param>
|
---|
257 | /// <returns>new storage, type of this storage, size and shape of indices</returns>
|
---|
258 | private ILDenseStorage<ElementType> CreateSubarrayStorageSequential(ILBaseArray<long> indices) {
|
---|
259 | if (indices.Storage is ILDenseStorage< long > ) {
|
---|
260 | long [] indArr = (indices.Storage as ILDenseStorage< long >).GetArrayForRead();
|
---|
261 | int outLen = indices.Size.NumberOfElements;
|
---|
262 | int myLen = Size.NumberOfElements;
|
---|
263 | ElementType[] outdata = ILMemoryPool.Pool.New<ElementType> (outLen);
|
---|
264 | ElementType[] myData = GetArrayForRead();
|
---|
265 | for (int i = 0; i < outLen; i++) {
|
---|
266 | int targetIndex = (int)indArr[i];
|
---|
267 | if (targetIndex < 0 || targetIndex >= myLen)
|
---|
268 | throw new ILArgumentException(String.Format("sequential index at position {0} out of range: {1}", i, targetIndex));
|
---|
269 | outdata[i] = myData[targetIndex];
|
---|
270 | }
|
---|
271 | return CreateSelf(outdata, indices.Size);
|
---|
272 | } else {
|
---|
273 | throw new ILArgumentException("unsupported storage type for indices");
|
---|
274 | }
|
---|
275 | }
|
---|
276 |
|
---|
277 |
|
---|
278 | /// <summary>
|
---|
279 | /// create new subarray storage, sequentially addressed elements
|
---|
280 | /// </summary>
|
---|
281 | /// <param name="indices">sequential indices, arbitrary size</param>
|
---|
282 | /// <returns>new storage, type of this storage, size and shape of indices</returns>
|
---|
283 | private ILDenseStorage<ElementType> CreateSubarrayStorageSequential(ILBaseArray<int> indices) {
|
---|
284 | if (indices.Storage is ILDenseStorage< int > ) {
|
---|
285 | int [] indArr = (indices.Storage as ILDenseStorage< int >).GetArrayForRead();
|
---|
286 | int outLen = indices.Size.NumberOfElements;
|
---|
287 | int myLen = Size.NumberOfElements;
|
---|
288 | ElementType[] outdata = ILMemoryPool.Pool.New<ElementType> (outLen);
|
---|
289 | ElementType[] myData = GetArrayForRead();
|
---|
290 | for (int i = 0; i < outLen; i++) {
|
---|
291 | int targetIndex = (int)indArr[i];
|
---|
292 | if (targetIndex < 0 || targetIndex >= myLen)
|
---|
293 | throw new ILArgumentException(String.Format("sequential index at position {0} out of range: {1}", i, targetIndex));
|
---|
294 | outdata[i] = myData[targetIndex];
|
---|
295 | }
|
---|
296 | return CreateSelf(outdata, indices.Size);
|
---|
297 | } else {
|
---|
298 | throw new ILArgumentException("unsupported storage type for indices");
|
---|
299 | }
|
---|
300 | }
|
---|
301 |
|
---|
302 |
|
---|
303 | /// <summary>
|
---|
304 | /// create new subarray storage, sequentially addressed elements
|
---|
305 | /// </summary>
|
---|
306 | /// <param name="indices">sequential indices, arbitrary size</param>
|
---|
307 | /// <returns>new storage, type of this storage, size and shape of indices</returns>
|
---|
308 | private ILDenseStorage<ElementType> CreateSubarrayStorageSequential(ILBaseArray<float> indices) {
|
---|
309 | if (indices.Storage is ILDenseStorage< float > ) {
|
---|
310 | float [] indArr = (indices.Storage as ILDenseStorage< float >).GetArrayForRead();
|
---|
311 | int outLen = indices.Size.NumberOfElements;
|
---|
312 | int myLen = Size.NumberOfElements;
|
---|
313 | ElementType[] outdata = ILMemoryPool.Pool.New<ElementType> (outLen);
|
---|
314 | ElementType[] myData = GetArrayForRead();
|
---|
315 | for (int i = 0; i < outLen; i++) {
|
---|
316 | int targetIndex = (int)indArr[i];
|
---|
317 | if (targetIndex < 0 || targetIndex >= myLen)
|
---|
318 | throw new ILArgumentException(String.Format("sequential index at position {0} out of range: {1}", i, targetIndex));
|
---|
319 | outdata[i] = myData[targetIndex];
|
---|
320 | }
|
---|
321 | return CreateSelf(outdata, indices.Size);
|
---|
322 | } else {
|
---|
323 | throw new ILArgumentException("unsupported storage type for indices");
|
---|
324 | }
|
---|
325 | }
|
---|
326 |
|
---|
327 | #endregion HYCALPER AUTO GENERATED CODE
|
---|
328 |
|
---|
329 |
|
---|
330 | /// <summary>
|
---|
331 | /// create column vector of all this array elements
|
---|
332 | /// </summary>
|
---|
333 | /// <returns>new storage, type of this storage, size and shape of indices</returns>
|
---|
334 | private ILDenseStorage<ElementType> CreateSubarrayStorageFull( ) {
|
---|
335 | return CreateSelf(Data,new ILSize(Size.NumberOfElements,1));
|
---|
336 | }
|
---|
337 |
|
---|
338 |
|
---|
339 | /// <summary>
|
---|
340 | /// create subarray from ILDenseStorage
|
---|
341 | /// </summary>
|
---|
342 | /// <param name="range"></param>
|
---|
343 | /// <returns></returns>
|
---|
344 | private ILDenseStorage<ElementType> CreateSubarrayStorage( ILRange range ) {
|
---|
345 | using (range) {
|
---|
346 | if (range == null || range.Size.NumberOfElements == 0)
|
---|
347 | return CreateSelf(ILSize.Empty00);
|
---|
348 | int rangeDimLen = range.RangeArray.Length, higherDimSum = 0;
|
---|
349 | int leadDimLenRange = range[0].Count, leadDimLen = m_size[0];
|
---|
350 | int curPosOut = 0, d, outElemCount = range.Size.NumberOfElements;
|
---|
351 | ElementType[] retArr = ILMemoryPool.Pool.New<ElementType>(outElemCount);
|
---|
352 | ElementType[] myArr = GetArrayForRead();
|
---|
353 | int[] idxArr = new int[rangeDimLen]; // used to store current position inside higher dims
|
---|
354 | ILIntList[] rng = range.RangeArray;
|
---|
355 | int[] seqDistances = m_size.GetSequentialIndexDistances(range.Size.NumberOfDimensions);
|
---|
356 | int[] inFullDim = new int[rangeDimLen];
|
---|
357 | // initialize higher dimension summand and inFullDim[] flag array
|
---|
358 | for (int i = 1; i < idxArr.Length; i++) {
|
---|
359 | if (rng[i][0] < 0) {
|
---|
360 | inFullDim[i] = rng[i][0];
|
---|
361 | } else {
|
---|
362 | inFullDim[i] = 0;
|
---|
363 | higherDimSum += seqDistances[i] * rng[i][0];
|
---|
364 | }
|
---|
365 | }
|
---|
366 | //for (int lIdx = 0; lIdx < leadDimLenRange; lIdx ++) {
|
---|
367 | // retArr[curPosOut++] = myArr[higherDimSum + rleadDim[lIdx]];
|
---|
368 | //}
|
---|
369 |
|
---|
370 | while (true) {
|
---|
371 | // copy along leading dimension
|
---|
372 | int rng0Count = rng[0].Count; int[] rng0 = rng[0].GetArray();
|
---|
373 | for (int i = 0; i < rng0Count; i++) {
|
---|
374 | int rng0i = rng0[i];
|
---|
375 | if (rng0i < 0) {
|
---|
376 | if (-rng0i > Settings.s_minElementLength4SystemArrayCopy) {
|
---|
377 | //int endOut = curPosOut -(rng0i - 1), startIn = higherDimSum;
|
---|
378 | //for (; curPosOut < retArr.Length; curPosOut++) {
|
---|
379 | // if (curPosOut >= endOut) break;
|
---|
380 | // retArr[curPosOut] = myArr[startIn++];
|
---|
381 | //}
|
---|
382 | System.Array.Copy(myArr, higherDimSum, retArr, curPosOut, -(rng0i - 1));
|
---|
383 | curPosOut -= (rng0i - 1);
|
---|
384 | } else {
|
---|
385 | //for (int c = -rng0[i]; c-- >= 0; ) {
|
---|
386 | // retArr[curPosOut++] = myArr[higherDimSum++];
|
---|
387 | //}
|
---|
388 | //higherDimSum += (rng0[i] - 1); // negative value in rng!
|
---|
389 | int endOut = curPosOut - (rng0i - 1), startIn = higherDimSum;
|
---|
390 | for (; curPosOut < outElemCount; curPosOut++) {
|
---|
391 | if (curPosOut >= endOut) break;
|
---|
392 | retArr[curPosOut] = myArr[startIn++];
|
---|
393 | }
|
---|
394 | }
|
---|
395 | } else {
|
---|
396 | retArr[curPosOut++] = myArr[higherDimSum + rng0i];
|
---|
397 | }
|
---|
398 | }
|
---|
399 |
|
---|
400 | // increase higher dims
|
---|
401 | d = 1;
|
---|
402 | while (d < rangeDimLen) {
|
---|
403 | if (inFullDim[d] < 0) {
|
---|
404 | higherDimSum += seqDistances[d];
|
---|
405 | inFullDim[d]++;
|
---|
406 | break;
|
---|
407 | }
|
---|
408 |
|
---|
409 | if (rng[d][idxArr[d]] >= 0) {
|
---|
410 | higherDimSum -= (rng[d][idxArr[d]] * seqDistances[d]);
|
---|
411 | } else {
|
---|
412 | higherDimSum += (rng[d][idxArr[d]] * seqDistances[d]);
|
---|
413 | }
|
---|
414 | idxArr[d]++;
|
---|
415 | if (idxArr[d] == rng[d].Count) {
|
---|
416 | idxArr[d] = 0;
|
---|
417 | if (rng[d][0] < 0) {
|
---|
418 | inFullDim[d] = rng[d][0];
|
---|
419 | } else {
|
---|
420 | higherDimSum += seqDistances[d] * rng[d][0];
|
---|
421 | }
|
---|
422 | d++;
|
---|
423 | } else if (rng[d][idxArr[d]] < 0) {
|
---|
424 | inFullDim[d] = rng[d][idxArr[d]];
|
---|
425 | break;
|
---|
426 | } else {
|
---|
427 | higherDimSum += seqDistances[d] * rng[d][idxArr[d]];
|
---|
428 | break;
|
---|
429 | }
|
---|
430 |
|
---|
431 | }
|
---|
432 | if (d >= idxArr.Length)
|
---|
433 | break;
|
---|
434 | }
|
---|
435 | return CreateSelf(retArr, range.Size);
|
---|
436 | }
|
---|
437 | }
|
---|
438 | /// <summary>
|
---|
439 | /// create new storage, shift dimensions
|
---|
440 | /// </summary>
|
---|
441 | /// <param name="shift">number of dimensions to shift</param>
|
---|
442 | /// <returns>shifted storage </returns>
|
---|
443 | private ILDenseStorage<ElementType> CreateShiftedStorage(int shift) {
|
---|
444 | ILSize retDimensions = m_size.GetShifted(shift);
|
---|
445 | int numElem = m_size.NumberOfElements - 1;
|
---|
446 | ElementType[] retArr = ILMemoryPool.Pool.New<ElementType>(retDimensions.NumberOfElements);
|
---|
447 | ElementType[] myArr = GetArrayForRead();
|
---|
448 | int inc = m_size.SequentialIndexDistance(Math.Min(shift, m_size.NumberOfDimensions));
|
---|
449 | int pos = 0;
|
---|
450 | int i = 0;
|
---|
451 | while (i < numElem) {
|
---|
452 | retArr[i++] = myArr[pos];
|
---|
453 | pos = (pos + inc) % numElem;
|
---|
454 | }
|
---|
455 | if (numElem >= 0) // except empty
|
---|
456 | retArr[i] = myArr[numElem];
|
---|
457 | return CreateSelf(retArr,retDimensions);
|
---|
458 | }
|
---|
459 |
|
---|
460 | protected virtual ILDenseStorage<ElementType> CreateSelf(ElementType[] data, ILSize size) {
|
---|
461 | return new ILDenseStorage<ElementType>(data, size);
|
---|
462 | }
|
---|
463 | protected virtual ILDenseStorage<ElementType> CreateSelf(ILSize size) {
|
---|
464 | return new ILDenseStorage<ElementType>(size);
|
---|
465 | }
|
---|
466 | protected virtual ILDenseStorage<ElementType> CreateSelf(ILCountableArray<ElementType> Data, ILSize iLDimension) {
|
---|
467 | return new ILDenseStorage<ElementType>(Data, iLDimension);
|
---|
468 | }
|
---|
469 |
|
---|
470 | #endregion
|
---|
471 |
|
---|
472 | }
|
---|
473 | }
|
---|