Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Functions/statistics/nansum.cs @ 11194

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

#1967: ILNumerics source for experimentation

File size: 21.3 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.Threading;
44using ILNumerics.Storage;
45using ILNumerics.Misc;
46using ILNumerics.Exceptions;
47
48
49
50namespace ILNumerics  {
51  public partial class ILMath {
52
53    /// <summary>
54    /// Sum elements along first non singleton dimension ignoring NaN values
55    /// </summary>
56    /// <param name="A">Input array</param>
57    /// <param name="dim">[Optional] Index of the dimension to operate along. If omitted operates along the first non singleton dimension (i.e. != 1).</param>
58    /// <returns>Sum of elements along specified of first non singleton dimension, ignoring nan values</returns>
59    /// <remarks><para>The array returned will have the same size as <paramref name="A"/>, with the specified or first non singleton dimension
60    /// reduced to the length 1. It will contain the sum of all elements along that dimension after removing NaN values respectively. </para>
61    /// <para>If A contains an all NaN vector along <paramref name="dim"/> ,
62    /// the resulting sum will be 0 - not NaN! This corresponds to the sum of an empty vector.</para></remarks>
63    public static ILRetArray<double> nansum(ILInArray<double> A, int dim = -1)
64    {
65      if (dim < 0)
66        dim = A.Size.WorkingDimension();
67      return nansum_internal(A, dim, false);
68    }
69   
70    /// <summary>
71    /// Depending on settings, calculate nansum or nanmean
72    /// </summary>
73    private static ILRetArray<double> nansum_internal (ILInArray<double> A, int dim, bool computeMean) {
74      using (ILScope.Enter(A)) {
75        if (dim >= A.Size.NumberOfDimensions)
76           return A.C;
77       
78        if (A.IsScalar) {
79          return array<double>(new double[1] { A.GetValue(0) }, 1, 1);
80        }
81       
82        if (A.S[dim] == 1) return A.C;
83
84        int[] newDims = A.S.ToIntArray();
85        newDims[dim] = 1;
86        ILSize retDimension = new ILSize(newDims);
87
88        if (A.IsEmpty)
89          return empty<double>(retDimension);
90
91        double[] retArr = ILMemoryPool.Pool.New<double>(retDimension.NumberOfElements);
92
93        int inc = A.Size.SequentialIndexDistance(dim);
94        int dimLen = A.Size[dim];
95        int maxRuns = retDimension.NumberOfElements;
96        int modHelp = A.Size.NumberOfElements - 1;
97        int modOut = retDimension.NumberOfElements - 1;
98        int incOut = retDimension.SequentialIndexDistance(dim);
99        int numelA = A.S.NumberOfElements;
100       
101        double[] aArray = A.GetArrayForRead();
102        if (maxRuns == 1) {
103         
104          double tmp = 0;
105          if (computeMean)
106          {
107            int cnt = 0;
108            for (int j = 0; j < dimLen; j++)
109            {
110              if (!/*HC:inArr1*/double.IsNaN(aArray[j]))
111              {
112                tmp += aArray[j];
113                cnt++;
114              }
115            }
116            if (cnt == 0)
117              retArr[0] = double.NaN;
118            else
119              retArr[0] = tmp / cnt;
120          }
121          else
122          {
123            for (int j = 0; j < dimLen; j++)
124            {
125              if (!/*HC:inArr1*/double.IsNaN(aArray[j]))
126                tmp += aArray[j];
127            }
128            retArr[0] = tmp;
129          }
130        } else {
131          #region may run parallel
132          int i = 0, workItemCount = Settings.s_maxNumberThreads, workItemLength, workerCount = 1;
133          if (Settings.s_maxNumberThreads > 1 && maxRuns > 1
134            && numelA / 2 >= Settings.s_minParallelElement1Count) {
135
136            if (maxRuns >= Settings.s_maxNumberThreads
137              && numelA / Settings.s_maxNumberThreads > Settings.s_minParallelElement1Count) {
138              workItemLength = maxRuns / workItemCount;
139            } else {
140              workItemLength = maxRuns / 2;
141              workItemCount = 2;
142            }
143           
144          } else {
145            workItemLength = maxRuns;
146            workItemCount = 1;
147          }
148          Action<object> action = (data) => {
149            Tuple<int, int> range = (Tuple<int, int>)data;
150            int from = range.Item1, to = range.Item2;
151            for (int c = from; c < to; c++) {
152              int pos = (int)(((long)dimLen * c * inc) % modHelp);
153              long posOut = ((long)c * incOut);
154              if (posOut > modOut)
155                posOut = ((posOut - 1) % modOut) + 1;
156             
157              double tmp = 0;
158              int end = pos + dimLen * inc;
159              if (computeMean)
160              {
161                int cnt = 0;
162                for (int j = pos; j < end; j += inc)
163                {
164                  if (!/*HC:inArr1*/double.IsNaN(aArray[j]))
165                  {
166                    tmp += aArray[j];
167                    cnt++;
168                  }
169                }
170                if (cnt == 0)
171                  retArr[posOut] = double.NaN;
172                else
173                  retArr[posOut] = tmp / cnt;
174              }
175              else
176              {
177                 
178                for (int j = pos; j < end; j += inc)
179                {
180                  if (!/*HC:inArr1*/double.IsNaN(aArray[j]))
181                    tmp += aArray[j];
182                }
183                retArr[posOut] = tmp;
184              }
185            }
186            System.Threading.Interlocked.Decrement(ref workerCount);
187          };
188          for (; i < workItemCount - 1; i++) {
189            Interlocked.Increment(ref workerCount);
190
191            ILThreadPool.QueueUserWorkItem(i,action, Tuple.Create(i * workItemLength, (i + 1) * workItemLength));
192          }
193          action(Tuple.Create(i * workItemLength, maxRuns));
194          ILThreadPool.Wait4Workers(ref workerCount);
195          #endregion
196        }
197        return array(retArr, newDims);
198      }
199    }
200
201#region HYCALPER AUTO GENERATED CODE
202
203    /// <summary>
204    /// Sum elements along first non singleton dimension ignoring NaN values
205    /// </summary>
206    /// <param name="A">Input array</param>
207    /// <param name="dim">[Optional] Index of the dimension to operate along. If omitted operates along the first non singleton dimension (i.e. != 1).</param>
208    /// <returns>Sum of elements along specified of first non singleton dimension, ignoring nan values</returns>
209    /// <remarks><para>The array returned will have the same size as <paramref name="A"/>, with the specified or first non singleton dimension
210    /// reduced to the length 1. It will contain the sum of all elements along that dimension after removing NaN values respectively. </para>
211    /// <para>If A contains an all NaN vector along <paramref name="dim"/> ,
212    /// the resulting sum will be 0 - not NaN! This corresponds to the sum of an empty vector.</para></remarks>
213    public static ILRetArray<fcomplex> nansum(ILInArray<fcomplex> A, int dim = -1)
214    {
215      if (dim < 0)
216        dim = A.Size.WorkingDimension();
217      return nansum_internal(A, dim, false);
218    }
219   
220    /// <summary>
221    /// Depending on settings, calculate nansum or nanmean
222    /// </summary>
223    private static ILRetArray<fcomplex> nansum_internal (ILInArray<fcomplex> A, int dim, bool computeMean) {
224      using (ILScope.Enter(A)) {
225        if (dim >= A.Size.NumberOfDimensions)
226           return A.C;
227       
228        if (A.IsScalar) {
229          return array<fcomplex>(new fcomplex[1] { A.GetValue(0) }, 1, 1);
230        }
231       
232        if (A.S[dim] == 1) return A.C;
233
234        int[] newDims = A.S.ToIntArray();
235        newDims[dim] = 1;
236        ILSize retDimension = new ILSize(newDims);
237
238        if (A.IsEmpty)
239          return empty<fcomplex>(retDimension);
240
241        fcomplex[] retArr = ILMemoryPool.Pool.New<fcomplex>(retDimension.NumberOfElements);
242
243        int inc = A.Size.SequentialIndexDistance(dim);
244        int dimLen = A.Size[dim];
245        int maxRuns = retDimension.NumberOfElements;
246        int modHelp = A.Size.NumberOfElements - 1;
247        int modOut = retDimension.NumberOfElements - 1;
248        int incOut = retDimension.SequentialIndexDistance(dim);
249        int numelA = A.S.NumberOfElements;
250       
251        fcomplex[] aArray = A.GetArrayForRead();
252        if (maxRuns == 1) {
253         
254          fcomplex tmp = 0;
255          if (computeMean)
256          {
257            int cnt = 0;
258            for (int j = 0; j < dimLen; j++)
259            {
260              if (!/*HC:*/fcomplex.IsNaN(aArray[j]))
261              {
262                tmp += aArray[j];
263                cnt++;
264              }
265            }
266            if (cnt == 0)
267              retArr[0] = fcomplex.NaN;
268            else
269              retArr[0] = tmp / cnt;
270          }
271          else
272          {
273            for (int j = 0; j < dimLen; j++)
274            {
275              if (!/*HC:*/fcomplex.IsNaN(aArray[j]))
276                tmp += aArray[j];
277            }
278            retArr[0] = tmp;
279          }
280        } else {
281          #region may run parallel
282          int i = 0, workItemCount = Settings.s_maxNumberThreads, workItemLength, workerCount = 1;
283          if (Settings.s_maxNumberThreads > 1 && maxRuns > 1
284            && numelA / 2 >= Settings.s_minParallelElement1Count) {
285
286            if (maxRuns >= Settings.s_maxNumberThreads
287              && numelA / Settings.s_maxNumberThreads > Settings.s_minParallelElement1Count) {
288              workItemLength = maxRuns / workItemCount;
289            } else {
290              workItemLength = maxRuns / 2;
291              workItemCount = 2;
292            }
293           
294          } else {
295            workItemLength = maxRuns;
296            workItemCount = 1;
297          }
298          Action<object> action = (data) => {
299            Tuple<int, int> range = (Tuple<int, int>)data;
300            int from = range.Item1, to = range.Item2;
301            for (int c = from; c < to; c++) {
302              int pos = (int)(((long)dimLen * c * inc) % modHelp);
303              long posOut = ((long)c * incOut);
304              if (posOut > modOut)
305                posOut = ((posOut - 1) % modOut) + 1;
306             
307              fcomplex tmp = 0;
308              int end = pos + dimLen * inc;
309              if (computeMean)
310              {
311                int cnt = 0;
312                for (int j = pos; j < end; j += inc)
313                {
314                  if (!/*HC:*/fcomplex.IsNaN(aArray[j]))
315                  {
316                    tmp += aArray[j];
317                    cnt++;
318                  }
319                }
320                if (cnt == 0)
321                  retArr[posOut] = fcomplex.NaN;
322                else
323                  retArr[posOut] = tmp / cnt;
324              }
325              else
326              {
327                 
328                for (int j = pos; j < end; j += inc)
329                {
330                  if (!/*HC:*/fcomplex.IsNaN(aArray[j]))
331                    tmp += aArray[j];
332                }
333                retArr[posOut] = tmp;
334              }
335            }
336            System.Threading.Interlocked.Decrement(ref workerCount);
337          };
338          for (; i < workItemCount - 1; i++) {
339            Interlocked.Increment(ref workerCount);
340
341            ILThreadPool.QueueUserWorkItem(i,action, Tuple.Create(i * workItemLength, (i + 1) * workItemLength));
342          }
343          action(Tuple.Create(i * workItemLength, maxRuns));
344          ILThreadPool.Wait4Workers(ref workerCount);
345          #endregion
346        }
347        return array(retArr, newDims);
348      }
349    }
350    /// <summary>
351    /// Sum elements along first non singleton dimension ignoring NaN values
352    /// </summary>
353    /// <param name="A">Input array</param>
354    /// <param name="dim">[Optional] Index of the dimension to operate along. If omitted operates along the first non singleton dimension (i.e. != 1).</param>
355    /// <returns>Sum of elements along specified of first non singleton dimension, ignoring nan values</returns>
356    /// <remarks><para>The array returned will have the same size as <paramref name="A"/>, with the specified or first non singleton dimension
357    /// reduced to the length 1. It will contain the sum of all elements along that dimension after removing NaN values respectively. </para>
358    /// <para>If A contains an all NaN vector along <paramref name="dim"/> ,
359    /// the resulting sum will be 0 - not NaN! This corresponds to the sum of an empty vector.</para></remarks>
360    public static ILRetArray<float> nansum(ILInArray<float> A, int dim = -1)
361    {
362      if (dim < 0)
363        dim = A.Size.WorkingDimension();
364      return nansum_internal(A, dim, false);
365    }
366   
367    /// <summary>
368    /// Depending on settings, calculate nansum or nanmean
369    /// </summary>
370    private static ILRetArray<float> nansum_internal (ILInArray<float> A, int dim, bool computeMean) {
371      using (ILScope.Enter(A)) {
372        if (dim >= A.Size.NumberOfDimensions)
373           return A.C;
374       
375        if (A.IsScalar) {
376          return array<float>(new float[1] { A.GetValue(0) }, 1, 1);
377        }
378       
379        if (A.S[dim] == 1) return A.C;
380
381        int[] newDims = A.S.ToIntArray();
382        newDims[dim] = 1;
383        ILSize retDimension = new ILSize(newDims);
384
385        if (A.IsEmpty)
386          return empty<float>(retDimension);
387
388        float[] retArr = ILMemoryPool.Pool.New<float>(retDimension.NumberOfElements);
389
390        int inc = A.Size.SequentialIndexDistance(dim);
391        int dimLen = A.Size[dim];
392        int maxRuns = retDimension.NumberOfElements;
393        int modHelp = A.Size.NumberOfElements - 1;
394        int modOut = retDimension.NumberOfElements - 1;
395        int incOut = retDimension.SequentialIndexDistance(dim);
396        int numelA = A.S.NumberOfElements;
397       
398        float[] aArray = A.GetArrayForRead();
399        if (maxRuns == 1) {
400         
401          float tmp = 0;
402          if (computeMean)
403          {
404            int cnt = 0;
405            for (int j = 0; j < dimLen; j++)
406            {
407              if (!/*HC:*/float.IsNaN(aArray[j]))
408              {
409                tmp += aArray[j];
410                cnt++;
411              }
412            }
413            if (cnt == 0)
414              retArr[0] = float.NaN;
415            else
416              retArr[0] = tmp / cnt;
417          }
418          else
419          {
420            for (int j = 0; j < dimLen; j++)
421            {
422              if (!/*HC:*/float.IsNaN(aArray[j]))
423                tmp += aArray[j];
424            }
425            retArr[0] = tmp;
426          }
427        } else {
428          #region may run parallel
429          int i = 0, workItemCount = Settings.s_maxNumberThreads, workItemLength, workerCount = 1;
430          if (Settings.s_maxNumberThreads > 1 && maxRuns > 1
431            && numelA / 2 >= Settings.s_minParallelElement1Count) {
432
433            if (maxRuns >= Settings.s_maxNumberThreads
434              && numelA / Settings.s_maxNumberThreads > Settings.s_minParallelElement1Count) {
435              workItemLength = maxRuns / workItemCount;
436            } else {
437              workItemLength = maxRuns / 2;
438              workItemCount = 2;
439            }
440           
441          } else {
442            workItemLength = maxRuns;
443            workItemCount = 1;
444          }
445          Action<object> action = (data) => {
446            Tuple<int, int> range = (Tuple<int, int>)data;
447            int from = range.Item1, to = range.Item2;
448            for (int c = from; c < to; c++) {
449              int pos = (int)(((long)dimLen * c * inc) % modHelp);
450              long posOut = ((long)c * incOut);
451              if (posOut > modOut)
452                posOut = ((posOut - 1) % modOut) + 1;
453             
454              float tmp = 0;
455              int end = pos + dimLen * inc;
456              if (computeMean)
457              {
458                int cnt = 0;
459                for (int j = pos; j < end; j += inc)
460                {
461                  if (!/*HC:*/float.IsNaN(aArray[j]))
462                  {
463                    tmp += aArray[j];
464                    cnt++;
465                  }
466                }
467                if (cnt == 0)
468                  retArr[posOut] = float.NaN;
469                else
470                  retArr[posOut] = tmp / cnt;
471              }
472              else
473              {
474                 
475                for (int j = pos; j < end; j += inc)
476                {
477                  if (!/*HC:*/float.IsNaN(aArray[j]))
478                    tmp += aArray[j];
479                }
480                retArr[posOut] = tmp;
481              }
482            }
483            System.Threading.Interlocked.Decrement(ref workerCount);
484          };
485          for (; i < workItemCount - 1; i++) {
486            Interlocked.Increment(ref workerCount);
487
488            ILThreadPool.QueueUserWorkItem(i,action, Tuple.Create(i * workItemLength, (i + 1) * workItemLength));
489          }
490          action(Tuple.Create(i * workItemLength, maxRuns));
491          ILThreadPool.Wait4Workers(ref workerCount);
492          #endregion
493        }
494        return array(retArr, newDims);
495      }
496    }
497    /// <summary>
498    /// Sum elements along first non singleton dimension ignoring NaN values
499    /// </summary>
500    /// <param name="A">Input array</param>
501    /// <param name="dim">[Optional] Index of the dimension to operate along. If omitted operates along the first non singleton dimension (i.e. != 1).</param>
502    /// <returns>Sum of elements along specified of first non singleton dimension, ignoring nan values</returns>
503    /// <remarks><para>The array returned will have the same size as <paramref name="A"/>, with the specified or first non singleton dimension
504    /// reduced to the length 1. It will contain the sum of all elements along that dimension after removing NaN values respectively. </para>
505    /// <para>If A contains an all NaN vector along <paramref name="dim"/> ,
506    /// the resulting sum will be 0 - not NaN! This corresponds to the sum of an empty vector.</para></remarks>
507    public static ILRetArray<complex> nansum(ILInArray<complex> A, int dim = -1)
508    {
509      if (dim < 0)
510        dim = A.Size.WorkingDimension();
511      return nansum_internal(A, dim, false);
512    }
513   
514    /// <summary>
515    /// Depending on settings, calculate nansum or nanmean
516    /// </summary>
517    private static ILRetArray<complex> nansum_internal (ILInArray<complex> A, int dim, bool computeMean) {
518      using (ILScope.Enter(A)) {
519        if (dim >= A.Size.NumberOfDimensions)
520           return A.C;
521       
522        if (A.IsScalar) {
523          return array<complex>(new complex[1] { A.GetValue(0) }, 1, 1);
524        }
525       
526        if (A.S[dim] == 1) return A.C;
527
528        int[] newDims = A.S.ToIntArray();
529        newDims[dim] = 1;
530        ILSize retDimension = new ILSize(newDims);
531
532        if (A.IsEmpty)
533          return empty<complex>(retDimension);
534
535        complex[] retArr = ILMemoryPool.Pool.New<complex>(retDimension.NumberOfElements);
536
537        int inc = A.Size.SequentialIndexDistance(dim);
538        int dimLen = A.Size[dim];
539        int maxRuns = retDimension.NumberOfElements;
540        int modHelp = A.Size.NumberOfElements - 1;
541        int modOut = retDimension.NumberOfElements - 1;
542        int incOut = retDimension.SequentialIndexDistance(dim);
543        int numelA = A.S.NumberOfElements;
544       
545        complex[] aArray = A.GetArrayForRead();
546        if (maxRuns == 1) {
547         
548          complex tmp = 0;
549          if (computeMean)
550          {
551            int cnt = 0;
552            for (int j = 0; j < dimLen; j++)
553            {
554              if (!/*HC:*/complex.IsNaN(aArray[j]))
555              {
556                tmp += aArray[j];
557                cnt++;
558              }
559            }
560            if (cnt == 0)
561              retArr[0] = complex.NaN;
562            else
563              retArr[0] = tmp / cnt;
564          }
565          else
566          {
567            for (int j = 0; j < dimLen; j++)
568            {
569              if (!/*HC:*/complex.IsNaN(aArray[j]))
570                tmp += aArray[j];
571            }
572            retArr[0] = tmp;
573          }
574        } else {
575          #region may run parallel
576          int i = 0, workItemCount = Settings.s_maxNumberThreads, workItemLength, workerCount = 1;
577          if (Settings.s_maxNumberThreads > 1 && maxRuns > 1
578            && numelA / 2 >= Settings.s_minParallelElement1Count) {
579
580            if (maxRuns >= Settings.s_maxNumberThreads
581              && numelA / Settings.s_maxNumberThreads > Settings.s_minParallelElement1Count) {
582              workItemLength = maxRuns / workItemCount;
583            } else {
584              workItemLength = maxRuns / 2;
585              workItemCount = 2;
586            }
587           
588          } else {
589            workItemLength = maxRuns;
590            workItemCount = 1;
591          }
592          Action<object> action = (data) => {
593            Tuple<int, int> range = (Tuple<int, int>)data;
594            int from = range.Item1, to = range.Item2;
595            for (int c = from; c < to; c++) {
596              int pos = (int)(((long)dimLen * c * inc) % modHelp);
597              long posOut = ((long)c * incOut);
598              if (posOut > modOut)
599                posOut = ((posOut - 1) % modOut) + 1;
600             
601              complex tmp = 0;
602              int end = pos + dimLen * inc;
603              if (computeMean)
604              {
605                int cnt = 0;
606                for (int j = pos; j < end; j += inc)
607                {
608                  if (!/*HC:*/complex.IsNaN(aArray[j]))
609                  {
610                    tmp += aArray[j];
611                    cnt++;
612                  }
613                }
614                if (cnt == 0)
615                  retArr[posOut] = complex.NaN;
616                else
617                  retArr[posOut] = tmp / cnt;
618              }
619              else
620              {
621                 
622                for (int j = pos; j < end; j += inc)
623                {
624                  if (!/*HC:*/complex.IsNaN(aArray[j]))
625                    tmp += aArray[j];
626                }
627                retArr[posOut] = tmp;
628              }
629            }
630            System.Threading.Interlocked.Decrement(ref workerCount);
631          };
632          for (; i < workItemCount - 1; i++) {
633            Interlocked.Increment(ref workerCount);
634
635            ILThreadPool.QueueUserWorkItem(i,action, Tuple.Create(i * workItemLength, (i + 1) * workItemLength));
636          }
637          action(Tuple.Create(i * workItemLength, maxRuns));
638          ILThreadPool.Wait4Workers(ref workerCount);
639          #endregion
640        }
641        return array(retArr, newDims);
642      }
643    }
644
645#endregion HYCALPER AUTO GENERATED CODE
646}
647}
Note: See TracBrowser for help on using the repository browser.