gpt4 book ai didi

arrays - F# 比较两个数组是否相等到指定的精度级别

转载 作者:行者123 更新时间:2023-12-05 09:25:15 26 4
gpt4 key购买 nike

这是我要翻译的 C# 代码:

public bool equals(Matrix matrix, int precision)
{

if (precision < 0)
{
throw new MatrixError("Precision can't be a negative number.");
}

double test = Math.Pow(10.0, precision);
if (double.IsInfinity(test) || (test > long.MaxValue))
{
throw new MatrixError("Precision of " + precision
+ " decimal places is not supported.");
}

precision = (int)Math.Pow(10, precision);

for (int r = 0; r < this.Rows; r++)
{
for (int c = 0; c < this.Cols; c++)
{
if ((long)(this[r, c] * precision) != (long)(matrix[r, c] * precision))
{
return false;
}
}
}

return true;
}

Here is what I have so far:

type Matrix(sourceMatrix:double[,]) =
let rows = sourceMatrix.GetUpperBound(0) + 1
let cols = sourceMatrix.GetUpperBound(1) + 1
let matrix = Array2D.zeroCreate<double> rows cols
do
for i in 0 .. rows - 1 do
for j in 0 .. cols - 1 do
matrix.[i,j] <- sourceMatrix.[i,j]
///The number of Rows in this Matrix.
member this.Rows = rows

///The number of Columns in this Matrix.
member this.Cols = cols

member this.Equals(matrix:Matrix, precision:int) =
if(precision < 0) then raise (new ArgumentOutOfRangeException("Precision can't be a negative number."))
let (test:double) = Math.Pow(10.0, double(precision))
if(System.Double.IsInfinity(test) || (test > double(System.Int32.MaxValue))) then raise (new ArgumentOutOfRangeException("Precision of " + precision.ToString() + " decimal places is not supported."))
let precision = int(Math.Pow(10.0, double(precision)))

如您所见,到目前为止我所写的内容充满了类型转换,这可能意味着我的代码没有按照应有的方式编写。未完成的部分需要方法返回第一个元素,该元素在评估到一定精度时返回 false。我确信必须有一些优雅的 F# 代码来实现这一点,显然我离它还差得很远。我试图弄清楚 Array2D 类是否有一些方法可以让我这样做,但如果有的话我找不到它。我知道 PowerPack Matrix 类并将最终使用它,但现在我正在尝试通过将我理解的 C# 代码翻译成 F# 来学习 F#。显然说起来容易做起来难。 :) 我相信我已经在我正在创建的类型中添加了所有相关的 F# 代码。如果我遗漏了什么,请告诉我。

最佳答案

一种可能不会非常有效的优雅和高级的写法是使用惰性序列表达式:

seq { for r in 0 .. this.Rows - 1 do
for c in 0 .. this.Cols - 1 do
if <your condition goes here> then
yield false}
|> Seq.forall id

想法是,只要矩阵中的第一个元素符合条件,序列就会生成 false。然后 Seq.forall 函数立即返回 false(并停止迭代序列)。

在实践中,您可能需要使用递归函数来实现它以提高效率。这不是特别好(因为在 F# 中无法打破循环),但您不应该经常需要这样的代码:

let rec loopRows r = 
let rec loopCols c =
if c = this.Cols then true
elif <your condition goes here> then false
else loopCols (c + 1)
if r = this.Rows then true // Processed all rows
elif not (loopCols 0) then false // Nonequal element in this row
else loopRows (r + 1) // Continue looping

loopRows 0

关于arrays - F# 比较两个数组是否相等到指定的精度级别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5215675/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com