확률 분포를위한 API 구현


9

소개

이 과제에서는 간단한 확률 분포에 사용할 수있는 미니 라이브러리를 함께 구성하는 간단한 함수 모음을 구현해야합니다. 사람들이 여기에서 사용하기에 더 난해한 언어를 수용하기 위해 다음과 같은 구현이 허용됩니다.

  1. 명명 된 함수 (또는 가장 가까운 함수)의 컬렉션을 정의하는 코드 스 니펫.
  2. 명명 된 함수 또는 익명 함수 (또는 가장 가까운 함수)로 평가되는 표현식 모음입니다.
  3. 여러 개의 명명 된 함수 나 익명 함수 (또는 가장 가까운 함수)로 평가되는 단일 표현식입니다.
  4. 명령 행, STDIN 또는 가장 유사한 항목에서 입력을 가져 와서 STDOUT 또는 가장 유사한 항목으로 출력하는 독립 프로그램의 모음입니다.

기능

원하는 경우 더 짧은 이름을 사용하여 다음 기능을 구현해야합니다.

  1. uniform입력으로 두 개의 부동 소수점 숫자를 소요 a하고 b, 반환에 균일 한 분포를 [a,b]. 당신은 그것을 가정 할 수 있습니다 a < b; 사건 a ≥ b은 정의되지 않았다.
  2. blend입력 세 확률 분포로 얻어 P, QR. 이 확률 분포 반환 S값을 무 x, yzP, QR각각 수율 y경우 x ≥ 0z경우 x < 0.
  3. over부동 소수점 숫자 f와 확률 분포 를 입력으로 취하고 에서 추출한 난수에 대한 P확률을 반환합니다 .x ≥ fxP

참고 over로 다음과 같이 정의 할 수 있습니다 (의사 코드로).

over(f, uniform(a, b)):
    if f <= a: return 1.0
    else if f >= b: return 0.0
    else: return (b - f)/(b - a)

over(f, blend(P, Q, R)):
    p = over(0.0, P)
    return p*over(f, Q) + (1-p)*over(f, R)

주어진 모든 확률 분포가 있다고 가정 할 수 있습니다 over사용하여 구성되어 uniformblend, 그리고 사용자가 확률 분포와 함께 할 것입니다 유일한인지에 공급하는 blendover. 편리한 데이터 유형을 사용하여 숫자, 문자열, 사용자 정의 객체 등의 분포를 나타내는 분포를 나타낼 수 있습니다. 유일한 중요한 것은 API가 올바르게 작동한다는 것입니다. 또한 동일한 입력에 대해 항상 동일한 출력을 반환한다는 의미에서 구현 결정 론적 이어야합니다 .

테스트 사례

이러한 테스트 사례에서 출력 값은 소수점 다음 두 자리 이상으로 정확해야합니다.

over(4.356, uniform(-4.873, 2.441)) -> 0.0
over(2.226, uniform(-1.922, 2.664)) -> 0.09550806803314438
over(-4.353, uniform(-7.929, -0.823)) -> 0.49676329862088375
over(-2.491, uniform(-0.340, 6.453)) -> 1.0
over(0.738, blend(uniform(-5.233, 3.384), uniform(2.767, 8.329), uniform(-2.769, 6.497))) -> 0.7701533851999125
over(-3.577, blend(uniform(-3.159, 0.070), blend(blend(uniform(-4.996, 4.851), uniform(-7.516, 1.455), uniform(-0.931, 7.292)), blend(uniform(-5.437, -0.738), uniform(-8.272, -2.316), uniform(-3.225, 1.201)), uniform(3.097, 6.792)), uniform(-8.215, 0.817))) -> 0.4976245638164541
over(3.243, blend(blend(uniform(-4.909, 2.003), uniform(-4.158, 4.622), blend(uniform(0.572, 5.874), uniform(-0.573, 4.716), blend(uniform(-5.279, 3.702), uniform(-6.564, 1.373), uniform(-6.585, 2.802)))), uniform(-3.148, 2.015), blend(uniform(-6.235, -5.629), uniform(-4.647, -1.056), uniform(-0.384, 2.050)))) -> 0.0
over(-3.020, blend(blend(uniform(-0.080, 6.148), blend(uniform(1.691, 6.439), uniform(-7.086, 2.158), uniform(3.423, 6.773)), uniform(-1.780, 2.381)), blend(uniform(-1.754, 1.943), uniform(-0.046, 6.327), blend(uniform(-6.667, 2.543), uniform(0.656, 7.903), blend(uniform(-8.673, 3.639), uniform(-7.606, 1.435), uniform(-5.138, -2.409)))), uniform(-8.008, -0.317))) -> 0.4487803553043079

2
내장 함수를 사용하여 만들 수 있습니까?
Mutador

@ AndréMuta 나는 Mathematica가 아마도이 모든 것을 위해 내장되어 있다는 것을 잊었다. 그러나 그들이 규칙을 따르는 한 그것들을 허용 할 것이다.
Zgarb

