两个迭代器的交叉迭代
expand.grid()
,返回数据框[for in for in]
,返回 tuple 的迭代器crossing()
函数,返回数组的数组
using Test
using Printf
"""
通项公式为 1/k/(n+1)^(2k)
对此公式交叉遍历 k 向量和 n 向量,求和
"""
#> "通项公式为 1/k/(n+1)^(2k) \n对此公式交叉遍历 k 向量和 n 向量,求和\n"
function doubles(maxk::Int, maxn::Int)::Float64
v(k, n) = 1 / k / (big(n) + 1)^(2k) # 不转换Float64或BigInt会数值越界
v(k, n) for k ∈ 1:maxk for n ∈ 1:maxn] |> sum
[end
#> doubles (generic function with 1 method)
doubles(10, 1000)
#> 0.6921486500921955
function ifinrange(maxk::Int, maxn::Int, expect::Float64; tolerence=1e-6)::Bool
# println("Expect $(round(expect, digits = 12))")
@printf("Expect %.12f\n", expect)
= doubles(maxk, maxn)
actual @printf("Actual %.12f\n", actual)
abs(actual - expect) ≤ tolerence
end
#> ifinrange (generic function with 1 method)
@testset "fixed tests" begin
@test ifinrange(1, 10, 0.5580321939764581) == true
@test ifinrange(10, 1000, 0.6921486500921933) == true
end
#> Expect 0.558032193976
#> Actual 0.558032193976
#> Expect 0.692148650092
#> Actual 0.692148650092
#> Test Summary: | Pass Total
#> fixed tests | 2 2
#> Test.DefaultTestSet("fixed tests", Any[], 2, false, false)
library(tidyverse)
library(data.table)
library(magrittr)
<- function(maxk, maxn) {
doubles <- expand.grid(k = 1:maxk, n = 1:maxn) %>%
iterator as.data.table()
`:=`(v, 1/(k * (n + 1)^(2 * k)))][, v] %>%
iterator[, sum()
}
doubles(1, 10)
#> [1] 0.5580322
library(testthat)
<- function(maxk, maxn, expected) {
dotest <- doubles(maxk, maxn)
actual expect_equal(actual, expected, tol = 1e-06, scale = 1, info = "")
}test_that("test doubles", {
dotest(1, 10, 0.558032193976458)
dotest(10, 1000, 0.692148650092193)
dotest(10, 5000, 0.69294721240312)
})
#> Test passed 😀
const Vector = require("../src/JavaScript/toolkit/Vector");
const naturalSequence = Vector.naturalSequence;
const crossing = Vector.crossing;
const sum = require("../src/JavaScript/toolkit/Statistics").sum;
function doubles(K, N) {
const v = (k, n) => 1 / (k * Math.pow(n + 1, 2 * k));
const crossIterator = crossing(naturalSequence(K), naturalSequence(N));
return sum(crossIterator.map(paras => v(paras[0], paras[1])));
}
console.log(doubles(1, 10));
console.log(doubles(10, 1000));
#> 0.5580321939764581
#> 0.6921486500921895