MathTextOntology-pasek

Jak wiadomo ludzie mają geny. Gen genowi nie równy, jeden gen bywa silniejszy od drugiego, te słabsze nazywamy recesywnymi. Dzieci biorą sie z miłości, a od mamy i taty dostają po jednej kopii genu. Można zatem mieć od mamy gen recesywny, od taty dominujący, od mamy dominujący od taty dominujący i tak dalej. Osobniki które mają oba geny dominujące nazywamy homozygotą dominująca i bynajmniej nie oznacza to stwierdzenie że ktoś jest gejem uprawiającym sadomaso. Osobniki które mają oba geny recesywna – to homozygoty recesywne, a jeśli jeden z genów jest dominujący a jeden recesywny – mamy heterozygotę. To jaki gen mamy od kogo – mamy czy taty – nie ma znaczenia. W przypadku homozygot dominujących i heterozygot – zawsze wygra gen dominujący.

Jako przykład rozważmy kwestię koloru oczu. Dla uproszczenia załóżmy że oczy mogą być niebieskie lub brązowe i że nie ma innych możliwych kolorów oczu. Jak wiadomo gen odpowiedzialny za oczy niebieskie, oznaczmy go N, jest recesywny, zaś ten od oczu brązowych, B, jest dominujący. Jeśli zatem mama była heterozygotą, miała geny NB, zaś tata homozygotą dominującą, czyli miał geny BB, to dziecko może mieć jedynie następujące kombinacje genów – BN,BB – i w efekcie będzie miało oczy brązowe bo gen B w kombinacji z N zawsze wygrywa.

W dalszym tekście będą wstawki z sage – można je sobie wykonać na swoim sage w domu, albo użyć arkusza dostępnego na google drive ( można go zaimportować do jakiegoś publicznego serwera Sage)

Rozważmy populację osobników. Przypiszmy następująca numerację dla możliwych kombinacji genów: (0)BB,(1)BN,(2)NN  . Prawdopodobieństwo posiadania oczu o pewnym kolorze opiszemy wektorem P_{i}  o składowych i \in \{0,1,2 \}  . Oczywiście składowe wektora P_{i}    nie są niezależne, aby opisywały prawdopodobieństwo muszą sumować się do wartości 1.

Przykładowy wektor opisujący prawdopodobieństwo o którym mowa wygląda zatem tak:

sage: var('x,y,z,a,b,c,d,p_1,p_2,p_3,s')
(x, y, z, a, b, c, d, p_1, p_2, p_3, s)
sage: # osobnik ma geny - (0)BB,(1)BN,(2)NN (B-brązowy, N-niebieski)
sage: # oczy niebieskie tylko kiedy osobnik ma NN
sage: # Mamy stosowne prawdopodobieństwa występowania danej kombinacji genów w populacji:
sage: p_1=0;
sage: p_2=0.3;
sage: P=vector([p_1,p_2,1-p_1-p_2]);P
(0.000000000000000, 0.300000000000000, 0.700000000000000)

Tata i mama szukali sie latami, aż wreszcie trafili na siebie i miłość odebrała im rozum. Szansa że pan (0)BB  trafi na panią (1)BN  jest równa P_{0} P_{1}  a dla innych konfiguracji małżeństw analogicznie. Tym samym mamy 9 możliwości z których spora cześć oczywiście jest symetryczna pod względem wartości prawdopodobieństwa co wynika zarówno z symetrii sytuacji ( jest obojętne od kogo dostajemy geny) jak i z symetrii iloczynu.

Zdefiniujemy zatem stosowny sposób wyliczania prawdopodobieństwa kombinacji rodziców:

sage: #szansa że rodzice z genami i, j spotkają się jest przez wektor w którym
sage: #składowe są iloczynami stosownych prawdopodobieństw.
sage: def mariageprob(P):
...       #dl=len(wektor)
...       dl=3
...       R = matrix(RR,1,dl*dl,0)
...       for i in range(0,dl):
...           for j in range(0,dl):
...               R[0,dl*i+j] = P[i]*P[j];
...       return R
sage: mariageprob(P).transpose()
[ 0.000000000000000]
[ 0.000000000000000]
[ 0.000000000000000]
[ 0.000000000000000]
[0.0900000000000000]
[ 0.210000000000000]
[ 0.000000000000000]
[ 0.210000000000000]
[ 0.490000000000000]

W ostatnim obliczeniu dokonałem transpozycji nie tylko ze względu na wygodę wyświetlenia wyniku w wąskiej kolumnie wordpressa, ale i ze względu na dalszy tok obliczeń. Kiedy spotyka sie pani (1)BN  z panami o rozmaitych genotypach, kolor oczu potomstwa bynajmniej nie jest dowolny. Na przykład potomstwo z panem (1)BN  może odziedziczyć zestaw genów (0)BB  z prawdopodobieństwem 1/4  , lub (0)NN  z prawdopodobieństwem 1/4  , lub (1)BN  z prawdopodobieństwem 1/2  . Kombinacje dla innych konfiguracji seksualnych podaje macierz T_{i,j}  gdzie i,j \in \{ (0)BB,(1)BN,(2)NN \}  . Macierz ta jest stała i ma następująca formę:

