Olasılık dağılımları için bir API uygulama


9

Giriş

Bu meydan okumada, göreviniz birlikte basit olasılık dağılımları için kullanılabilir bir mini kütüphane oluşturan basit fonksiyonların bir koleksiyonunu uygulamaktır. İnsanların burada kullanmayı sevdikleri daha ezoterik dillerden bazılarını barındırmak için aşağıdaki uygulamalar kabul edilebilir:

  1. Adlandırılmış işlevlerin (veya en yakın eşdeğerlerinin) bir koleksiyonunu tanımlayan bir kod snippet'i.
  2. Adlandırılmış veya anonim işlevlere (veya en yakın eşdeğerlere) göre değerlendirilen bir ifade koleksiyonu.
  3. Birden fazla adlandırılmış veya anonim işleve (veya en yakın eşdeğere) göre değerlendirilen tek bir ifade.
  4. Komut satırından, STDIN veya en yakın eşdeğerden girişler alan ve STDOUT veya en yakın eşdeğerden çıkış alan bağımsız programlar topluluğu.

Fonksiyonlar

İsterseniz daha kısa isimler kullanarak aşağıdaki işlevleri yerine getireceksiniz.

  1. uniformgirdi olarak iki kayan nokta sayısı alır ave beşit dağılımı verir [a,b]. Bunu varsayabilirsiniz a < b; dava a ≥ btanımsız.
  2. blendgirdilerin üç olasılık dağılımları olarak alır P, Qve R. Bir olasılık dağılımını verir Sdeğerleri çizer x, yve zgelen P, Qve R, sırası ile, ve ürünler yhalinde x ≥ 0ve zeğer x < 0.
  3. overgiriş, bir kayan nokta sayısı olarak alır fve bir olasılık dağılımına Pve olasılığını verir x ≥ frastgele bir sayı için de geçerlidir xçekilir P.

Referans overiçin aşağıdaki gibi tanımlanabilir (sözde kodda):

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)

Verilen tüm olasılık dağılımlarının overkullanılarak oluşturulduğunu uniformve blendbir kullanıcının olasılık dağılımıyla yapacağı tek şeyin onu blendveya ' ye beslemek olduğunu varsayabilirsiniz over. Dağılımları temsil etmek için herhangi bir uygun veri türünü kullanabilirsiniz: sayılar, dizeler, özel nesneler, vb. Listeleri. Tek önemli şey API'nin düzgün çalışmasıdır. Ayrıca, aynı girdiler için her zaman aynı çıktıyı döndürme anlamında uygulamanız belirleyici olmalıdır .

Test senaryoları

Çıktı değerleriniz, bu test senaryolarında ondalık noktadan sonra en az iki basamaklı olmalıdır.

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
Bunları yapmak için yerleşik işlevleri kullanabilir miyiz?
Mutador

@ AndréMuta Mathematica'nın muhtemelen tüm bunlar için yerleşik olduğunu unuttum ... ama kurallara uydukları sürece onlara izin vereceğim.
Zgarb

BrainFuck'ta kayan nokta verilerinin nasıl temsil edileceğine dair öneriniz nedir?
Kusur

@flawr Yerel kayan nokta numarası olmayan diller için, ardışık değerler arasında en fazla 0.001 fark olan -10.0 ve 10.0 (özel) arasındaki kayan noktalar için herhangi bir uygun kodlamayı kullanabilirsiniz. Çıktı, test durumları için 0,01 fark dahilinde doğru olmalıdır.
Zgarb

Yanıtlar:


1

CJam, 58 bayt

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

Bunlar yığın üzerinde çalışan postfix operatörleridir: 2.0 1.0 3.0 U Ois over(2, uniform(1, 3)).

Puan sayısı

{[\]}fonksiyonun kendisidir, :U;isme atar Uve açılır. Temelde bu fonksiyonun bir parçası değildir, bu yüzden skor 2 kuralını saymakla, sadece saymak zorunda kalırım {[\]}. Bbenzer şekilde tanımlanır.

Ancak, Oözyinelemeli ve bir ad belirtmezsem, tekrarlamanın yolu yoktur. Yani burada, :O;parçayı saymaya meyilli olurum . Sonra 5+5+48=58puanım toplam bayttır.

