Generics 如何统一这两个浮点函数?
我发现这是一种在一次数据传递中计算平均值和标准偏差的方法。我想让它为Generics 如何统一这两个浮点函数?,generics,f#,numbers,type-conversion,type-inference,Generics,F#,Numbers,Type Conversion,Type Inference,我发现这是一种在一次数据传递中计算平均值和标准偏差的方法。我想让它为float32和float工作,我正努力用通用数字来纠正这个错误 module Seq = let inline private avgVarianceReducer toFloat (count, oldM, oldS) x = if count = 1 then 2, x, LanguagePrimitives.GenericZero else
float32
和float
工作,我正努力用通用数字来纠正这个错误
module Seq =
let inline private avgVarianceReducer toFloat (count, oldM, oldS) x =
if count = 1 then
2, x, LanguagePrimitives.GenericZero
else
let meanFree = x - oldM
let newM = oldM + meanFree / (toFloat count)
count + 1, newM, oldS + meanFree * (x - newM)
let inline private avgVarianceWith toFloat source =
match source |> Seq.fold (avgVarianceReducer toFloat) (1, LanguagePrimitives.GenericZero, LanguagePrimitives.GenericZero) with
| 0, _, _ -> LanguagePrimitives.GenericZero, LanguagePrimitives.GenericZero
| 1, mean, _ -> mean, LanguagePrimitives.GenericZero
| n, mean, var -> mean, var / (n - 2 |> toFloat)
let avgVariance source = source |> avgVarianceWith float
let avgVariancef source = source |> avgVarianceWith float32
这对这两种类型都有效,但我有额外的avgVariancef
,而且在调用时必须选择正确的一种
对我来说,中心问题是在avgvarianceducer
中转换到正确类型的浮点,我通过传递正确的转换函数解决了这个问题。我尝试了op_Explicit
的方法,但失败了
有人有更优雅的解决方案吗?你试过了吗?
它包含一个通用数学模块和您正在寻找的通用显式函数
下面是您的代码的外观:
#r @"FsControl.dll"
#r @"FSharpPlus.dll"
open FSharpPlus
open FSharpPlus.Operators.GenericMath
module Seq =
let inline private avgVarianceReducer (count, oldM, oldS) (x:'R) =
if count = 1 then
2, x, 0G
else
let meanFree = x - oldM
let newM = oldM + meanFree / explicit count
count + 1, newM, oldS + meanFree * (x - newM)
let inline avgVariance source : 'R * 'R =
match source |> Seq.fold avgVarianceReducer (1, 0G, 0G) with
| 0, _, _ -> 0G, 0G
| 1, mean, _ -> mean, 0G
| n, mean, var -> mean, var / (n - 2 |> explicit)
// or if you prefer specific functions
let avgVarianceF32 source : float32 * float32 = avgVariance source
let avgVarianceF source : float * float = avgVariance source
// it will work with other types as well
let avgVarianceD source : decimal * decimal = avgVariance source
事实上,您不需要函数explicit
,您可以使用函数from integral
,它对数字更为具体
您还可以浏览库的源代码,并仅提取特定案例所需的代码。您尝试过吗?
它包含一个通用数学模块和您正在寻找的通用显式函数
下面是您的代码的外观:
#r @"FsControl.dll"
#r @"FSharpPlus.dll"
open FSharpPlus
open FSharpPlus.Operators.GenericMath
module Seq =
let inline private avgVarianceReducer (count, oldM, oldS) (x:'R) =
if count = 1 then
2, x, 0G
else
let meanFree = x - oldM
let newM = oldM + meanFree / explicit count
count + 1, newM, oldS + meanFree * (x - newM)
let inline avgVariance source : 'R * 'R =
match source |> Seq.fold avgVarianceReducer (1, 0G, 0G) with
| 0, _, _ -> 0G, 0G
| 1, mean, _ -> mean, 0G
| n, mean, var -> mean, var / (n - 2 |> explicit)
// or if you prefer specific functions
let avgVarianceF32 source : float32 * float32 = avgVariance source
let avgVarianceF source : float * float = avgVariance source
// it will work with other types as well
let avgVarianceD source : decimal * decimal = avgVariance source
事实上,您不需要函数explicit
,您可以使用函数from integral
,它对数字更为具体
您还可以浏览库的源代码,并仅提取特定案例所需的代码