/// <summary> /// Computes the average of each "feature" /// </summary> public static IArray<double> Averages(this IEnumerable<IEnumerable<double>> data) { var sums = new List<double>(data.First()); int count = 1, i; foreach (var enumerable in data.Skip(1)) { count++; i = 0; foreach (double d in enumerable) if (sums.Count <= i) break; else sums[i++] += d; for (int j = sums.Count - 1; j >= i; j--) sums.RemoveAt(j); } for (i = 0; i < sums.Count; i++) sums[i] /= count; return sums.AsIArray(); }
/// <summary> /// Groups entries using the sequences formed by their relative timestamps /// </summary> public static IEnumerable<IArrayView<EEGDataEntry>> SectionByStimulus(this IEnumerable<EEGDataEntry> entries) { if (entries.IsEmpty()) yield break; var section = new List<EEGDataEntry>() { entries.First() }; foreach (var entry in entries.Skip(1)) { if (entry.RelativeTimeStamp >= section.LastItem().RelativeTimeStamp) section.Add(entry); else { yield return section.AsIArray(); section = new List<EEGDataEntry>() { entry }; } } yield return section.AsIArray(); // return the last section }
/// <summary> /// Groups the entries by their respective time bins /// </summary> public static IArrayView<IArrayView<EEGDataEntry>> BinByTime(this IEnumerable<EEGDataEntry> entries, int binWidthMillis) { if (binWidthMillis <= 0) throw new ArgumentOutOfRangeException("binWidthMillis"); int baseTime = entries.First().TimeStamp; var bins = new List<IArrayView<EEGDataEntry>>(); var bin = new List<EEGDataEntry>(); foreach (var entry in entries) // add it the the current bin if (entry.TimeStamp < baseTime + binWidthMillis) bin.Add(entry); else // save the old bin and add it to the new one { bins.Add(bin.AsIArray()); while (true) { baseTime += binWidthMillis; if (entry.TimeStamp < baseTime + binWidthMillis) { bin = new List<EEGDataEntry>() { entry }; break; } bins.Add(Arrays.New<EEGDataEntry>(0)); // empty array } } // make sure to get the last bin! if (bin.Count > 0) bins.Add(bin.AsIArray()); return bins.AsIArray(); }