sage: # macierz prawdopodobieństwa w kolumnach ma kombinacje osobników 
sage: # ( tj (0)BB(0)BB, (0)BB(1)BN, (0)BB(2)NN, (1)BN(0)BB,... itp)
sage: # wszystkie kombinacje z powtórzeniami.
sage: # w wierszach jest prawdopodobieństwo że z rodziców w kolumnie 
sage: # powstanie potomek o genotypie (i). 
sage: # np. w wierszu (0)BB i kolumnie (0)BB(2)NN jest prawdopodobieństwo 
sage: # że z rodziców (0)BB(2)NN będzie genotyp (0)BB = 0
sage: #macierz T jest macierzą probabilistyczną
sage: BB= [1,0.5,0,0.5,0.25,0,0,0,0]
sage: BN = [0,0.5,1,0.5,0.5,0.5,1,0.5,0]
sage: NN = [0,0,0,0,0.25,0.5,0,0.5,1]
sage: T = matrix([BB,BN,NN]);T

Prawdopodobieństwo że dzieci będą miały kombinację genów X zadane jest wzorem:

P(X) = P(X | Y,Z ) P(Y,Z) = P(X | Y,Z ) P(Y) P(Z)

Macierz T_{i,j}  to właśnie wyrażenie P(X | Y,Z )  zaś mariageprob(P) zwraca stosowny wektor iloczynów prawdopodobieństw P(Y) P(Z)  gdzie X,Y,Z \in \{ BB,BN,NN \}  .

Dla wybranych w przykładzie powyżej wartości wektora prawdopodobieństw P , daje to następujące prawdopodobieństwa cech dzieci  w pierwszym pokoleniu:

sage: # przy zadanych częstościach początkowych występowania genów ( w wektorze P), 
sage: # w następnym pokoleniu mamy następujące prawdopodobieństwa:
sage: P1 = T*(mariageprob(P).transpose());P1
[0.0225000000000000]
[ 0.255000000000000]
[ 0.722500000000000]

Jak wiadomo dzieci mają dzieci. Sprawdźmy zatem co się stanie w pokoleniu drugim:

sage: P2 = T*(mariageprob(P1).transpose());P2
[0.0225000000000000]
[ 0.255000000000000]
[ 0.722500000000000]

Hmm… Ciekawe. Wyszło to samo…

Pobawmy sie w iteracje tego procesu. Postąpimy tak. Na siatce w układzie współrzędnych, w przedziale [0,1]  dla każdego punktu, przyjmiemy że jego współrzędne (x,y)  określają wartości prawdopodobieństwa cech (P(0),P(1),1-P(0)-P(1))  . Prawdopodobieństwo trzeciej kombinacji określone jest przez dwie pozostałe bo w sumie muszą dawać 1. Zdefiniujemy sobie funkcję, która wykona pewną liczbę iteracji startując od początkowych wartości (x,y)  określonych jako współrzędne punktu na płaszczyźnie, i wyliczy szanse posiadania cechy k.

Funkcja ta ma postać:

sage: # Pobawimy sie w iteracje.
sage: # Dla zadanego wektora P, który ma tylko 2 niezależne składowe
sage: # wyrysujemy jakie jest prawdopodobieństwo występowania cechy k \in {(0)BB,(1)BN,(2)NN},
sage: # po Iter pokoleniach
sage: # dokładnie tak jak w wypadku żuczka Mandelbrota.
sage: # TR poniżej to macierz T podana w wstawce wyżej
sage: def genotypeprob(Iter,k,PTS=10):
...   TR = matrix([[1,0.5,0,0.5,0.25,0,0,0,0],  [0,0.5,1,0.5,0.5,0.5,1,0.5,0],  [0,0,0,0,0.25,0.5,0,0.5,1]]);
...     PR=[]
...     N_pts=PTS
...     M = matrix(RR,N_pts,N_pts,0)
...     delta = 1/N_pts
...     i=0;
...     j=0;
...     z=0;
...     for i in range(N_pts):
...         for j in range(N_pts-i):
...             PR = vector([i*delta,j*delta,heaviside(1-i*delta-j*delta)*(1-i*delta-j*delta)])
...             #print(PR, TR*mariageprob(PR).transpose())
...             for s in range(Iter):
...                 PR = TR*mariageprob(PR).transpose()
...             M[i,j] = PR[k].get(0)
...     return M

No i policzmy dla przykładu kilka iteracji, oraz przedstawmy je na wykresie. Przykładowo wywołanie  genotypeprob(2,2,200) oznacza że wykonujemy 2 iteracje ( badamy 2-gie pokolenie), interesuje nas cecha (2)NN, oraz kwadrat pokrywamy siatką 200×200 punktów. Oś y to prawdopodobieństwo w pierwszym pokoleniu, startowe, cechy BB czyli oczu brązowych, która jest dominująca, zaś oś x to prawdopodobieństwo startowe cechy BN. Kolorem oznaczono prawdopodobieństwo cechy NN czyli występowania oczu niebieskich, które realizują się tylko w takiej kombinacji genów.

Poniżej wykresy:

sage: m12=genotypeprob(1,2,200);
sage: matrix_plot(m12,colorbar=True,cmap='spectral',origin='lower')

m12

sage: m22=genotypeprob(2,2,200);
sage: matrix_plot(m22,colorbar=True,cmap='spectral',origin='lower')

m22

sage: m32=genotypeprob(3,2,200);
sage: matrix_plot(m32,colorbar=True,cmap='spectral',origin='lower'

m32

Jak ktoś chce może oczywiście wyprodukować kolejne. Widać wyraźnie ze prawdopodobieństwa na wykresach są stałe!

Powyższe obliczenia ilustrują prawo Hardy’ego-Weinberga.

Dodatkowo na poniższym wykresie widać że obliczenia numeryczne mają skończoną dokładność ;-)

sage: matrix_plot((m12-m22),colorbar=True,cmap='spectral',origin='lower')

diff    Pytanie – czy tak zdefiniowany proces dziedziczenia jest procesem Markowa?