Julia on Float vs. Octave on Float

时间:2015-11-17 08:38:54

标签: julia numeric

版本: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),代码崩溃。拥有更多经验的人可以查看代码并说出我应该改进/改变的内容吗?

4 个答案:

答案 0 :(得分:3)

虽然BigIntBigFloat是必要时的优秀工具,但通常应避免使用它们,因为它们过度而且速度慢。

在这种情况下,问题确实是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)

虽然BigIntBigFloat可以在这里使用,但它们是严重的过度杀伤力。真正的问题是你在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