BrainFuck에서 부동 소수점 데이터를 표현하는 방법에 대한 제안은 무엇입니까?
flawr

@flawr 네이티브 부동 소수점 숫자가없는 언어의 경우 연속 값 사이에 최대 0.001 차이가있는 -10.0에서 10.0 (제외) 사이의 부동 소수점에 편리한 인코딩을 사용할 수 있습니다. 테스트 사례에 대한 출력은 0.01 차이 내에서 정확해야합니다.
Zgarb

답변:


1

CJam, 58 바이트

{[\]}:U;
{[@]}:B;
{_,2={~1$-@@-\/0e>1e<}{6Yb@f*\.{O})[_1@-].*:+}?}:O;

이들은 스택에서 작동하는 접미사 연산자입니다 : 2.0 1.0 3.0 U Ois over(2, uniform(1, 3)).

점수 카운트

{[\]}함수 자체이며 :U;이름에 할당 U하고 팝업합니다. 기본적으로 이것은 함수의 일부가 아니므로 점수 계산 규칙 2로 계산해야합니다 {[\]}. B비슷하게 정의됩니다.

그러나 O재귀 적이며 이름을 지정하지 않으면 재귀 할 수있는 방법이 없습니다. 그래서 여기, 나는 그 :O;부분 을 세는 경향이 있습니다 . 그런 다음 내 점수는 5+5+48=58총 바이트입니다.

설명

U두 개의 인수를 표시하고 반대 순서로 쌍을 만듭니다 a b => [b a].

B세 개의 인수를 표시하고 회전 순서대로 트리플을 만듭니다 a b c => [b c a].

O구조는 다음과 같습니다.

{             }:O;   Define O as this function:
 _,2=        ?       If the argument list's length is 2:
     {~Γ}            Append the list to the stack and execute subprogram Γ.
         {~Δ}        Else, do the same, but execute subprogram Δ.

서브 프로그램 Γ 는 균일 분포를 처리합니다.

Executed ops      Explanation   Stack contents
============      ===========   ==============
                  Initial       f; b; a
1$                Copy b        f; b; a; b
  -               Difference    f; b; (a-b)
   @@             Rotate x2     (a-b); f, b
     -            Difference    (a-b); (f-b)
      \/          Flip divide   (f-b)/(a-b)
        0e>       Clamp low     max(0, (f-b)/(a-b))
           1e<    Clamp high    min(1, max(0, (f-b)/(a-b)))

서브 프로그램 Δ 는 혼합 분포를 처리합니다.

Executed ops              Explanation    Stack contents
============              ===========    ==============
                          Initial        f; [Q R P]
6Yb                       Push [1,1,0]   f; [Q R P]; [1 1 0]
   @                      Rotate         [Q R P]; [1 1 0]; f
    f*                    Multiply each  [Q R P]; [f f 0]
      \                   Swap           [f f 0]; [Q R P]
       .{O}               Pairwise O     [q r p]
           )              Uncons         [q r] p
            [_1@-]        [p, 1-p]       [q r] [p 1-p]
                  .*:+    Dot product    q*p+r*(1-p)

2

루비, 103

u=b=->*a{a}
o=->f,d{d[2]?(p=o[0,d[0]])*o[f,d[1]]+(1-p)*o[f,d[2]]:(f<a=d[0])?1:(f>b=d[1])?0:(b-f)/(b-a)}

정의 세 람다, u, b,와 o. u그리고 b단지 각각 두 개의 요소 및 3 요소 배열을 만들 수 있습니다. o2 요소 배열이 균일 분포이고 3 요소 배열이 세 분포의 혼합이라고 가정합니다. 후자의 경우에는 재귀 적으로 호출됩니다.


2

MATLAB, 73

MATLAB의 "기능 프로그래밍"에 대한 시간입니다. 이들은 3 가지 익명 함수입니다. 유니폼과 블렌드는 예제와 같은 방식으로 불려지지만 over인수는 서로 바꿔야합니다. over처음 두 반환 함수 이후로는 실제로 필요하지 않지만 공식적 feval으로 함수를 호출 할 수있는 함수입니다.

%uniform
@(a,b)@(x)(x<b)*min(1,(b-x)/(b-a))
%blend
@(P,Q,R)@(x)P(0)*(Q(x)-R(x))+R(x)
%over
@feval

이제 MATLAB의 파싱 및 평가 시스템은 가장 말이 안됩니다. 함수에서 반환 된 함수를 직접 호출 할 수 없습니다. 대신, 먼저 결과를 변수에 저장해야합니다. 네 번째 예는 다음과 같이 수행 할 수 있습니다.

x=uniform(-5.233,3.384);y=uniform(2.767,8.329);z=uniform(-2.769,6.497);over(blend(x,y,z),0.738)

