import Foundation extension Sequence where Element == Float { func mean() -> Float { var sum: Float = 0 var count: Int = 0 for value in self { sum += value count += 1 } return count == 0 ? .nan : sum / Float(count) } func onlyNaN() -> Bool { return first(where: {!$0.isNaN}) == nil } func hasValidData() -> Bool { return !onlyNaN() } } extension Array where Element == Float { func max(by: Int) -> [Float] { return stride(from: 0, through: count-by, by: by).map { i in return self[i.. [Float] { return stride(from: 0, through: count-by, by: by).map { i in return self[i.. [Float] { return stride(from: 0, through: count-by, by: by).map { i in return self[i.. [Float] { return stride(from: Float(0), through: Float(count)-by, by: by).map { (i: Float) -> Float in return self[Int(roundf(i)).. [Float] { return stride(from: 0, through: count-by, by: by).map { i in return self[i.. [Float] { return stride(from: 0, through: count-by, by: by).map { i in if i == 0 { return .nan } return self[i-by.. [Float] { let roundExponent = powf(10, Float(digits)) return map { return Foundation.round($0 * roundExponent) / roundExponent } } func containsNaN() -> Bool { return first(where: {$0.isNaN}) != nil } mutating func fillWithNaNs() { for i in self.indices { self[i] = .nan } } } extension Array where Element == Float { /// Shift longitudes by 180° and flip south.north mutating func shift180LongitudeAndFlipLatitude(nt: Int, ny: Int, nx: Int) { precondition(nt * ny * nx == count) self.withUnsafeMutableBufferPointer { data in /// Data starts eastwards at 0°E... rotate to start at -180°E for t in 0..