版本:v“0.5.0-dev + 1259”
上下文:目标是计算与VC维n
相关的给定数据点dvc
上的Rademacher惩罚界限和{{1}表示的概率}
请考虑朱莉娅代码:
delta
和Octave / Matlab中的等效代码:
#Growth function on any n points with respect to VC-dimmension
function mh(n, dvc)
if n <= dvc
2^n #A
else
n^dvc #B
end
end
#Rademacher penalty bound
function rademacher_penalty_bound(n::Int, dvc::Int, delta::Float64)
sqrt((2.0*log(2.0*n*mh(n,dvc)))/n) + sqrt((2.0/n)*log(1.0/delta)) + 1.0/n
end
问题: 当我开始测试时,我收到以下结果:
朱莉娅第一次:
%Growth function on n points for a give VC dimmension (dvc)
function md = mh(n, dvc)
if n <= dvc
md= 2^n;
else
md = n^dvc;
end
end
%Rademacher penalty bound
function epsilon = rademacher_penalty_bound (n, dvc, delta)
epsilon = sqrt ((2*log(2*n*mh(n,dvc)))/n) + sqrt((2/n)*log(1/delta)) + 1/n;
end
现在Octave:
julia> rademacher_penalty_bound(50, 50, 0.05) #50 points
1.619360057204432
julia> rademacher_penalty_bound(500, 50, 0.05) #500 points
ERROR: DomainError:
[inlined code] from math.jl:137
in rademacher_penalty_bound at none:2
in eval at ./boot.jl:264
问题:根据Noteworthy differences from MATLAB我认为我遵循经验法则(“没有小数点的文字数字(如42)创建整数而不是浮点数... “)。当点数超过51时(octave:17> rademacher_penalty_bound(50, 50, 0.05)
ans = 1.6194
octave:18> rademacher_penalty_bound(500, 50, 0.05)
ans = 1.2387
中的行#B),代码崩溃。拥有更多经验的人可以查看代码并说出我应该改进/改变的内容吗?
答案 0 :(得分:3)
虽然BigInt
和BigFloat
是必要时的优秀工具,但通常应避免使用它们,因为它们过度而且速度慢。
在这种情况下,问题确实是Octave(将所有内容视为浮点数)和Julia之间的区别,例如2作为整数。
所以要做的第一件事就是在Julia中使用浮点数:
function mh(n, dvc)
if n <= dvc
2.0 ^ n
else
Float64(n) ^ dvc
end
end
这已经有所帮助,例如mh(50, 50)
有效。
然而,这个问题的正确解决方案是更仔细地查看代码,并意识到函数mh
仅发生在log
内:
log(2.0*n*mh(n,dvc))
我们可以使用对数定律将其重写为
log(2.0*n) + log_mh(n, dvc)
其中log_mh
是一个新函数,它返回mh
结果的对数。当然,这不应该直接写成log(mh(n, dvc))
,而是一个新功能:
function log_mh(n, dvc)
if n <= dvc
n * log(2.0)
else
dvc * log(n)
end
end
通过这种方式,您可以使用大量数字而不会溢出。
答案 1 :(得分:3)
虽然BigInt
和BigFloat
可以在这里使用,但它们是严重的过度杀伤力。真正的问题是你在Julia中进行整数求幂,在Octave / Matlab中进行浮点求幂。因此,您只需要将mh
更改为使用浮点数而不是指数的整数:
mh(n, dvc) = n <= dvc ? 2^float(n) : n^float(dvc)
rademacher_penalty_bound(n, dvc, δ) =
√((2log(2n*mh(n,dvc)))/n) + √(2log(1/δ)/n) + 1/n
通过这些定义,您可以获得与Octave / Matlab相同的结果:
julia> rademacher_penalty_bound(50, 50, 0.05)
1.619360057204432
julia> rademacher_penalty_bound(500, 50, 0.05)
1.2386545010981596
在Octave / Matlab中,即使你输入一个没有小数点的文字,你仍然得到一个浮点数 - 你必须对int类型进行显式转换。此外,Octave / Matlab中的取幂总是首先转换为float。在Julia中,x^2
相当于x*x
,它禁止转换为浮点数。
答案 2 :(得分:1)
我不知道获得BigFloat
的结果是否可以接受,但无论如何,在julia部分你可以使用BigInt
#Growth function on any n points with respect to VC-dimmension
function mh(n, dvc)
if n <= dvc
(BigInt(2))^n #A
else
n^dvc #B
end
end
#Rademacher penalty bound
function rademacher_penalty_bound(n::BigInt, dvc::BigInt, delta::Float64)
sqrt((2.0*log(2.0*n*mh(n,dvc)))/n) + sqrt((2.0/n)*log(1.0/delta)) + 1.0/n
end
rademacher_penalty_bound(BigInt(500), BigInt(500), 0.05)
# => 1.30055251010957621105182244420.....
答案 3 :(得分:-1)
因为默认情况下,Julia Int是&#34;机器尺寸&#34;整数,常见x86-64平台的64位整数,而Octave使用浮点。所以在Julia mh(500,50)溢出。您可以通过替换mh()来修复它,如下所示:
function mh(n, dvc)
n2 = BigInt(n) # Or n2 = Float64(n)
if n <= dvc
2^n2 #A
else
n2^dvc #B
end
end