그러나 feval모든 함수를 호출 하는 데 사용 하면 이 문제를 해결할 수 있습니다. 다음과 같은 정의가 사용되는 경우, 작성된대로 정확하게 예제를 평가할 수 있습니다.

uniform=@(a,b)@(x)(x<b)*min(1,(b-x)/(b-a))
blend=@(P,Q,R)@(x)feval(P,0)*(feval(Q,x)-feval(R,x))+feval(R,x)
over=@(x,f)feval(f,x)

함수를 만드는 함수 .
Luis Mendo

1

Mathematica, 129116 바이트

u=UniformDistribution@{##}&;b=If[x<0,z,y]~TransformedDistribution~{x\uF3D2#,y\uF3D2#2,z\uF3D2#3}&;o=Probability[x>=#,x\uF3D2#2]&

u, b하고 o있다 uniform, blend그리고 over표준 기능을 통해 respectively.Wrapper. \uF3D2s를 3 바이트 문자로 바꿉니다 . 반환 0하고 1사례 1, 4 및 7의 경우.


1

파이썬, 146 바이트

u=lambda*a:a
b=u
x=lambda f,a,b:[int(f<=a),(b-f)/(b-a)][a<f<b]
y=lambda f,p,q,r:o(0,p)*o(f,q)+(1-o(0,p))*o(f,r)
o=lambda f,p:[x,y][len(p)-2](f,*p)

histocrat의 Ruby 답변과 같은 전략이지만 Python에서는 A ~ Z-콤비 (비용이 많이 드는 것이다)하지 않고 재귀를 수행, xy평가 도우미 함수로 정의된다 over(2, 3 길이 인수 튜플 uniformblend각각 인수).

이데온의 테스트 사례


0

Matlab, 104 바이트

부동 소수점을 지원하지 않는 언어에 대한 요구 사항 인 [-10,10]을 지원하는 배포판에서만 작동하므로 이것이 여전히 유효하기를 바랍니다. 대응하는 숫자 만 변경하면 서포트 벡터와 정확도를 쉽게 조정할 수 있습니다. u,o,b입니다 uniform,blend,over. pdf는 이산 벡터로 표시됩니다. 이 접근법은 다른 언어로 쉽게 옮길 수 있다고 생각합니다.

D=1e-4;X=-10:D:10;
u=@(a,b)(1/(b-a))*(a<X&X<b);
o=@(x,d)sum(d.*(X>x))*D;
b=@(p,q,r)o(0,p).*q+(1-o(0,p)).*r;

해당 함수를 먼저 정의한 다음이 코드를 붙여 넣으면 테스트 할 수 있습니다.

[o(4.356, u(-4.873, 2.441)) , 0.0;
o(2.226, u(-1.922, 2.664)) , 0.09550806803314438;
o(-4.353, u(-7.929, -0.823)) , 0.49676329862088375;
o(-2.491, u(-0.340, 6.453)) , 1.0;
o(0.738, b(u(-5.233, 3.384), u(2.767, 8.329), u(-2.769, 6.497))) , 0.7701533851999125;
o(-3.577, b(u(-3.159, 0.070), b(b(u(-4.996, 4.851), u(-7.516, 1.455), u(-0.931, 7.292)), b(u(-5.437, -0.738), u(-8.272, -2.316), u(-3.225, 1.201)), u(3.097, 6.792)), u(-8.215, 0.817))) , 0.4976245638164541;
o(3.243, b(b(u(-4.909, 2.003), u(-4.158, 4.622), b(u(0.572, 5.874), u(-0.573, 4.716), b(u(-5.279, 3.702), u(-6.564, 1.373), u(-6.585, 2.802)))), u(-3.148, 2.015), b(u(-6.235, -5.629), u(-4.647, -1.056), u(-0.384, 2.050)))) , 0.0;
o(-3.020, b(b(u(-0.080, 6.148), b(u(1.691, 6.439), u(-7.086, 2.158), u(3.423, 6.773)), u(-1.780, 2.381)), b(u(-1.754, 1.943), u(-0.046, 6.327), b(u(-6.667, 2.543), u(0.656, 7.903), b(u(-8.673, 3.639), u(-7.606, 1.435), u(-5.138, -2.409)))), u(-8.008, -0.317))) , 0.4487803553043079]

Matlab은 FP를 지원하므로 이것이 유효하지 않다고 생각합니다.
LegionMammal978

Matlab은 기본적으로 부동 소수점 숫자를 지원하기 때문에 이것을 망설입니다. 당신이 대체 할 수있는 경우 XDMIN_FLOATMAX_FLOAT(또는 매트랩을 호출 무엇이든), 다음이 올바른 접근 방법이다.
Zgarb

예, realmax/ realmin를 사용하지 않을 수 있습니다. 메모리가 충분하면 모든 부동 소수점 수를 통과 하는 벡터를 만들 수도 있습니다.
flawr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.