açıklama

Uiki bağımsız değişkenin çıkar ve ters bir çift yapar: a b => [b a].

Büç argüman çıkar ve döndürülmüş sırayla üçlü yapar: a b c => [b c a].

Oyapısı aşağıdaki gibidir:

{             }: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 Δ.

Alt program Γ üniforma dağılımları ele alır:

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)))

Alt program bl karışık dağılımları ele alır:

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

Ruby, 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)}

Tanımlar üç lambda'lar, u, b, ve o. uve bsırasıyla iki elemanlı ve üç elemanlı diziler oluşturun. oiki elementli bir dizinin tekdüze bir dağılım olduğunu ve üç elementli bir dizinin üç dağılımın bir karışımı olduğunu varsayar. İkinci durumda kendini tekrar tekrar çağırır.


2

MATLAB, 73

MATLAB'da küçük bir "işlevsel programlama" zamanı. Bunlar 3 anonim işlevdir. Düzgün ve harman, örneklerle aynı şekilde adlandırılır, ancak overargümanlar için değiştirilmelidir. overİlk iki geri dönüş işlevinden beri gerçekten ihtiyacım yok , ama formalite fevalbir işlevi çağırabilecek bir işlevdir.

%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

Şimdi MATLAB'ın ayrıştırma ve değerlendirme sistemi en azını söylemekte biraz sakat. Bir işlevden döndürülen bir işlevi doğrudan çağırmanıza izin vermez. Bunun yerine, öncelikle sonucu bir değişkene kaydetmeniz gerekir. 4. örnek şu şekilde yapılabilir:

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)

Bununla birlikte, fevaltüm işlevleri çağırmak için kullanarak bunu aşmak mümkündür. Aşağıdaki tanımlar kullanılırsa, örnekler tam olarak yazıldığı gibi değerlendirilebilir.

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)

Fonksiyonlar fonksiyonlar ... ne kadar sapkın!
Luis Mendo

1

Mathematica, 129 116 bayt

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

u, bVe ovardır uniform, blendve overstandart fonksiyonları üzerinde respectively.Wrapper. Leri \uF3D23 baytlık karakterle değiştirin. Sadece döner 0ve 11, 4 ve 7 vakaları için.


1

Python, 146 bayt

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)

Histokratın Ruby cevabı ile aynı strateji, ancak Python'da. Z-birleştiricisi olmadan (pahalıya mal olacak) özyineleme yapmak xve 2- ve 3 uzunluklu bağımsız değişken gruplarını ( ve bağımsız değişkenleri) ydeğerlendiren yardımcı işlevler olarak tanımlanır .overuniformblend

İdeone üzerinde test vakaları


0

Matlab, 104 bayt

Umarım bu hala geçerlidir, çünkü bu sadece [-10,10] 'da destekli dağıtımlar için çalışır; bu da kayan nokta desteği olmayan diller için bir gerekliliktir. Destek vektörü ve doğruluğu sadece karşılık gelen sayılar değiştirilerek kolayca ayarlanabilir. u,o,biçindir uniform,blend,over. Pdf sadece ayrık bir vektör olarak temsil edilir. Bu yaklaşımın diğer dillere kolayca aktarılabileceğini düşünüyorum.

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;

Önce bu işlevleri tanımlarsanız ve ardından yalnızca bu kodu yapıştırırsanız bunları test edebilirsiniz:

[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'ın FP desteği var, bu yüzden bunun geçersiz olacağını düşünüyorum.
LegionMammal978

Matlab'ın doğal olarak kayan nokta sayılarını desteklediği için buna izin vermekten çekinmeyin. Değiştirmek Eğer Xve Dbirlikte MIN_FLOATve MAX_FLOAT(veya Matlab onları çağırır ne olursa olsun), o zaman bu geçerli bir yaklaşımdır.
Zgarb

Evet, Ouse olabilir realmax/ realmin, sen bile yeterli bellek varsa tüm kayan noktalı sayı Throu giden bir vektör yapabiliriz.
Kusur
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.