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.Runtime.Serialization;
|
---|
45 | using System.Runtime.CompilerServices;
|
---|
46 | using ILNumerics.Misc;
|
---|
47 | using ILNumerics.Data;
|
---|
48 | using ILNumerics.Exceptions;
|
---|
49 | using System.Linq.Expressions;
|
---|
50 |
|
---|
51 | namespace ILNumerics.Storage {
|
---|
52 |
|
---|
53 | /// <summary>
|
---|
54 | /// The class realizes an internal storage wrapper for cell arrays. It takes care of value semantics for reference types.
|
---|
55 | /// </summary>
|
---|
56 | [Serializable]
|
---|
57 | internal class ILCellStorage : ILDenseStorage<ILStorage> {
|
---|
58 |
|
---|
59 | #region attributes
|
---|
60 | bool m_fromImplicitCast = false;
|
---|
61 | #endregion
|
---|
62 |
|
---|
63 | #region properties
|
---|
64 | internal bool FromImplicitCast {
|
---|
65 | get { return m_fromImplicitCast; }
|
---|
66 | set { m_fromImplicitCast = value; }
|
---|
67 | }
|
---|
68 | #endregion
|
---|
69 |
|
---|
70 | #region Constructors
|
---|
71 | /// <summary>
|
---|
72 | /// create new cell storage
|
---|
73 | /// </summary>
|
---|
74 | /// <param name="system_array">countable array</param>
|
---|
75 | /// <param name="dimensions">dimensions</param>
|
---|
76 | internal ILCellStorage(ILStorage[] system_array, ILSize dimensions)
|
---|
77 | : base(system_array, dimensions) {
|
---|
78 | DeepReferenceElements();
|
---|
79 | }
|
---|
80 | internal ILCellStorage(ILBaseArray[] system_array, ILSize dimensions)
|
---|
81 | : base(baseArray2Storages(system_array, dimensions.NumberOfElements), dimensions) {
|
---|
82 | DeepReferenceElements();
|
---|
83 | }
|
---|
84 | internal ILCellStorage(ILCountableArray<ILStorage> countableArray, ILSize dimensions)
|
---|
85 | : base(countableArray, dimensions) {
|
---|
86 | DeepReferenceElements();
|
---|
87 | }
|
---|
88 | internal ILCellStorage(ILSize dimensions)
|
---|
89 | : base(dimensions) { }
|
---|
90 | #endregion
|
---|
91 |
|
---|
92 | #region public interface
|
---|
93 | /// <summary>
|
---|
94 | /// replace array at specified location
|
---|
95 | /// </summary>
|
---|
96 | /// <param name="value">new scalar value for element</param>
|
---|
97 | /// <param name="indices">indices of element to be altered, supports 'deep indexing'</param>
|
---|
98 | internal override void SetValueTyped(ILStorage value, params int[] indices) {
|
---|
99 | //if (Object.ReferenceEquals(value, null) || value.Size.NumberOfElements == 0)
|
---|
100 | // throw new ILArgumentException("cell removal is not supported for single integer indexing. value specified must not be null");
|
---|
101 | int mydimlen = Size.NumberOfDimensions;
|
---|
102 | if (indices.Length <= mydimlen) {
|
---|
103 | try {
|
---|
104 | // address this ILCell
|
---|
105 | ILStorage curVal = base.GetValueTyped(indices);
|
---|
106 | if (curVal != null)
|
---|
107 | curVal.Dispose();
|
---|
108 |
|
---|
109 | } catch (IndexOutOfRangeException) {
|
---|
110 | } catch (ILArgumentException) {
|
---|
111 | // address outside range -> no need to dispose
|
---|
112 | } finally {
|
---|
113 | base.SetValueTyped(value == null ? null: value.Clone(), indices);
|
---|
114 | }
|
---|
115 | } else {
|
---|
116 | if (value != null && value.Size.NumberOfElements > 1)
|
---|
117 | throw new ILArgumentException("value given must be scalar or null");
|
---|
118 | // address element of an element of this ILCell
|
---|
119 | int[] innerIndices = new int[indices.Length - mydimlen];
|
---|
120 | int i = 1, elIndex = indices[0];
|
---|
121 | for (; i < mydimlen; i++)
|
---|
122 | elIndex += (Size.SequentialIndexDistance(i) * indices[i]);
|
---|
123 | if (elIndex > Size.NumberOfElements)
|
---|
124 | throw new ILArgumentException("index out of range");
|
---|
125 | for (int n = 0; i < indices.Length; i++)
|
---|
126 | innerIndices[n++] = indices[i];
|
---|
127 | ILStorage innerElement = GetArrayForRead()[elIndex];
|
---|
128 | if (object.Equals(innerElement, null))
|
---|
129 | throw new ILArgumentException("No array found in cell at indices specified. Invalid deep indices given.");
|
---|
130 | if (innerElement is ILCellStorage) {
|
---|
131 | innerElement.SetValue(value, innerIndices);
|
---|
132 | } else {
|
---|
133 | if (value != null && value.Size.NumberOfElements != 1)
|
---|
134 | throw new ILArgumentException("deep cell indexing requires the new value to be a scalar. Given: "
|
---|
135 | + value.Size.ToString());
|
---|
136 | innerElement.SetValue(value != null ? value.GetValue(0) : null, innerIndices);
|
---|
137 | }
|
---|
138 | //if (innerElement is ILDenseStorage<ILStorage>) { // send the _reference_ of value to inner storage (clone will be done at the end)
|
---|
139 | // (innerElement as ILDenseStorage<ILStorage>).SetValueTyped(value, innerIndices);
|
---|
140 | //} else if (value is ILStorage<double> && innerElement is ILStorage<double>) {
|
---|
141 | // (innerElement as ILStorage<double>).SetValueTyped((value as ILStorage<double>).GetValueTyped(0), innerIndices);
|
---|
142 | //} else if (value is ILStorage<float> && innerElement is ILStorage<float>) {
|
---|
143 | // (innerElement as ILStorage<float>).SetValueTyped((value as ILStorage<float>).GetValueTyped(0), innerIndices);
|
---|
144 | //} else if (value is ILStorage<complex> && innerElement is ILStorage<complex>) {
|
---|
145 | // (innerElement as ILStorage<complex>).SetValueTyped((value as ILStorage<complex>).GetValueTyped(0), innerIndices);
|
---|
146 | //} else if (value is ILStorage<fcomplex> && innerElement is ILStorage<fcomplex>) {
|
---|
147 | // (innerElement as ILStorage<fcomplex>).SetValueTyped((value as ILStorage<fcomplex>).GetValueTyped(0), innerIndices);
|
---|
148 | //} else if (value is ILStorage<Int32> && innerElement is ILStorage<Int32>) {
|
---|
149 | // (innerElement as ILStorage<Int32>).SetValueTyped((value as ILStorage<Int32>).GetValueTyped(0), innerIndices);
|
---|
150 | //} else if (value is ILStorage<Int64> && innerElement is ILStorage<Int64>) {
|
---|
151 | // (innerElement as ILStorage<Int64>).SetValueTyped((value as ILStorage<Int64>).GetValueTyped(0), innerIndices);
|
---|
152 | //} else if (value is ILStorage<byte> && innerElement is ILStorage<byte>) {
|
---|
153 | // (innerElement as ILStorage<byte>).SetValueTyped((value as ILStorage<byte>).GetValueTyped(0), innerIndices);
|
---|
154 | //} else if (value is ILStorage<string> && innerElement is ILStorage<string>) {
|
---|
155 | // (innerElement as ILStorage<string>).SetValueTyped((value as ILStorage<string>).GetValueTyped(0), innerIndices);
|
---|
156 | //} else {
|
---|
157 | // throw new ILArgumentTypeException("right side argument type is not valid in this context. the value must have the same type as the inner array addressed");
|
---|
158 | //}
|
---|
159 | }
|
---|
160 | }
|
---|
161 | /// <summary>
|
---|
162 | /// get element from this cell storage
|
---|
163 | /// </summary>
|
---|
164 | /// <param name="indices">indices of element</param>
|
---|
165 | /// <returns>element </returns>
|
---|
166 | internal override ILStorage GetValueTyped(params int[] indices) {
|
---|
167 | int mydimlen = Size.NumberOfDimensions;
|
---|
168 | if (indices.Length <= mydimlen) {
|
---|
169 | // address this ILCell
|
---|
170 | ILStorage element = base.GetValueTyped(indices);
|
---|
171 | return (element != null) ? element.Clone() : null;
|
---|
172 | } else {
|
---|
173 | // address element of an element of this ILCell (deep addressing)
|
---|
174 | int[] innerIndices = new int[indices.Length - mydimlen];
|
---|
175 | int i = 1, elIndex = indices[0];
|
---|
176 | for (; i < mydimlen; i++)
|
---|
177 | elIndex += (Size.SequentialIndexDistance(i) * indices[i]);
|
---|
178 | for (int n = 0; i < indices.Length; i++)
|
---|
179 | innerIndices[n++] = indices[i];
|
---|
180 | ILStorage innerElement = base.GetValueTyped(elIndex);
|
---|
181 | if (innerElement == null)
|
---|
182 | throw new ILArgumentException("Deep indices out of range. The specified element does not exist.");
|
---|
183 | return innerElement.GetValueAsStorage(innerIndices);
|
---|
184 | }
|
---|
185 | }
|
---|
186 | internal override ILStorage GetValueAsStorage(params int[] innerIndices) {
|
---|
187 | return GetValueTyped(innerIndices);
|
---|
188 | }
|
---|
189 | /// <summary>
|
---|
190 | /// test if an element of the cell is an array of the given element type
|
---|
191 | /// </summary>
|
---|
192 | /// <typeparam name="T">the array element type to check the cell element against</typeparam>
|
---|
193 | /// <param name="position">position of the cell element to be tested</param>
|
---|
194 | /// <returns>true if the element found at the given position is an array of the element type <typeparamref name="T"/>, false otherwise</returns>
|
---|
195 | /// <remarks>The method is helpful in order to investigate the contents of a cell array. If you are not sure about the
|
---|
196 | /// types of elements in the cell, this function can be used to make sure, elements are of the expected type before retrieving them as such.
|
---|
197 | /// <para>In most situations, elements of a cell are stored arrays of a distinct element type. That element type is given to IsTypeOf as
|
---|
198 | /// typeparameter <typeparamref name="T"/>. That means, in order to find out, if the first cell element stores an array of int (<c>ILArray<int></c>),
|
---|
199 | /// one may use <c>cell.IsTypeOf<int>(0)</c></para>
|
---|
200 | /// <para>In order to test, if a cell element is of cell type, one can provide the type <c>ILCell</c> as type parameter:
|
---|
201 | /// <c>cell.IsTypeOf<ILCell>(0)</c>. Note the different semantic when checking for cell elements of type cell. Here we do not test for the
|
---|
202 | /// element type but for the array type itself, ie. <c>ILCell</c>. The reason of this is: the type of elements of <c>ILCell</c> is
|
---|
203 | /// an implementation detail and therefore hidden to the user.</para>
|
---|
204 | /// </remarks>
|
---|
205 | /// <example>
|
---|
206 | /// <para>In the following example a ILCell of size 3x2 is created. It stores several array types, among which other cells are stored as elements of the outer cell.</para>
|
---|
207 | /// <code>ILCell cell = ILMath.cell(new ILSize(3, 2)
|
---|
208 | /// , "first element"
|
---|
209 | /// , 2.0
|
---|
210 | /// , ILMath.cell(Math.PI, 100f)
|
---|
211 | /// , ILMath.create<short>(1, 2, 3, 4, 5, 6)
|
---|
212 | /// , new double[] {-1.4, -1.5, -1.6});
|
---|
213 | /// </code>
|
---|
214 | /// The cell is now:
|
---|
215 | /// <code>ILCell [3,2]
|
---|
216 | /// <String> first element <Int16> [2,3,4,5,6]
|
---|
217 | /// <Double> 2 ILCell [1,3]
|
---|
218 | /// ILCell [2,1] (null)
|
---|
219 | /// </code>
|
---|
220 | /// We test the element type of every element in the cell:
|
---|
221 | /// <code>
|
---|
222 | /// Console.Out.WriteLine("cell[0,0] is of type 'string': {0}", cell.IsTypeOf<string>(0));
|
---|
223 | /// Console.Out.WriteLine("cell[0,0] is of type 'double': {0}", cell.IsTypeOf<double>(0));
|
---|
224 | ///
|
---|
225 | /// Console.Out.WriteLine("cell[1,0] is of type 'double': {0}", cell.IsTypeOf<double>(1));
|
---|
226 | /// Console.Out.WriteLine("cell[2,0] is of type 'ILCell': {0}", cell.IsTypeOf<ILCell>(2));
|
---|
227 | ///
|
---|
228 | /// Console.Out.WriteLine("cell[0,1] is of type 'short': {0}", cell.IsTypeOf<short>(0, 1));
|
---|
229 | /// Console.Out.WriteLine("cell[1,1] is of type 'ILCell': {0}", cell.IsTypeOf<ILCell>(1, 1));
|
---|
230 | /// Console.Out.WriteLine("cell[2,1] is of type 'double': {0}", cell.IsTypeOf<double>(2, 1));
|
---|
231 | /// </code>
|
---|
232 | /// This gives the following output:
|
---|
233 | /// <code>
|
---|
234 | /// cell[0,0] is element type 'string': True
|
---|
235 | /// cell[0,0] is element type 'double': False
|
---|
236 | /// cell[1,0] is element type 'double': True
|
---|
237 | /// cell[2,0] is element type 'ILCell': True
|
---|
238 | /// cell[0,1] is element type 'short': True
|
---|
239 | /// cell[1,1] is element type 'ILCell': True
|
---|
240 | /// cell[2,1] is element type 'double': False // element is null, IsTypeOf<> never gives true
|
---|
241 | /// </code></example>
|
---|
242 | public bool IsTypeOf<T>(params ILBaseArray[] position) {
|
---|
243 | ILCellStorage cellStorage = (ILCellStorage)Subarray(position);
|
---|
244 | try {
|
---|
245 | if (cellStorage.Size.NumberOfElements == 1) {
|
---|
246 | ILStorage innerStorage = cellStorage.GetValueTyped(0);
|
---|
247 | try {
|
---|
248 | if (typeof(T) == typeof(ILCell)) {
|
---|
249 | return innerStorage is ILCellStorage;
|
---|
250 | }
|
---|
251 | return (innerStorage is ILStorage<T>);
|
---|
252 | } finally {
|
---|
253 | if (innerStorage != null) {
|
---|
254 | innerStorage.Dispose();
|
---|
255 | }
|
---|
256 | }
|
---|
257 | } else {
|
---|
258 | throw new ILArgumentException("indices must define a scalar subarray range");
|
---|
259 | }
|
---|
260 | } finally {
|
---|
261 | cellStorage.Dispose();
|
---|
262 | }
|
---|
263 | }
|
---|
264 | /// <summary>
|
---|
265 | /// gives clone of value addressed, supports deep index addressing
|
---|
266 | /// </summary>
|
---|
267 | /// <param name="indices"></param>
|
---|
268 | /// <returns></returns>
|
---|
269 | internal override object GetValue(params int[] indices) {
|
---|
270 | int mydimlen = Size.NumberOfDimensions;
|
---|
271 | if (indices.Length <= mydimlen) {
|
---|
272 | // address this ILCell
|
---|
273 | ILStorage element = base.GetValueTyped(indices);
|
---|
274 | return (element != null) ? element.Clone() : null;
|
---|
275 | } else {
|
---|
276 | // address element of an element of this ILCell (deep addressing)
|
---|
277 | int[] innerIndices = new int[indices.Length - mydimlen];
|
---|
278 | int i = 1, elIndex = indices[0];
|
---|
279 | for (; i < mydimlen; i++)
|
---|
280 | elIndex += (Size.SequentialIndexDistance(i) * indices[i]);
|
---|
281 | for (int n = 0; i < indices.Length; i++)
|
---|
282 | innerIndices[n++] = indices[i];
|
---|
283 | ILStorage innerElement = base.GetValueTyped(elIndex);
|
---|
284 | if (innerElement == null)
|
---|
285 | throw new ILArgumentException("Deep indices out of range. The specified element does not exist.");
|
---|
286 | return innerElement.GetValue(innerIndices);
|
---|
287 | }
|
---|
288 | }
|
---|
289 | /// <summary>
|
---|
290 | /// get single element from cell storage, predefined element type
|
---|
291 | /// </summary>
|
---|
292 | /// <typeparam name="T">predefined type</typeparam>
|
---|
293 | /// <param name="indices">location of element to return</param>
|
---|
294 | /// <returns>element</returns>
|
---|
295 | /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if the element found is not of the specified type</exception>
|
---|
296 | public T GetValue<T>(params int[] indices) {
|
---|
297 | object obj = GetValue(indices);
|
---|
298 | if (obj is T)
|
---|
299 | return (T)obj;
|
---|
300 | else
|
---|
301 | throw new ILArgumentException("the element at specified position is not of requested type or does not exist");
|
---|
302 | }
|
---|
303 | |
---|
304 |
|
---|
305 | /// <summary>
|
---|
306 | /// Alter elements of this storage adressed by sequential indices
|
---|
307 | /// </summary>
|
---|
308 | /// <param name="indices">array specifying the elements to be altered, sequential indexing</param>
|
---|
309 | /// <param name="values">ILBaseArray of the same type than this array, holding the new values.
|
---|
310 | /// The number of elements of storage must match the
|
---|
311 | /// number of elements of indices. The only exception to this rule is if 'values' is a scalar array. The
|
---|
312 | /// single value of 'values' is than used to set all elements addressed by 'indices'.</param>
|
---|
313 | /// <remarks><para>For empty arrays, scalar or vectors, indices outside the current bounds for
|
---|
314 | /// this array will expand this array to the size neccessary.
|
---|
315 | /// For other arrays the sequential indices given must fit inside this arrays dimensions. </para></remarks>
|
---|
316 | public override void SetRange(ILBaseArray<double> indices, ILDenseStorage<ILStorage> values) {
|
---|
317 | //if (object.Equals(indices,null))
|
---|
318 | // throw new ILArgumentException("indices given must not be null");
|
---|
319 | if (object.Equals(values, null))
|
---|
320 | throw new ILArgumentException("values given must not be null. Use A[ind] = null; if removal was intended.");
|
---|
321 | #region set full shortcut
|
---|
322 | // if (indices is ILFullRange || object.Equals(indices, null)) {
|
---|
323 | if (object.Equals(indices, null))
|
---|
324 | {
|
---|
325 | int pos;
|
---|
326 | ILStorage[] myArray = GetArrayForWrite();
|
---|
327 | if (values.Size.NumberOfElements == 1) {
|
---|
328 | pos = Size.NumberOfElements;
|
---|
329 | ILStorage val = values.GetValueTyped(0);
|
---|
330 | while (pos-- > 0) {
|
---|
331 | if (myArray[pos] != null)
|
---|
332 | myArray[pos].Dispose();
|
---|
333 | myArray[pos] = val;
|
---|
334 | }
|
---|
335 | } else {
|
---|
336 | if (values.Size.NumberOfElements != Size.NumberOfElements)
|
---|
337 | throw new ILArgumentException("number of elements in source must match number of elements in destination array");
|
---|
338 | pos = 0;
|
---|
339 | foreach (ILStorage val in values) {
|
---|
340 | if (myArray[pos] != null)
|
---|
341 | myArray[pos].Dispose();
|
---|
342 | myArray[pos++] = val;
|
---|
343 | }
|
---|
344 | }
|
---|
345 | } else if (indices.Size.NumberOfElements != values.Size.NumberOfElements
|
---|
346 | && values.Size.NumberOfElements != 1)
|
---|
347 | throw new ILArgumentException("number of elements in source must match number of elements in destination array");
|
---|
348 | #endregion
|
---|
349 | if (indices.IsEmpty)
|
---|
350 | return;
|
---|
351 | if (indices.Storage is ILDenseStorage< double>) {
|
---|
352 |
|
---|
353 | double maxIndex, minIndex;
|
---|
354 | ILDenseStorage< double> indStorage = indices.Storage as ILDenseStorage< double>;
|
---|
355 | indStorage.GetLimits(out minIndex, out maxIndex);
|
---|
356 | if (minIndex < 0)
|
---|
357 | throw new ILArgumentException("sequential indices can not be negative");
|
---|
358 | if ((int)maxIndex >= m_size.NumberOfElements) {
|
---|
359 | // handle resize
|
---|
360 | if (m_size.NumberOfDimensions == 2) {
|
---|
361 | if (m_size.NumberOfElements <= 1) {
|
---|
362 | // scalar or empty -> expand along 1
|
---|
363 | ExpandArray(new int[] { (int)maxIndex + 1, 1 });
|
---|
364 | } else if (m_size[0] > 1 && m_size[1] == 1) {
|
---|
365 | ExpandArray(new int[] { (int)maxIndex + 1, 1 });
|
---|
366 | } else if (m_size[0] == 1 && m_size[1] > 1) {
|
---|
367 | ExpandArray(new int[] { 1, (int)maxIndex + 1 });
|
---|
368 | } else
|
---|
369 | throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
|
---|
370 | } else
|
---|
371 | throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
|
---|
372 | }
|
---|
373 | ILStorage[] myArray = GetArrayForWrite();
|
---|
374 |
|
---|
375 | double[] indArray = indStorage.GetArrayForRead();
|
---|
376 |
|
---|
377 | int len = indices.Size.NumberOfElements;
|
---|
378 | int ind;
|
---|
379 | if (values.Size.NumberOfElements == 1) {
|
---|
380 | ILStorage scalarElement = values.GetValueTyped(0);
|
---|
381 | for (int i = 0; i < len; i++) {
|
---|
382 | ind = (int)indArray[i];
|
---|
383 | if (myArray[ind] != null)
|
---|
384 | myArray[ind].Dispose();
|
---|
385 | myArray[ind] = scalarElement;
|
---|
386 | }
|
---|
387 | } else {
|
---|
388 | ILStorage[] valArray = values.GetArrayForRead();
|
---|
389 | for (int i = 0; i < len; ) {
|
---|
390 | ind = (int)indArray[i];
|
---|
391 | if (myArray[ind] != null)
|
---|
392 | myArray[ind].Dispose();
|
---|
393 | myArray[(int)indArray[i]] = valArray[i++];
|
---|
394 | }
|
---|
395 | }
|
---|
396 | } else {
|
---|
397 | throw new ILArgumentException("storage type of given indices is not supported");
|
---|
398 | }
|
---|
399 | }
|
---|
400 | |
---|
401 | #region HYCALPER AUTO GENERATED CODE
|
---|
402 | |
---|
403 |
|
---|
404 | /// <summary>
|
---|
405 | /// Alter elements of this storage adressed by sequential indices
|
---|
406 | /// </summary>
|
---|
407 | /// <param name="indices">array specifying the elements to be altered, sequential indexing</param>
|
---|
408 | /// <param name="values">ILBaseArray of the same type than this array, holding the new values.
|
---|
409 | /// The number of elements of storage must match the
|
---|
410 | /// number of elements of indices. The only exception to this rule is if 'values' is a scalar array. The
|
---|
411 | /// single value of 'values' is than used to set all elements addressed by 'indices'.</param>
|
---|
412 | /// <remarks><para>For empty arrays, scalar or vectors, indices outside the current bounds for
|
---|
413 | /// this array will expand this array to the size neccessary.
|
---|
414 | /// For other arrays the sequential indices given must fit inside this arrays dimensions. </para></remarks>
|
---|
415 | public override void SetRange(ILBaseArray<Int64> indices, ILDenseStorage<ILStorage> values) {
|
---|
416 | //if (object.Equals(indices,null))
|
---|
417 | // throw new ILArgumentException("indices given must not be null");
|
---|
418 | if (object.Equals(values, null))
|
---|
419 | throw new ILArgumentException("values given must not be null. Use A[ind] = null; if removal was intended.");
|
---|
420 | #region set full shortcut
|
---|
421 | // if (indices is ILFullRange || object.Equals(indices, null)) {
|
---|
422 | if (object.Equals(indices, null))
|
---|
423 | {
|
---|
424 | int pos;
|
---|
425 | ILStorage[] myArray = GetArrayForWrite();
|
---|
426 | if (values.Size.NumberOfElements == 1) {
|
---|
427 | pos = Size.NumberOfElements;
|
---|
428 | ILStorage val = values.GetValueTyped(0);
|
---|
429 | while (pos-- > 0) {
|
---|
430 | if (myArray[pos] != null)
|
---|
431 | myArray[pos].Dispose();
|
---|
432 | myArray[pos] = val;
|
---|
433 | }
|
---|
434 | } else {
|
---|
435 | if (values.Size.NumberOfElements != Size.NumberOfElements)
|
---|
436 | throw new ILArgumentException("number of elements in source must match number of elements in destination array");
|
---|
437 | pos = 0;
|
---|
438 | foreach (ILStorage val in values) {
|
---|
439 | if (myArray[pos] != null)
|
---|
440 | myArray[pos].Dispose();
|
---|
441 | myArray[pos++] = val;
|
---|
442 | }
|
---|
443 | }
|
---|
444 | } else if (indices.Size.NumberOfElements != values.Size.NumberOfElements
|
---|
445 | && values.Size.NumberOfElements != 1)
|
---|
446 | throw new ILArgumentException("number of elements in source must match number of elements in destination array");
|
---|
447 | #endregion
|
---|
448 | if (indices.IsEmpty)
|
---|
449 | return;
|
---|
450 | if (indices.Storage is ILDenseStorage< Int64>) {
|
---|
451 |
|
---|
452 | Int64 maxIndex, minIndex;
|
---|
453 | ILDenseStorage< Int64> indStorage = indices.Storage as ILDenseStorage< Int64>;
|
---|
454 | indStorage.GetLimits(out minIndex, out maxIndex);
|
---|
455 | if (minIndex < 0)
|
---|
456 | throw new ILArgumentException("sequential indices can not be negative");
|
---|
457 | if ((int)maxIndex >= m_size.NumberOfElements) {
|
---|
458 | // handle resize
|
---|
459 | if (m_size.NumberOfDimensions == 2) {
|
---|
460 | if (m_size.NumberOfElements <= 1) {
|
---|
461 | // scalar or empty -> expand along 1
|
---|
462 | ExpandArray(new int[] { (int)maxIndex + 1, 1 });
|
---|
463 | } else if (m_size[0] > 1 && m_size[1] == 1) {
|
---|
464 | ExpandArray(new int[] { (int)maxIndex + 1, 1 });
|
---|
465 | } else if (m_size[0] == 1 && m_size[1] > 1) {
|
---|
466 | ExpandArray(new int[] { 1, (int)maxIndex + 1 });
|
---|
467 | } else
|
---|
468 | throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
|
---|
469 | } else
|
---|
470 | throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
|
---|
471 | }
|
---|
472 | ILStorage[] myArray = GetArrayForWrite();
|
---|
473 |
|
---|
474 | Int64[] indArray = indStorage.GetArrayForRead();
|
---|
475 |
|
---|
476 | int len = indices.Size.NumberOfElements;
|
---|
477 | int ind;
|
---|
478 | if (values.Size.NumberOfElements == 1) {
|
---|
479 | ILStorage scalarElement = values.GetValueTyped(0);
|
---|
480 | for (int i = 0; i < len; i++) {
|
---|
481 | ind = (int)indArray[i];
|
---|
482 | if (myArray[ind] != null)
|
---|
483 | myArray[ind].Dispose();
|
---|
484 | myArray[ind] = scalarElement;
|
---|
485 | }
|
---|
486 | } else {
|
---|
487 | ILStorage[] valArray = values.GetArrayForRead();
|
---|
488 | for (int i = 0; i < len; ) {
|
---|
489 | ind = (int)indArray[i];
|
---|
490 | if (myArray[ind] != null)
|
---|
491 | myArray[ind].Dispose();
|
---|
492 | myArray[(int)indArray[i]] = valArray[i++];
|
---|
493 | }
|
---|
494 | }
|
---|
495 | } else {
|
---|
496 | throw new ILArgumentException("storage type of given indices is not supported");
|
---|
497 | }
|
---|
498 | }
|
---|
499 |
|
---|
500 | /// <summary>
|
---|
501 | /// Alter elements of this storage adressed by sequential indices
|
---|
502 | /// </summary>
|
---|
503 | /// <param name="indices">array specifying the elements to be altered, sequential indexing</param>
|
---|
504 | /// <param name="values">ILBaseArray of the same type than this array, holding the new values.
|
---|
505 | /// The number of elements of storage must match the
|
---|
506 | /// number of elements of indices. The only exception to this rule is if 'values' is a scalar array. The
|
---|
507 | /// single value of 'values' is than used to set all elements addressed by 'indices'.</param>
|
---|
508 | /// <remarks><para>For empty arrays, scalar or vectors, indices outside the current bounds for
|
---|
509 | /// this array will expand this array to the size neccessary.
|
---|
510 | /// For other arrays the sequential indices given must fit inside this arrays dimensions. </para></remarks>
|
---|
511 | public override void SetRange(ILBaseArray<Int32> indices, ILDenseStorage<ILStorage> values) {
|
---|
512 | //if (object.Equals(indices,null))
|
---|
513 | // throw new ILArgumentException("indices given must not be null");
|
---|
514 | if (object.Equals(values, null))
|
---|
515 | throw new ILArgumentException("values given must not be null. Use A[ind] = null; if removal was intended.");
|
---|
516 | #region set full shortcut
|
---|
517 | // if (indices is ILFullRange || object.Equals(indices, null)) {
|
---|
518 | if (object.Equals(indices, null))
|
---|
519 | {
|
---|
520 | int pos;
|
---|
521 | ILStorage[] myArray = GetArrayForWrite();
|
---|
522 | if (values.Size.NumberOfElements == 1) {
|
---|
523 | pos = Size.NumberOfElements;
|
---|
524 | ILStorage val = values.GetValueTyped(0);
|
---|
525 | while (pos-- > 0) {
|
---|
526 | if (myArray[pos] != null)
|
---|
527 | myArray[pos].Dispose();
|
---|
528 | myArray[pos] = val;
|
---|
529 | }
|
---|
530 | } else {
|
---|
531 | if (values.Size.NumberOfElements != Size.NumberOfElements)
|
---|
532 | throw new ILArgumentException("number of elements in source must match number of elements in destination array");
|
---|
533 | pos = 0;
|
---|
534 | foreach (ILStorage val in values) {
|
---|
535 | if (myArray[pos] != null)
|
---|
536 | myArray[pos].Dispose();
|
---|
537 | myArray[pos++] = val;
|
---|
538 | }
|
---|
539 | }
|
---|
540 | } else if (indices.Size.NumberOfElements != values.Size.NumberOfElements
|
---|
541 | && values.Size.NumberOfElements != 1)
|
---|
542 | throw new ILArgumentException("number of elements in source must match number of elements in destination array");
|
---|
543 | #endregion
|
---|
544 | if (indices.IsEmpty)
|
---|
545 | return;
|
---|
546 | if (indices.Storage is ILDenseStorage< Int32>) {
|
---|
547 |
|
---|
548 | Int32 maxIndex, minIndex;
|
---|
549 | ILDenseStorage< Int32> indStorage = indices.Storage as ILDenseStorage< Int32>;
|
---|
550 | indStorage.GetLimits(out minIndex, out maxIndex);
|
---|
551 | if (minIndex < 0)
|
---|
552 | throw new ILArgumentException("sequential indices can not be negative");
|
---|
553 | if ((int)maxIndex >= m_size.NumberOfElements) {
|
---|
554 | // handle resize
|
---|
555 | if (m_size.NumberOfDimensions == 2) {
|
---|
556 | if (m_size.NumberOfElements <= 1) {
|
---|
557 | // scalar or empty -> expand along 1
|
---|
558 | ExpandArray(new int[] { (int)maxIndex + 1, 1 });
|
---|
559 | } else if (m_size[0] > 1 && m_size[1] == 1) {
|
---|
560 | ExpandArray(new int[] { (int)maxIndex + 1, 1 });
|
---|
561 | } else if (m_size[0] == 1 && m_size[1] > 1) {
|
---|
562 | ExpandArray(new int[] { 1, (int)maxIndex + 1 });
|
---|
563 | } else
|
---|
564 | throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
|
---|
565 | } else
|
---|
566 | throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
|
---|
567 | }
|
---|
568 | ILStorage[] myArray = GetArrayForWrite();
|
---|
569 |
|
---|
570 | Int32[] indArray = indStorage.GetArrayForRead();
|
---|
571 |
|
---|
572 | int len = indices.Size.NumberOfElements;
|
---|
573 | int ind;
|
---|
574 | if (values.Size.NumberOfElements == 1) {
|
---|
575 | ILStorage scalarElement = values.GetValueTyped(0);
|
---|
576 | for (int i = 0; i < len; i++) {
|
---|
577 | ind = (int)indArray[i];
|
---|
578 | if (myArray[ind] != null)
|
---|
579 | myArray[ind].Dispose();
|
---|
580 | myArray[ind] = scalarElement;
|
---|
581 | }
|
---|
582 | } else {
|
---|
583 | ILStorage[] valArray = values.GetArrayForRead();
|
---|
584 | for (int i = 0; i < len; ) {
|
---|
585 | ind = (int)indArray[i];
|
---|
586 | if (myArray[ind] != null)
|
---|
587 | myArray[ind].Dispose();
|
---|
588 | myArray[(int)indArray[i]] = valArray[i++];
|
---|
589 | }
|
---|
590 | }
|
---|
591 | } else {
|
---|
592 | throw new ILArgumentException("storage type of given indices is not supported");
|
---|
593 | }
|
---|
594 | }
|
---|
595 |
|
---|
596 | /// <summary>
|
---|
597 | /// Alter elements of this storage adressed by sequential indices
|
---|
598 | /// </summary>
|
---|
599 | /// <param name="indices">array specifying the elements to be altered, sequential indexing</param>
|
---|
600 | /// <param name="values">ILBaseArray of the same type than this array, holding the new values.
|
---|
601 | /// The number of elements of storage must match the
|
---|
602 | /// number of elements of indices. The only exception to this rule is if 'values' is a scalar array. The
|
---|
603 | /// single value of 'values' is than used to set all elements addressed by 'indices'.</param>
|
---|
604 | /// <remarks><para>For empty arrays, scalar or vectors, indices outside the current bounds for
|
---|
605 | /// this array will expand this array to the size neccessary.
|
---|
606 | /// For other arrays the sequential indices given must fit inside this arrays dimensions. </para></remarks>
|
---|
607 | public override void SetRange(ILBaseArray<Int16> indices, ILDenseStorage<ILStorage> values) {
|
---|
608 | //if (object.Equals(indices,null))
|
---|
609 | // throw new ILArgumentException("indices given must not be null");
|
---|
610 | if (object.Equals(values, null))
|
---|
611 | throw new ILArgumentException("values given must not be null. Use A[ind] = null; if removal was intended.");
|
---|
612 | #region set full shortcut
|
---|
613 | // if (indices is ILFullRange || object.Equals(indices, null)) {
|
---|
614 | if (object.Equals(indices, null))
|
---|
615 | {
|
---|
616 | int pos;
|
---|
617 | ILStorage[] myArray = GetArrayForWrite();
|
---|
618 | if (values.Size.NumberOfElements == 1) {
|
---|
619 | pos = Size.NumberOfElements;
|
---|
620 | ILStorage val = values.GetValueTyped(0);
|
---|
621 | while (pos-- > 0) {
|
---|
622 | if (myArray[pos] != null)
|
---|
623 | myArray[pos].Dispose();
|
---|
624 | myArray[pos] = val;
|
---|
625 | }
|
---|
626 | } else {
|
---|
627 | if (values.Size.NumberOfElements != Size.NumberOfElements)
|
---|
628 | throw new ILArgumentException("number of elements in source must match number of elements in destination array");
|
---|
629 | pos = 0;
|
---|
630 | foreach (ILStorage val in values) {
|
---|
631 | if (myArray[pos] != null)
|
---|
632 | myArray[pos].Dispose();
|
---|
633 | myArray[pos++] = val;
|
---|
634 | }
|
---|
635 | }
|
---|
636 | } else if (indices.Size.NumberOfElements != values.Size.NumberOfElements
|
---|
637 | && values.Size.NumberOfElements != 1)
|
---|
638 | throw new ILArgumentException("number of elements in source must match number of elements in destination array");
|
---|
639 | #endregion
|
---|
640 | if (indices.IsEmpty)
|
---|
641 | return;
|
---|
642 | if (indices.Storage is ILDenseStorage< Int16>) {
|
---|
643 |
|
---|
644 | Int16 maxIndex, minIndex;
|
---|
645 | ILDenseStorage< Int16> indStorage = indices.Storage as ILDenseStorage< Int16>;
|
---|
646 | indStorage.GetLimits(out minIndex, out maxIndex);
|
---|
647 | if (minIndex < 0)
|
---|
648 | throw new ILArgumentException("sequential indices can not be negative");
|
---|
649 | if ((int)maxIndex >= m_size.NumberOfElements) {
|
---|
650 | // handle resize
|
---|
651 | if (m_size.NumberOfDimensions == 2) {
|
---|
652 | if (m_size.NumberOfElements <= 1) {
|
---|
653 | // scalar or empty -> expand along 1
|
---|
654 | ExpandArray(new int[] { (int)maxIndex + 1, 1 });
|
---|
655 | } else if (m_size[0] > 1 && m_size[1] == 1) {
|
---|
656 | ExpandArray(new int[] { (int)maxIndex + 1, 1 });
|
---|
657 | } else if (m_size[0] == 1 && m_size[1] > 1) {
|
---|
658 | ExpandArray(new int[] { 1, (int)maxIndex + 1 });
|
---|
659 | } else
|
---|
660 | throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
|
---|
661 | } else
|
---|
662 | throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
|
---|
663 | }
|
---|
664 | ILStorage[] myArray = GetArrayForWrite();
|
---|
665 |
|
---|
666 | Int16[] indArray = indStorage.GetArrayForRead();
|
---|
667 |
|
---|
668 | int len = indices.Size.NumberOfElements;
|
---|
669 | int ind;
|
---|
670 | if (values.Size.NumberOfElements == 1) {
|
---|
671 | ILStorage scalarElement = values.GetValueTyped(0);
|
---|
672 | for (int i = 0; i < len; i++) {
|
---|
673 | ind = (int)indArray[i];
|
---|
674 | if (myArray[ind] != null)
|
---|
675 | myArray[ind].Dispose();
|
---|
676 | myArray[ind] = scalarElement;
|
---|
677 | }
|
---|
678 | } else {
|
---|
679 | ILStorage[] valArray = values.GetArrayForRead();
|
---|
680 | for (int i = 0; i < len; ) {
|
---|
681 | ind = (int)indArray[i];
|
---|
682 | if (myArray[ind] != null)
|
---|
683 | myArray[ind].Dispose();
|
---|
684 | myArray[(int)indArray[i]] = valArray[i++];
|
---|
685 | }
|
---|
686 | }
|
---|
687 | } else {
|
---|
688 | throw new ILArgumentException("storage type of given indices is not supported");
|
---|
689 | }
|
---|
690 | }
|
---|
691 |
|
---|
692 | /// <summary>
|
---|
693 | /// Alter elements of this storage adressed by sequential indices
|
---|
694 | /// </summary>
|
---|
695 | /// <param name="indices">array specifying the elements to be altered, sequential indexing</param>
|
---|
696 | /// <param name="values">ILBaseArray of the same type than this array, holding the new values.
|
---|
697 | /// The number of elements of storage must match the
|
---|
698 | /// number of elements of indices. The only exception to this rule is if 'values' is a scalar array. The
|
---|
699 | /// single value of 'values' is than used to set all elements addressed by 'indices'.</param>
|
---|
700 | /// <remarks><para>For empty arrays, scalar or vectors, indices outside the current bounds for
|
---|
701 | /// this array will expand this array to the size neccessary.
|
---|
702 | /// For other arrays the sequential indices given must fit inside this arrays dimensions. </para></remarks>
|
---|
703 | public override void SetRange(ILBaseArray<float> indices, ILDenseStorage<ILStorage> values) {
|
---|
704 | //if (object.Equals(indices,null))
|
---|
705 | // throw new ILArgumentException("indices given must not be null");
|
---|
706 | if (object.Equals(values, null))
|
---|
707 | throw new ILArgumentException("values given must not be null. Use A[ind] = null; if removal was intended.");
|
---|
708 | #region set full shortcut
|
---|
709 | // if (indices is ILFullRange || object.Equals(indices, null)) {
|
---|
710 | if (object.Equals(indices, null))
|
---|
711 | {
|
---|
712 | int pos;
|
---|
713 | ILStorage[] myArray = GetArrayForWrite();
|
---|
714 | if (values.Size.NumberOfElements == 1) {
|
---|
715 | pos = Size.NumberOfElements;
|
---|
716 | ILStorage val = values.GetValueTyped(0);
|
---|
717 | while (pos-- > 0) {
|
---|
718 | if (myArray[pos] != null)
|
---|
719 | myArray[pos].Dispose();
|
---|
720 | myArray[pos] = val;
|
---|
721 | }
|
---|
722 | } else {
|
---|
723 | if (values.Size.NumberOfElements != Size.NumberOfElements)
|
---|
724 | throw new ILArgumentException("number of elements in source must match number of elements in destination array");
|
---|
725 | pos = 0;
|
---|
726 | foreach (ILStorage val in values) {
|
---|
727 | if (myArray[pos] != null)
|
---|
728 | myArray[pos].Dispose();
|
---|
729 | myArray[pos++] = val;
|
---|
730 | }
|
---|
731 | }
|
---|
732 | } else if (indices.Size.NumberOfElements != values.Size.NumberOfElements
|
---|
733 | && values.Size.NumberOfElements != 1)
|
---|
734 | throw new ILArgumentException("number of elements in source must match number of elements in destination array");
|
---|
735 | #endregion
|
---|
736 | if (indices.IsEmpty)
|
---|
737 | return;
|
---|
738 | if (indices.Storage is ILDenseStorage< float>) {
|
---|
739 |
|
---|
740 | float maxIndex, minIndex;
|
---|
741 | ILDenseStorage< float> indStorage = indices.Storage as ILDenseStorage< float>;
|
---|
742 | indStorage.GetLimits(out minIndex, out maxIndex);
|
---|
743 | if (minIndex < 0)
|
---|
744 | throw new ILArgumentException("sequential indices can not be negative");
|
---|
745 | if ((int)maxIndex >= m_size.NumberOfElements) {
|
---|
746 | // handle resize
|
---|
747 | if (m_size.NumberOfDimensions == 2) {
|
---|
748 | if (m_size.NumberOfElements <= 1) {
|
---|
749 | // scalar or empty -> expand along 1
|
---|
750 | ExpandArray(new int[] { (int)maxIndex + 1, 1 });
|
---|
751 | } else if (m_size[0] > 1 && m_size[1] == 1) {
|
---|
752 | ExpandArray(new int[] { (int)maxIndex + 1, 1 });
|
---|
753 | } else if (m_size[0] == 1 && m_size[1] > 1) {
|
---|
754 | ExpandArray(new int[] { 1, (int)maxIndex + 1 });
|
---|
755 | } else
|
---|
756 | throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
|
---|
757 | } else
|
---|
758 | throw new ILArgumentException("resizing array via sequential index access is supported for empty, scalar or vector only");
|
---|
759 | }
|
---|
760 | ILStorage[] myArray = GetArrayForWrite();
|
---|
761 |
|
---|
762 | float[] indArray = indStorage.GetArrayForRead();
|
---|
763 |
|
---|
764 | int len = indices.Size.NumberOfElements;
|
---|
765 | int ind;
|
---|
766 | if (values.Size.NumberOfElements == 1) {
|
---|
767 | ILStorage scalarElement = values.GetValueTyped(0);
|
---|
768 | for (int i = 0; i < len; i++) {
|
---|
769 | ind = (int)indArray[i];
|
---|
770 | if (myArray[ind] != null)
|
---|
771 | myArray[ind].Dispose();
|
---|
772 | myArray[ind] = scalarElement;
|
---|
773 | }
|
---|
774 | } else {
|
---|
775 | ILStorage[] valArray = values.GetArrayForRead();
|
---|
776 | for (int i = 0; i < len; ) {
|
---|
777 | ind = (int)indArray[i];
|
---|
778 | if (myArray[ind] != null)
|
---|
779 | myArray[ind].Dispose();
|
---|
780 | myArray[(int)indArray[i]] = valArray[i++];
|
---|
781 | }
|
---|
782 | }
|
---|
783 | } else {
|
---|
784 | throw new ILArgumentException("storage type of given indices is not supported");
|
---|
785 | }
|
---|
786 | }
|
---|
787 |
|
---|
788 | #endregion HYCALPER AUTO GENERATED CODE
|
---|
789 |
|
---|
790 | internal override void SetRangeFull(ILDenseStorage<ILStorage> values) {
|
---|
791 | if (values.Size.NumberOfElements != 1 && values.Size.NumberOfElements != Size.NumberOfElements)
|
---|
792 | throw new ILArgumentException("source and destination array must have the same number of arguments");
|
---|
793 | ILStorage[] myArr = GetArrayForWrite();
|
---|
794 | if (values.Size.NumberOfElements == 1) {
|
---|
795 | ILStorage scal = values.GetValueTyped(0);
|
---|
796 | for (int i = Size.NumberOfElements; i-- > 0; ) {
|
---|
797 | if (myArr[i] != null)
|
---|
798 | myArr[i].Dispose();
|
---|
799 | myArr[i] = scal;
|
---|
800 | }
|
---|
801 | } else {
|
---|
802 | ILStorage[] valArr = values.GetArrayForRead();
|
---|
803 | for (int i = Size.NumberOfElements; i-- > 0; ) {
|
---|
804 | if (myArr[i] != null)
|
---|
805 | myArr[i].Dispose();
|
---|
806 | myArr[i] = valArr[i];
|
---|
807 | }
|
---|
808 | }
|
---|
809 | }
|
---|
810 | public override void SetRange(ILRange range, ILDenseStorage<ILStorage> values) {
|
---|
811 | if (range.Size.NumberOfElements == 0) return;
|
---|
812 | int rangeDimLen = range.RangeArray.Length, higherDimSum = 0;
|
---|
813 | int leadDimLenRange = range[0].Count, leadDimLen = m_size[0];
|
---|
814 | int d, outElemCount = range.Size.NumberOfElements;
|
---|
815 | ILStorage[] myArr = GetArrayForWrite();
|
---|
816 | int[] idxArr = new int[rangeDimLen]; // used to store current position inside higher dims
|
---|
817 | ILIntList[] rng = range.RangeArray;
|
---|
818 | int[] seqDistances = m_size.GetSequentialIndexDistances(range.Size.NumberOfDimensions);
|
---|
819 | int[] inFullDim = new int[rangeDimLen];
|
---|
820 | // initialize higher dimension summand and inFullDim[] flag array
|
---|
821 | for (int i = 1; i < idxArr.Length; i++) {
|
---|
822 | if (rng[i][0] < 0) {
|
---|
823 | inFullDim[i] = rng[i][0];
|
---|
824 | } else {
|
---|
825 | inFullDim[i] = 0;
|
---|
826 | higherDimSum += seqDistances[i] * rng[i][0];
|
---|
827 | }
|
---|
828 | }
|
---|
829 | //for (int lIdx = 0; lIdx < leadDimLenRange; lIdx ++) {
|
---|
830 | // retArr[curPosOut++] = myArr[higherDimSum + rleadDim[lIdx]];
|
---|
831 | //}
|
---|
832 | if (values.Size.NumberOfElements == 1) {
|
---|
833 | #region scalar case
|
---|
834 | ILStorage scalar = values.GetValueTyped(0);
|
---|
835 | while (true) {
|
---|
836 | #region copy along leading dimension
|
---|
837 | for (int i = 0; i < rng[0].Count; i++) {
|
---|
838 | if (rng[0][i] < 0) {
|
---|
839 | for (int c = -rng[0][i]; c-- >= 0; ) {
|
---|
840 | ILStorage cur = myArr[higherDimSum];
|
---|
841 | if (cur != null)
|
---|
842 | cur.Dispose();
|
---|
843 | myArr[higherDimSum] = scalar.Clone();
|
---|
844 | higherDimSum++;
|
---|
845 | }
|
---|
846 | higherDimSum += (rng[0][i] - 1); // negative value in rng!
|
---|
847 | } else {
|
---|
848 | int ind = higherDimSum + rng[0][i];
|
---|
849 | ILStorage cur = myArr[ind];
|
---|
850 | if (cur != null)
|
---|
851 | cur.Dispose();
|
---|
852 | myArr[ind] = scalar.Clone();
|
---|
853 | }
|
---|
854 | }
|
---|
855 | #endregion
|
---|
856 | #region increase higher dims
|
---|
857 | d = 1;
|
---|
858 | while (d < idxArr.Length) {
|
---|
859 | if (inFullDim[d] < 0) {
|
---|
860 | higherDimSum += seqDistances[d];
|
---|
861 | inFullDim[d]++;
|
---|
862 | break;
|
---|
863 | }
|
---|
864 |
|
---|
865 | if (rng[d][idxArr[d]] >= 0) {
|
---|
866 | higherDimSum -= (rng[d][idxArr[d]] * seqDistances[d]);
|
---|
867 | } else {
|
---|
868 | higherDimSum += (rng[d][idxArr[d]] * seqDistances[d]);
|
---|
869 | }
|
---|
870 | idxArr[d]++;
|
---|
871 | if (idxArr[d] == rng[d].Count) {
|
---|
872 | idxArr[d] = 0;
|
---|
873 | if (rng[d][idxArr[d]] < 0) {
|
---|
874 | inFullDim[d] = rng[d][idxArr[d]];
|
---|
875 | }
|
---|
876 | d++;
|
---|
877 | } else if (rng[d][idxArr[d]] < 0) {
|
---|
878 | inFullDim[d] = rng[d][idxArr[d]];
|
---|
879 | break;
|
---|
880 | } else {
|
---|
881 | higherDimSum += seqDistances[d] * rng[d][idxArr[d]];
|
---|
882 | break;
|
---|
883 | }
|
---|
884 |
|
---|
885 | }
|
---|
886 | #endregion
|
---|
887 | if (d >= idxArr.Length)
|
---|
888 | break;
|
---|
889 | }
|
---|
890 | scalar.Dispose(); // we have only made copies of scalar input
|
---|
891 | #endregion
|
---|
892 | } else {
|
---|
893 | #region non scalar case
|
---|
894 | ILStorage[] valuesArr = values.GetArrayForRead();
|
---|
895 | int valuesPos = 0;
|
---|
896 | while (true) {
|
---|
897 | // copy along leading dimension
|
---|
898 | for (int i = 0; i < rng[0].Count; i++) {
|
---|
899 | if (rng[0][i] < 0) {
|
---|
900 | for (int c = -rng[0][i]; c-- >= 0; ) {
|
---|
901 | ILStorage cur = myArr[higherDimSum];
|
---|
902 | if (cur != null)
|
---|
903 | cur.Dispose();
|
---|
904 | myArr[higherDimSum] = valuesArr[valuesPos];
|
---|
905 | valuesPos++;
|
---|
906 | higherDimSum++;
|
---|
907 | }
|
---|
908 | higherDimSum += (rng[0][i] - 1); // negative value in rng!
|
---|
909 | } else {
|
---|
910 | int ind = higherDimSum + rng[0][i];
|
---|
911 | ILStorage cur = myArr[ind];
|
---|
912 | if (cur != null)
|
---|
913 | cur.Dispose();
|
---|
914 | myArr[ind] = valuesArr[valuesPos];
|
---|
915 | valuesPos++;
|
---|
916 | }
|
---|
917 | }
|
---|
918 |
|
---|
919 | // increase higher dims
|
---|
920 | d = 1;
|
---|
921 | while (d < idxArr.Length) {
|
---|
922 | if (inFullDim[d] < 0) {
|
---|
923 | higherDimSum += seqDistances[d];
|
---|
924 | inFullDim[d]++;
|
---|
925 | break;
|
---|
926 | }
|
---|
927 |
|
---|
928 | if (rng[d][idxArr[d]] >= 0) {
|
---|
929 | higherDimSum -= (rng[d][idxArr[d]] * seqDistances[d]);
|
---|
930 | } else {
|
---|
931 | higherDimSum += (rng[d][idxArr[d]] * seqDistances[d]);
|
---|
932 | }
|
---|
933 | idxArr[d]++;
|
---|
934 | if (idxArr[d] == rng[d].Count) {
|
---|
935 | idxArr[d] = 0;
|
---|
936 | if (rng[d][idxArr[d]] < 0) {
|
---|
937 | inFullDim[d] = rng[d][idxArr[d]];
|
---|
938 | }
|
---|
939 | d++;
|
---|
940 | } else if (rng[d][idxArr[d]] < 0) {
|
---|
941 | inFullDim[d] = rng[d][idxArr[d]];
|
---|
942 | break;
|
---|
943 | } else {
|
---|
944 | higherDimSum += seqDistances[d] * rng[d][idxArr[d]];
|
---|
945 | break;
|
---|
946 | }
|
---|
947 |
|
---|
948 | }
|
---|
949 | if (d >= idxArr.Length)
|
---|
950 | break;
|
---|
951 | }
|
---|
952 | #endregion
|
---|
953 | }
|
---|
954 | }
|
---|
955 | /// <summary>
|
---|
956 | /// detach this storage: copy its countable array if needed
|
---|
957 | /// </summary>
|
---|
958 | protected override void Detach() {
|
---|
959 | if (m_data.ReferenceCount <= 1)
|
---|
960 | return;
|
---|
961 | Data = m_data.CreateCopy();
|
---|
962 | }
|
---|
963 | /// <summary>
|
---|
964 | /// walk all elements of this cell and recursively replace them with clones of themself
|
---|
965 | /// </summary>
|
---|
966 | /// <remarks>Due to the cloning mechanism of ILNumerics, the full clone
|
---|
967 | /// will be cheap by using lazy copies of the data. Cloned elements will automatically be detached on write access.</remarks>
|
---|
968 | internal void DeepReferenceElements() {
|
---|
969 | int len = Size.NumberOfElements;
|
---|
970 | ILStorage[] myArr = GetArrayForWrite();
|
---|
971 | for (int i = 0; i < len; i++) {
|
---|
972 | ILStorage a = myArr[i];
|
---|
973 | if (!Object.ReferenceEquals(a, null) && !a.IsDisposed) {
|
---|
974 | ILStorage clone = a.Clone();
|
---|
975 | myArr[i] =clone;
|
---|
976 | } else
|
---|
977 | myArr[i] = null;
|
---|
978 | }
|
---|
979 | }
|
---|
980 | internal ILDenseStorage<T> GetDenseStorage<T>(params ILBaseArray[] indices) {
|
---|
981 | ILCellStorage retStorage = (ILCellStorage)Subarray(indices);
|
---|
982 | if (retStorage.Size.NumberOfElements == 1) {
|
---|
983 | ILStorage innerStorage = (retStorage as ILCellStorage).GetValueTyped(0);
|
---|
984 | if (innerStorage is ILDenseStorage<T>) {
|
---|
985 | return innerStorage as ILDenseStorage<T>;
|
---|
986 | } else {
|
---|
987 | if (innerStorage == null) {
|
---|
988 | throw new ILArgumentException("the type of the element at the specified position could not be determined");
|
---|
989 | }
|
---|
990 | Type innerStorageType = innerStorage.GetType();
|
---|
991 | if (innerStorageType == typeof(ILCellStorage))
|
---|
992 | throw new ILArgumentException("The cell element specified contains a cell storage. Use GetCell() in order to retrieve cells from cells!");
|
---|
993 | if (!innerStorageType.Name.Contains("ILDenseStorage")) // unlikely to happen in ILNumerics R2
|
---|
994 | throw new ILArgumentException("the type of the element at the specified position is not valid in this context");
|
---|
995 | Type[] arguments = innerStorageType.GetGenericArguments();
|
---|
996 | if (arguments.Length > 0)
|
---|
997 | throw new ILArgumentException(String.Format("the array found at the specified location is of type <{0}> and not of the requested type <{1}>",arguments[0].Name, typeof(T).Name));
|
---|
998 | throw new ILArgumentException("an unknown error occoured while trying to retrieve the cell element");
|
---|
999 | }
|
---|
1000 | } else {
|
---|
1001 | throw new ILArgumentException("indices must define a scalar subarray range to an existing cell element");
|
---|
1002 | }
|
---|
1003 | }
|
---|
1004 | internal ILBaseArray GetScalar(params ILBaseArray[] indices) {
|
---|
1005 | ILCellStorage cellStorage = (ILCellStorage)Subarray(indices);
|
---|
1006 | if (cellStorage.Size.NumberOfElements == 1) {
|
---|
1007 | ILStorage innerStorage = cellStorage.GetValueTyped(0);
|
---|
1008 | return (innerStorage == null) ? null : innerStorage.GetAsBaseArray();
|
---|
1009 | } else {
|
---|
1010 | throw new ILArgumentException("indices must define a scalar subarray range");
|
---|
1011 | }
|
---|
1012 |
|
---|
1013 | }
|
---|
1014 | internal override ILBaseArray GetAsBaseArray() {
|
---|
1015 | return new ILRetCell((ILCellStorage)Clone());
|
---|
1016 | }
|
---|
1017 | internal override void Dispose(bool manual) {
|
---|
1018 | if (IsDisposed) return;
|
---|
1019 |
|
---|
1020 | for (int i = m_size.NumberOfElements; i--> 0;) {
|
---|
1021 | ILStorage storage = m_data.Data[i];
|
---|
1022 | if(storage != null)
|
---|
1023 | storage.Dispose(manual);
|
---|
1024 | }
|
---|
1025 | base.Dispose(manual);
|
---|
1026 | }
|
---|
1027 | internal override bool Equals(object obj) {
|
---|
1028 | if (object.Equals(obj, null)) return false;
|
---|
1029 | ILCellStorage obStor = obj as ILCellStorage;
|
---|
1030 | if (obStor != null) {
|
---|
1031 | if (!obStor.Size.IsSameSize(Size)) return false;
|
---|
1032 | ILStorage[] myArr = GetArrayForRead();
|
---|
1033 | ILStorage[] objArr = obStor.GetArrayForRead();
|
---|
1034 |
|
---|
1035 | for (int i = Size.NumberOfElements; i --> 0; ) {
|
---|
1036 | ILStorage stor1 = myArr[i];
|
---|
1037 | ILStorage stor2 = objArr[i];
|
---|
1038 | if (stor1 == null ^ stor2 == null) return false;
|
---|
1039 | if (stor1 == null) continue;
|
---|
1040 | if (!myArr[i].Equals(objArr[i])) return false;
|
---|
1041 | }
|
---|
1042 | return true;
|
---|
1043 | } else {
|
---|
1044 | return false;
|
---|
1045 | }
|
---|
1046 | }
|
---|
1047 | #endregion
|
---|
1048 |
|
---|
1049 | #region helper
|
---|
1050 | private static ILStorage[] baseArray2Storages(ILBaseArray[] system_array, int minLength) {
|
---|
1051 | using (ILScope.Enter(system_array)) {
|
---|
1052 | ILStorage[] ret = ILMemoryPool.Pool.New<ILStorage>(minLength);
|
---|
1053 | int i = 0;
|
---|
1054 | for (; i < system_array.Length; i++) {
|
---|
1055 | ILBaseArray curArr = system_array[i];
|
---|
1056 | if (curArr == null) {
|
---|
1057 | ret[i] = null;
|
---|
1058 | } else {
|
---|
1059 | ILStorage cur = system_array[i].Storage;
|
---|
1060 | ret[i] = cur;
|
---|
1061 | }
|
---|
1062 | }
|
---|
1063 | // clear the rest of the array
|
---|
1064 | for (; i < minLength; i++)
|
---|
1065 | ret[i] = null;
|
---|
1066 | return ret;
|
---|
1067 | }
|
---|
1068 | }
|
---|
1069 | protected override ILDenseStorage<ILStorage> CreateSelf(ILStorage[] data, ILSize size) {
|
---|
1070 | ILCellStorage ret = new ILCellStorage(data, size);
|
---|
1071 | //ret.DeepReferenceElements();
|
---|
1072 | return ret;
|
---|
1073 | }
|
---|
1074 | protected override ILDenseStorage<ILStorage> CreateSelf(ILSize size) {
|
---|
1075 | ILCellStorage ret = new ILCellStorage(size);
|
---|
1076 | //ret.DeepReferenceElements();
|
---|
1077 | return ret;
|
---|
1078 | }
|
---|
1079 | protected override ILDenseStorage<ILStorage> CreateSelf(ILCountableArray<ILStorage> Data, ILSize ILSize) {
|
---|
1080 | ILCellStorage ret = new ILCellStorage(Data, ILSize);
|
---|
1081 | //ret.DeepReferenceElements();
|
---|
1082 | return ret;
|
---|
1083 | }
|
---|
1084 | internal override string ShortInfo() {
|
---|
1085 | if (IsDisposed)
|
---|
1086 | return "Cell (disposed)";
|
---|
1087 | return "Cell " + Size.ToString();
|
---|
1088 | }
|
---|
1089 | //internal override void Remove(int dimension, ILIntList indices) {
|
---|
1090 | // using (ILScope.Enter()) {
|
---|
1091 | // if (dimension >= Dimensions.NumberOfDimensions)
|
---|
1092 | // throw new ILArgumentException("index out of range");
|
---|
1093 | // if (dimension == -1) {
|
---|
1094 | // Data = new ILCountableArray<ILStorage>(0);
|
---|
1095 | // m_dimensions = ILSize.Empty00;
|
---|
1096 | // return;
|
---|
1097 | // }
|
---|
1098 | // // TODO: may should be replaced with a faster (&fancier? ) version... ??
|
---|
1099 | // ILBaseArray[] dims = new ILBaseArray[Dimensions.NumberOfDimensions];
|
---|
1100 | // ILIntList keepInd = ILIntList.Create();
|
---|
1101 | // ILIntList remvInd = indices;
|
---|
1102 | // int max = Dimensions[dimension];
|
---|
1103 | // foreach (int i in indices)
|
---|
1104 | // if (i >= max || i < 0) throw new ILArgumentException("removal index out of range");
|
---|
1105 | // for (int i = 0; i < max; i++) {
|
---|
1106 | // if (!remvInd.Contains(i)) {
|
---|
1107 | // keepInd.Add(i);
|
---|
1108 | // }
|
---|
1109 | // }
|
---|
1110 | // // we give the indices to _keep_ to the subarray function
|
---|
1111 | // ILArray<int> remIndices = ILMath.create<int>(keepInd.GetArray(), new ILSize(1, keepInd.Count));
|
---|
1112 | // if (remIndices.Dimensions.NumberOfElements == Dimensions[dimension]) {
|
---|
1113 | // // nothing to do
|
---|
1114 | // return;
|
---|
1115 | // }
|
---|
1116 | // for (int i = 0; i < dims.Length; i++) {
|
---|
1117 | // dims[i] = ILMath.full;
|
---|
1118 | // }
|
---|
1119 | // dims[dimension] = remIndices;
|
---|
1120 | // ILCellStorage ret = (ILCellStorage)Subarray(dims);
|
---|
1121 | // //ret.DeepReferenceElements();
|
---|
1122 |
|
---|
1123 | // Dispose();
|
---|
1124 | // Data = ret.Data;
|
---|
1125 | // m_dimensions = ret.Dimensions;
|
---|
1126 | // }
|
---|
1127 | //}
|
---|
1128 | #endregion
|
---|
1129 |
|
---|
1130 | }
|
---|
1131 | }
|
---|