Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Storage/ILDenseStorage_Constructors.cs @ 9426

Last change on this file since 9426 was 9102, checked in by gkronber, 12 years ago

#1967: ILNumerics source for experimentation

File size: 23.8 KB
Line 
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
40using System;
41using System.Collections.Generic;
42using System.Text;
43using System.IO;
44using System.Linq.Expressions;
45using System.Runtime.Serialization;
46using ILNumerics;
47using ILNumerics.Misc;
48using ILNumerics.Data;
49using ILNumerics.Exceptions;
50
51namespace 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}
Note: See TracBrowser for help on using the repository browser.