Last active
June 28, 2024 05:47
-
-
Save longemen3000/6e39d7ef1eeea78c8bf8333602a0ac00 to your computer and use it in GitHub Desktop.
Exact solution for the association 2B - 2B with cross association
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Roots | |
| function X_exact2!(K,X) | |
| k1 = K[1,2] | |
| k2 = K[2,1] | |
| #this computation is equivalent to the one done in Clapeyron.X_exact1 | |
| _a = k2 | |
| _b = 1 - k2 + k1 | |
| _c = -1 | |
| denom = _b + sqrt(_b*_b - 4*_a*_c) | |
| x1 = -2*_c/denom | |
| x1k = k2*x1 | |
| x2 = (1- x1k)/(1 - x1k*x1k) | |
| X[1] = x1 | |
| X[2] = x2 | |
| return X | |
| end | |
| function X_exact4!(K,X) | |
| #= | |
| strategy is the following: | |
| given K (4x4 assoc matrix) and X | |
| 1. we solve for x1 (7th order polynomial, bracketed newton) | |
| 2. we solve for x3 (2nd order polynomial, analytic) | |
| 3. x2 and x4 only depend on x1 and x3. | |
| this supposes non-zero values of the diagonal submatrices. | |
| we catch the zero case earlier. | |
| =# | |
| _0 = zero(eltype(K)) | |
| k3 = K[2] | |
| k7 = K[4] | |
| k1 = K[5] | |
| k5 = K[7] | |
| k4 = K[10] | |
| k8 = K[12] | |
| k2 = K[13] | |
| k6 = K[15] | |
| X_exact2!(@view(K[1:2,1:2]),@view(X[1:2])) | |
| x10 = X[1] | |
| pol_x1 = __assoc_x1_poly(K) | |
| dpol_x1 = Solvers.polyder(pol_x1) | |
| d2pol_x1 = Solvers.polyder(dpol_x1) | |
| function f0(x) | |
| fx = evalpoly(x,pol_x1) | |
| dfx = evalpoly(x,dpol_x1) | |
| return fx,fx/dfx | |
| end | |
| prob_x1 = Roots.ZeroProblem(f0,x10) | |
| x1res = Roots.solve(prob_x1,Roots.Newton()) #bracketed newton | |
| d2fdx1 = evalpoly(x1res, d2pol_x1) | |
| if d2fdx1 < 0 || !(0 <= x1res <= 1) | |
| return X,false | |
| end | |
| x1 = x1res | |
| x3 = __assoc_x3(K,x1) | |
| x2 = 1 / (1 + k3*x1 + k4*x3) | |
| x4 = 1 / (1 + k7*x1 + k8*x3) | |
| X[1] = x1 | |
| X[2] = x2 | |
| X[3] = x3 | |
| X[4] = x4 | |
| return X,true | |
| end | |
| function __assoc_x1_poly(K) | |
| k3 = K[2] | |
| k7 = K[4] | |
| k1 = K[5] | |
| k5 = K[7] | |
| k4 = K[10] | |
| k8 = K[12] | |
| k2 = K[13] | |
| k6 = K[15] | |
| var1 = k8*k8 | |
| var2 = k1*k2*k4*k5*k8 | |
| var3 = k1*k1 | |
| var4 = var3*k4*k6*k8 | |
| var5 = k4*k4 | |
| var6 = var3*var5*k6*k8 | |
| var7 = -(var3*k4*k5*k6*k8) | |
| var8 = -(2*k1*k2*k4*k5*k6*k8) | |
| var9 = k6*k6 | |
| var10 = var3*k4*var9*k8 | |
| var11 = -(k1*k2*k5*var1) | |
| var12 = k1*k2*k4*k5*var1 | |
| var13 = k5*k5 | |
| var14 = -(k1*k2*var13*var1) | |
| var15 = -(var3*k6*var1) | |
| var16 = -(var3*k4*k6*var1) | |
| var17 = 2*var3*k5*k6*var1 | |
| var18 = k1*k2*k5*k6*var1 | |
| var19 = var1*k8 | |
| var20 = -(k1*k2*k5*var19) | |
| var21 = k2*k2 | |
| var22 = k1*k2*k3*k4*k5*k8 | |
| var23 = var3*k1 | |
| var24 = var3*k3*k4*k6*k8 | |
| var25 = -(2*k1*k2*k3*k4*k5*k6*k8) | |
| var26 = var3*k3*k4*var9*k8 | |
| var27 = 2*k1*k2*k4*k5*k7*k8 | |
| var28 = 2*var3*k4*k6*k7*k8 | |
| var29 = 2*var3*var5*k6*k7*k8 | |
| var30 = -(2*var3*k4*k5*k6*k7*k8) | |
| var31 = -(2*k1*k2*k4*k5*k6*k7*k8) | |
| var32 = var3*k4*var9*k7*k8 | |
| var33 = k7*k7 | |
| var34 = -(2*k1*k2*k3*k5*var1) | |
| var35 = k1*k2*k3*k4*k5*var1 | |
| var36 = -(k1*k2*k3*var13*var1) | |
| var37 = -(2*var3*k3*k6*var1) | |
| var38 = -(var3*k3*k4*k6*var1) | |
| var39 = 2*var3*k3*k5*k6*var1 | |
| var40 = 2*k1*k2*k3*k5*k6*var1 | |
| var41 = k3*k3 | |
| var42 = -(k1*k2*k5*k7*var1) | |
| var43 = k1*k2*k4*k5*k7*var1 | |
| var44 = -(k1*k2*var13*k7*var1) | |
| var45 = -(var3*k6*k7*var1) | |
| var46 = -(var3*k4*k6*k7*var1) | |
| var47 = 2*var3*k5*k6*k7*var1 | |
| var48 = -(2*k1*k2*k3*k5*var19) | |
| var49 = k2*var21 | |
| var50 = 2*k1*k2*k3*k4*k5*k7*k8 | |
| var51 = 2*var3*k3*k4*k6*k7*k8 | |
| var52 = -(2*k1*k2*k3*k4*k5*k6*k7*k8) | |
| var53 = var3*k3*k4*var9*k7*k8 | |
| var54 = k1*k2*k4*k5*var33*k8 | |
| var55 = var3*k4*k6*var33*k8 | |
| var56 = var3*var5*k6*var33*k8 | |
| var57 = -(var3*k4*k5*k6*var33*k8) | |
| var58 = -(k1*k2*var41*k5*var1) | |
| var59 = var3*var3 | |
| var60 = -(var3*var41*k6*var1) | |
| var61 = k1*k2*var41*k5*k6*var1 | |
| var62 = -(2*k1*k2*k3*k5*k7*var1) | |
| var63 = k1*k2*k3*k4*k5*k7*var1 | |
| var64 = -(k1*k2*k3*var13*k7*var1) | |
| var65 = -(2*var3*k3*k6*k7*var1) | |
| var66 = -(var3*k3*k4*k6*k7*var1) | |
| var67 = 2*var3*k3*k5*k6*k7*var1 | |
| var68 = -(k1*k2*var41*k5*var19) | |
| var69 = k1*k2*k3*k4*k5*var33*k8 | |
| var70 = var3*k3*k4*k6*var33*k8 | |
| var71 = -(k1*k2*var41*k5*k7*var1) | |
| var72 = -(var3*var41*k6*k7*var1) | |
| p0 = zero(eltype(K)) | |
| p1 = k1*k4*k5*k6*k8-k1*k5*k6*var1 | |
| p2 =var20-k1*k5*k6*k7*var1-2*k1*k3*k5*k6*var1+var18+var17+3*k1*k5*k6*var1+var16+var15+var14+var12+var11+2*k1*k4*k5*k6*k7*k8+var10+k1*k3*k4*k5*k6*k8+var8+var7-3*k1*k4*k5*k6*k8+var6+var4+var2 | |
| p3 = var48+var3*k2*k5*var19+2*k1*k2*k5*var19-var3*k2*k4*var19-var3*k2*var19-2*k1*k3*k5*k6*k7*var1+var47+3*k1*k5*k6*k7*var1+var46+var45+var44+var43+var42-k1*var41*k5*k6*var1+var40+var39+6*k1*k3*k5*k6*var1-var3*k2*k5*k6*var1-2*k1*k2*k5*k6*var1-var23*k5*k6*var1-4*var3*k5*k6*var1-3*k1*k5*k6*var1+var38+2*var3*k2*k4*k6*var1+var23*k4*k6*var1+2*var3*k4*k6*var1+var37+var3*k2*k6*var1+2*var23*k6*var1+2*var3*k6*var1+var36+k1*var21*var13*var1+var3*k2*var13*var1+2*k1*k2*var13*var1+var35-k1*var21*k4*k5*var1-2*var3*k2*k4*k5*var1-2*k1*k2*k4*k5*var1+var34+k1*var21*k5*var1+2*k1*k2*k5*var1+var3*k2*var5*var1-var3*k2*var1+k1*k4*k5*k6*var33*k8+var32+2*k1*k3*k4*k5*k6*k7*k8+var31+var30-6*k1*k4*k5*k6*k7*k8+var29+var28+var27+var26-var3*k2*k4*var9*k8-var23*k4*var9*k8-2*var3*k4*var9*k8+var25-3*k1*k3*k4*k5*k6*k8+k1*var21*k4*k5*k6*k8+var3*k2*k4*k5*k6*k8+4*k1*k2*k4*k5*k6*k8+2*var3*k4*k5*k6*k8+3*k1*k4*k5*k6*k8-var3*k2*var5*k6*k8-2*var3*var5*k6*k8+var24-var23*k4*k6*k8-2*var3*k4*k6*k8+var22-2*k1*var21*k4*k5*k8-var3*k2*k4*k5*k8-2*k1*k2*k4*k5*k8+var3*k2*var5*k8+var3*k2*k4*k8 | |
| p4 = var68+var3*k2*k3*k5*var19+4*k1*k2*k3*k5*var19-var3*k2*k5*var19+var20-var3*k2*k3*k4*var19+var3*k2*k4*var19-2*var3*k2*k3*var19+var23*k2*var19+var3*k2*var19-k1*var41*k5*k6*k7*var1+var67+6*k1*k3*k5*k6*k7*var1-var23*k5*k6*k7*var1-4*var3*k5*k6*k7*var1-3*k1*k5*k6*k7*var1+var66+var23*k4*k6*k7*var1+2*var3*k4*k6*k7*var1+var65+2*var23*k6*k7*var1+2*var3*k6*k7*var1+var64+var3*k2*var13*k7*var1+2*k1*k2*var13*k7*var1+var63-2*var3*k2*k4*k5*k7*var1-2*k1*k2*k4*k5*k7*var1+var62+2*k1*k2*k5*k7*var1+var3*k2*var5*k7*var1-var3*k2*k7*var1+var61+3*k1*var41*k5*k6*var1-var3*k2*k3*k5*k6*var1-4*k1*k2*k3*k5*k6*var1-4*var3*k3*k5*k6*var1-6*k1*k3*k5*k6*var1+var3*k2*k5*k6*var1+var18+var23*k5*k6*var1+var17+k1*k5*k6*var1+2*var3*k2*k3*k4*k6*var1+2*var3*k3*k4*k6*var1-2*var3*k2*k4*k6*var1-var23*k4*k6*var1+var16+var60+2*var3*k2*k3*k6*var1+2*var23*k3*k6*var1+4*var3*k3*k6*var1-var23*k2*k6*var1-var3*k2*k6*var1-var59*k6*var1-2*var23*k6*var1+var15+k1*var21*k3*var13*var1+2*k1*k2*k3*var13*var1-k1*var21*var13*var1-var3*k2*var13*var1+var14-k1*var21*k3*k4*k5*var1-2*k1*k2*k3*k4*k5*var1+k1*var21*k4*k5*var1+2*var3*k2*k4*k5*var1+var12+var58+2*k1*var21*k3*k5*var1+4*k1*k2*k3*k5*var1+var3*var21*k5*var1-k1*var21*k5*var1+var23*k2*k5*var1+var11-var3*k2*var5*var1+var3*var21*k4*var1-var23*k2*k4*var1-2*var3*k2*k3*var1+var3*var21*var1+var23*k2*var1+var3*k2*var1+k1*k3*k4*k5*k6*var33*k8+var57-3*k1*k4*k5*k6*var33*k8+var56+var55+var54+var53-var23*k4*var9*k7*k8-2*var3*k4*var9*k7*k8+var52-6*k1*k3*k4*k5*k6*k7*k8+var3*k2*k4*k5*k6*k7*k8+4*k1*k2*k4*k5*k6*k7*k8+4*var3*k4*k5*k6*k7*k8+6*k1*k4*k5*k6*k7*k8-var3*k2*var5*k6*k7*k8-4*var3*var5*k6*k7*k8+var51-2*var23*k4*k6*k7*k8-4*var3*k4*k6*k7*k8+var50-2*k1*var21*k4*k5*k7*k8-2*var3*k2*k4*k5*k7*k8-4*k1*k2*k4*k5*k7*k8+2*var3*k2*var5*k7*k8+2*var3*k2*k4*k7*k8-var3*k2*k3*k4*var9*k8-2*var3*k3*k4*var9*k8+var3*k2*k4*var9*k8+var23*k4*var9*k8+var10+k1*var21*k3*k4*k5*k6*k8+4*k1*k2*k3*k4*k5*k6*k8+3*k1*k3*k4*k5*k6*k8-k1*var21*k4*k5*k6*k8-var3*k2*k4*k5*k6*k8+var8+var7-k1*k4*k5*k6*k8+var3*k2*var5*k6*k8+var6-2*var3*k3*k4*k6*k8-var3*var21*k4*k6*k8-var23*k2*k4*k6*k8+var23*k4*k6*k8+var4-2*k1*var21*k3*k4*k5*k8-2*k1*k2*k3*k4*k5*k8+k1*var49*k4*k5*k8+var3*var21*k4*k5*k8+2*k1*var21*k4*k5*k8+var3*k2*k4*k5*k8+var2-var3*var21*var5*k8-var3*k2*var5*k8+var3*k2*k3*k4*k8-var3*var21*k4*k8-var23*k2*k4*k8-var3*k2*k4*k8 | |
| p5 = 2*k1*k2*var41*k5*var19-var3*k2*k3*k5*var19+var48+var3*k2*k3*k4*var19-var3*k2*var41*var19+var23*k2*k3*var19+2*var3*k2*k3*var19+3*k1*var41*k5*k6*k7*var1-4*var3*k3*k5*k6*k7*var1-6*k1*k3*k5*k6*k7*var1+var23*k5*k6*k7*var1+var47+k1*k5*k6*k7*var1+2*var3*k3*k4*k6*k7*var1-var23*k4*k6*k7*var1+var46+var72+2*var23*k3*k6*k7*var1+4*var3*k3*k6*k7*var1-var59*k6*k7*var1-2*var23*k6*k7*var1+var45+2*k1*k2*k3*var13*k7*var1-var3*k2*var13*k7*var1+var44-2*k1*k2*k3*k4*k5*k7*var1+2*var3*k2*k4*k5*k7*var1+var43+var71+4*k1*k2*k3*k5*k7*var1+var23*k2*k5*k7*var1+var42-var3*k2*var5*k7*var1-var23*k2*k4*k7*var1-2*var3*k2*k3*k7*var1+var23*k2*k7*var1+var3*k2*k7*var1-2*k1*k2*var41*k5*k6*var1-3*k1*var41*k5*k6*var1+var3*k2*k3*k5*k6*var1+var40+var39+2*k1*k3*k5*k6*var1-2*var3*k2*k3*k4*k6*var1+var38+var3*k2*var41*k6*var1+2*var3*var41*k6*var1-var23*k2*k3*k6*var1-2*var3*k2*k3*k6*var1-2*var23*k3*k6*var1+var37-k1*var21*k3*var13*var1+var36+k1*var21*k3*k4*k5*var1+var35+k1*var21*var41*k5*var1+2*k1*k2*var41*k5*var1+var3*var21*k3*k5*var1-2*k1*var21*k3*k5*var1+var34+var3*var21*k3*k4*var1-var3*k2*var41*var1+2*var3*var21*k3*var1+var23*k2*k3*var1+2*var3*k2*k3*var1-3*k1*k3*k4*k5*k6*var33*k8+2*var3*k4*k5*k6*var33*k8+3*k1*k4*k5*k6*var33*k8-2*var3*var5*k6*var33*k8+var70-var23*k4*k6*var33*k8-2*var3*k4*k6*var33*k8+var69-var3*k2*k4*k5*var33*k8-2*k1*k2*k4*k5*var33*k8+var3*k2*var5*var33*k8+var3*k2*k4*var33*k8-2*var3*k3*k4*var9*k7*k8+var23*k4*var9*k7*k8+var32+4*k1*k2*k3*k4*k5*k6*k7*k8+6*k1*k3*k4*k5*k6*k7*k8-var3*k2*k4*k5*k6*k7*k8+var31+var30-2*k1*k4*k5*k6*k7*k8+var3*k2*var5*k6*k7*k8+var29-4*var3*k3*k4*k6*k7*k8-var23*k2*k4*k6*k7*k8+2*var23*k4*k6*k7*k8+var28-2*k1*var21*k3*k4*k5*k7*k8-4*k1*k2*k3*k4*k5*k7*k8+var3*var21*k4*k5*k7*k8+2*k1*var21*k4*k5*k7*k8+2*var3*k2*k4*k5*k7*k8+var27-var3*var21*var5*k7*k8-2*var3*k2*var5*k7*k8+2*var3*k2*k3*k4*k7*k8-var3*var21*k4*k7*k8-2*var23*k2*k4*k7*k8-2*var3*k2*k4*k7*k8+var3*k2*k3*k4*var9*k8+var26-k1*var21*k3*k4*k5*k6*k8+var25-k1*k3*k4*k5*k6*k8-var3*var21*k3*k4*k6*k8+var24+k1*var49*k3*k4*k5*k8+2*k1*var21*k3*k4*k5*k8+var22-var3*var21*k3*k4*k8-var3*k2*k3*k4*k8 | |
| p6 = var68+var3*k2*var41*var19-3*k1*var41*k5*k6*k7*var1+var67+2*k1*k3*k5*k6*k7*var1+var66+2*var3*var41*k6*k7*var1-2*var23*k3*k6*k7*var1+var65+var64+var63+2*k1*k2*var41*k5*k7*var1+var62-var3*k2*var41*k7*var1+var23*k2*k3*k7*var1+2*var3*k2*k3*k7*var1+var61+k1*var41*k5*k6*var1-var3*k2*var41*k6*var1+var60-k1*var21*var41*k5*var1+var58+var3*var21*var41*var1+var3*k2*var41*var1+3*k1*k3*k4*k5*k6*var33*k8+var57-k1*k4*k5*k6*var33*k8+var56-2*var3*k3*k4*k6*var33*k8+var23*k4*k6*var33*k8+var55-2*k1*k2*k3*k4*k5*var33*k8+var3*k2*k4*k5*var33*k8+var54-var3*k2*var5*var33*k8+var3*k2*k3*k4*var33*k8-var23*k2*k4*var33*k8-var3*k2*k4*var33*k8+var53+var52-2*k1*k3*k4*k5*k6*k7*k8+var51+2*k1*var21*k3*k4*k5*k7*k8+var50-var3*var21*k3*k4*k7*k8-2*var3*k2*k3*k4*k7*k8 | |
| p7 = k1*var41*k5*k6*k7*var1+var72+var71+var3*k2*var41*k7*var1-k1*k3*k4*k5*k6*var33*k8+var70+var69-var3*k2*k3*k4*var33*k8 | |
| if p7 > 0 | |
| return (p1/p7,p2/p7,p3/p7,p4/p7,p5/p7,p6/p7,one(eltype(K))) | |
| elseif p7 < 0 | |
| return (-p1/p7,-p2/p7,-p3/p7,-p4/p7,-p5/p7,-p6/p7,-one(eltype(K))) | |
| else | |
| return (p1,p2,p3,p4,p5,p6,p7) | |
| end | |
| end | |
| function __assoc_x3(K,x1) | |
| _0 = zero(eltype(K)) | |
| k3 = K[2] | |
| k7 = K[4] | |
| k1 = K[5] | |
| k5 = K[7] | |
| k4 = K[10] | |
| k8 = K[12] | |
| k2 = K[13] | |
| k6 = K[15] | |
| c3 = -k3*k7 | |
| c2 = k7*(k3 - k1 - 1) - k3*(k2 + 1) | |
| c1 = k7 + k3 - k2 - k1 - 1 | |
| c = evalpoly(x1,(one(c1),c1,c2,c3)) | |
| b2 = -k3*k8-k4*k7 | |
| b1 = k8*(k3 - k1 - 1) + k4*(k7 -k2 - 1) | |
| b0 = k8+k4 | |
| b = evalpoly(x1,(b0,b1,b2)) | |
| a = k4*k8*(1 - x1) | |
| Δ = b*b - 4*a*c | |
| x3 = (-b + sqrt(Δ))/(2*a) | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment