Files
@ 7a95aed29ade
Branch filter:
Location: AENC/resampling_chain/exact/compute_linesegment.m
7a95aed29ade
4.7 KiB
application/vnd.wolfram.mathematica.package
Add computation of P(Z^n | start 011..11)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | (* ::Package:: *)
(* ::Section:: *)
(*Choice of symbols*)
(* ::Text:: *)
(*Sample a 0=BAD with probability p*)
(*Sample a 1=GOOD with probability 1-p = q*)
(*Pick a random 0 and resample.*)
(*All-1 state is the final good state.*)
(* ::Text:: *)
(*Goal: compute P(Z^n | start in 011..11) on the finite chain {1,...,n}*)
(*Method: sum over (k>=1) of P(vertex n gets zero for the first time at step k)*)
(*Let M be the Markov Chain on n-1 vertices such that if site n becomes zero, then it goes to a special state with no outgoing arrows*)
(*Furthermore the all-good state has no self-loop (but has incoming paths). This last thing seems like it is not required but removes the 1 eigenvalue so I guess it is good for inverting. Let si be the initial state, let sf be the final special state.*)
(*Goal is to compute sum over (k>=0) of si . M^k . sf*)
(*This is equal to si . (1 - M)^(-1) . sf*)
(* ::Chapter:: *)
(*Markov Chain Matrix*)
(* Note that the matrix function requires at least n\[GreaterEqual]3 *)
generateInitialState[n_]:=SparseArray[{(1+FromDigits[Join[{0},ConstantArray[1,n-2]],2])->1},{2^(n-1)+1}]
generateFinalState[n_]:=SparseArray[{(2^(n-1)+1)->1},{2^(n-1)+1}]
(* Matrix as described above! *)
generateLeakingMatrix[nReal_,p_]:=Module[{n,mcM,bits,numBads,j1,j2,j3,newbits,prob},
n = nReal-1; (* See description above. When vertex n is resampled it is a special state. *)
mcM=SparseArray[{},{2^n+1,2^n+1},0];
Do[
(* Compute neighbours of i *)
bits=IntegerDigits[i,2,n];
numBads=Count[bits,0];
(* Special cases: j==1 and j==n *)
If[bits[[1]]==0, (* j==1 *)
newbits=bits;
Do[
newbits[[{1,2}]]={b1,b2};
prob=((1-p)^(b1+b2)*(p)^(2-(b1+b2)))/numBads;
(* Set the matrix entry *)
mcM[[i+1,FromDigits[newbits,2]+1]]+=prob;
,{b1,0,1},{b2,0,1}];
];
If[bits[[n]]==0, (* j==n *)
(* This 'n' is actually the n-1 vertex. So we check if it sets the real n vertex to zero. *)
(* Potentially go into special state *)
newbits=bits;
Do[
prob=((1-p)^(b1+b2+b3)*(p)^(3-(b1+b2+b3)))/numBads;
If[b3==0,
(* Special state *)
mcM[[i+1,-1]]+=prob;
,
(* Normal state *)
newbits[[{n-1,n}]]={b1,b2};
(* Set the matrix entry *)
mcM[[i+1,FromDigits[newbits,2]+1]]+=prob;
];
,{b1,0,1},{b2,0,1},{b3,0,1}];
];
If[n>=3,
Do[ (* 2 <= j <= n-1 *)
(* For all sites, check if it is BAD *)
If[bits[[j]]==0,
newbits=bits;
Do[
newbits[[{j-1,j,j+1}]]={b1,b2,b3};
prob=((1-p)^(b1+b2+b3)*(p)^(3-(b1+b2+b3)))/numBads;
(* Set the matrix entry *)
mcM[[i+1,FromDigits[newbits,2]+1]]+=prob;
,{b1,0,1},{b2,0,1},{b3,0,1}];
]; (* endif bits[[j]] *)
,{j,2,n-1}];];
,{i,0,2^n-1}];
mcM
]/;(nReal>=3)
(* ::Section:: *)
(*Symbolic evaluation*)
(* ::Subsection:: *)
(*Expected number of resamples using inverse method*)
(* This function definition causes automatic memoization of results *)
getIdMinusM[n_]:=getIdMinusM[n]=Module[{M,IdMinusM},
PrintTemporary["Generating matrix (Id-M) for n = ",n," and general p."];
M=generateLeakingMatrix[n,p];
IdMinusM=IdentityMatrix[Length[M],SparseArray]-M;
IdMinusM
]
(* Replacement rules do not work on sparsearrays. Instead we use this, taken shamelessly from stackoverflow *)
ReplaceElement[s_SparseArray, rule_]:=SparseArray[ArrayRules[s]/.rule,Dimensions[s]]
computeFullExpression[n_,pValue_]:=Module[{nSites,si,sf,IdMinusM,inv1},
(*PrintTemporary["Generating initial state for n = ",n,", p = ",pValue];*)
(*PrintTemporary["Getting (Id-M) matrix."];*)
IdMinusM=getIdMinusM[n];
(*PrintTemporary["Entering p into matrix"];*)
IdMinusM=Simplify[ReplaceElement[IdMinusM,p->pValue]];
si=generateInitialState[n];
sf=generateFinalState[n];
PrintTemporary["Solving (Id-M).x = b for n = ",n," , p = ",pValue];
inv1=LinearSolve[IdMinusM,sf];
(*PrintTemporary["Computing final inner product"];*)
Simplify[si.inv1]
]
generateLeakingMatrix[2,p]
(* ::Subsection:: *)
(*Compute and save coefficients*)
(* For n up to 10 it can be done symbolically in p *)
n2function[p_]=computeFullExpression[2,p];
(*
n3function[p_]=computeFullExpression[3,p];
n4function[p_]=computeFullExpression[4,p];
n5function[p_]=computeFullExpression[5,p];
n6function[p_]=computeFullExpression[6,p];
n7function[p_]=computeFullExpression[7,p];
n8function[p_]=computeFullExpression[8,p];
n9function[p_]=computeFullExpression[9,p];
n10function[p_]=computeFullExpression[10,p];
*)
For[i=1,i<500,i++,
pValue=0/1000+i/500;
Rvalue=computeFullExpression[12,pValue];
PutAppend[{12,pValue,Rvalue},"functionValuesN12.m"]
PutAppend[",","functionValuesN12.m"]
]
|