diff --git a/coefficients/lm006_wrong_sign_20261006_r20/NOTE.md b/coefficients/lm006_wrong_sign_20261006_r20/NOTE.md new file mode 100644 index 000000000..a79f08085 --- /dev/null +++ b/coefficients/lm006_wrong_sign_20261006_r20/NOTE.md @@ -0,0 +1,245 @@ +# An outward enclosure of the actual LM006 cubic sign coefficient + +Dylan Roy — delegated AI mathematical/numerical work. Actual author OpenAI / +GPT-6 Astra Pro, `r20-sign-coefficient-enclosure-20261006-1105`, pickup +Math-#358/6014879289. Scientific effect NONE; organizational-independence credit0. +This is an additive certificate candidate, not an independent review or Lean proof. + +## 1. Exact coefficient and scope + +Consume ONLY the coefficient formula (3)–(5),(18)–(20) of +`reviews/lm006_wrong_sign_asymptotic_20261006/NOTE.md` at immutable Math- +`64c0a203b94105f0fccbe6f8116a94e13431f84e`, Git blob +`ea914c1b8e0b8180b645f3f626e2081ab87700b9`, SHA256 +`00d57d987c28ef5f2e3f6467c9e343fb60ffb3ad5806d004f245fe16914fbb61`. +Its theorem and source review are not reproved or broadened by this calculation. +The model is d=2, L=24, b=6/5, original coordinate axes, six canonical pins with +height gap r^3/6, and the FULL normalized determinant tilt. The coefficient is +for the saddle-transverse event f_yy(S)>=0, not capture, elder or persistence. + +Write m2,m4 for the exact one-coordinate torus spectral moments, +delta=m4-m2^2, v=m2*delta. Under the UNTILTED Gaussian law take independent +D~N(0,v), B~N(0,v/4), Q~N(-m2*b,delta). Then + + C=p0*Gamma/z0, Gamma=E J(D,B^2), z0=E(Q_-)^2, + p0=exp(-(m2*b)^2/(2delta))/sqrt(2*pi*delta), + J(d,u)=int_0^(d_+) (d-u-t)_+ (u-t)_+ dt. (1) + +For u>=0, J=0 when u=0 or d<=u. Otherwise, with l=min(u,d-u), +M=max(u,d-u), J=l^2*(3M-l)/6. The denominator z0 is NOT conditioned on +the sign event. There is no extra pin density, six-variable Jacobian, or +factor from treating B as the full derivative rather than its half. + +**Computed enclosure.** The algorithm proved below, evaluated at grid2048, +gives inclusive outward decimal bounds + + 0.001305365507 <= C_(24,6/5) <= 0.001338803452. (2) + +In particular 0.00130=1) exp(-288n^2). + +Gaussian image tails permit termwise differentiation. Put +A2=2 sum_(n>=1)(24n)^2 exp(-288n^2), +A4=2 sum_(n>=1)(24n)^4 exp(-288n^2). Direct second/fourth derivatives give + + m2=1-A2/H, m4=3+(A4-6A2)/H. (4) + +For every n>=1, (24n)^4-6(24n)^2>0, so m4>=3. H>=1. The positive rational +Taylor sum sum_(k=0)^400 288^k/k! is greater than10^125, checked exactly by +image_bounds(). Hence exp(-288)=0, a=isqrt(floor(x*S^2)) gives a/S<=sqrt(x). If (a/S)^2=x, +the upper endpoint is a/S; otherwise it is(a+1)/S. Products and reciprocals +of positive interval endpoints are carried out exactly before outward rounding. + +For exp(-x), divide x by2 until y<=1/8. The alternating Taylor polynomial of +degree23 is a lower bound, and degree22 is an upper bound. Terms decrease. +First round the lower down and upper up to units1/S, then square each interval +as many times as the initial divisions, rounding each squared lower down and +upper up. Monotonicity on nonnegative numbers preserves enclosure. Intersection +with[0,1] is valid because0=0) + (-1)^k z^(2k+1)/(2^k k! (2k+1)). (6) + +This follows by integrating the Gaussian exponential series on[0,z]. Its +terms decrease; k=0..33 gives a lower sum, k=0..32 an upper sum. The positive +normalizing factor is bounded by the previous pi/root construction. The +implementation explicitly rejects z outside[0,1]; the parameter intervals +in(5) put a/sqrt(delta) strictly inside this domain, with a=m2*b>0. +The DLMF7.6.1 power series was consulted as classical context; the alternating +remainder and all coefficients used here are stated explicitly, not imported +from a floating library or unread numerical table. + +Finally + + z0=(a^2+delta) Phi(a/sqrt(delta)) + +a sqrt(delta) phi(a/sqrt(delta)). (7) + +All factors are positive. Bound the argument by its a/delta endpoints, use +monotonicity of Phi and decreasing phi on nonnegative arguments, then combine +positive lower/upper products. p0=phi(a/sqrt(delta))/sqrt(delta) is treated +similarly. This encloses the means as well as covariances; it does not assume +normalizer invariance under a mean shift. + +## 4. Rectangle extrema and Gaussian density bounds + +By symmetry in B and since J=0 for D<=0, + + Gamma=2 int_0^infty int_0^infty J(d,beta^2) + p_D(d) p_B(beta) d beta dd. (8) + +For fixed u, J(d,u) is nondecreasing in d by its original nonnegative integral. +For fixed d>=0 it is symmetric under u -> d-u on[0,d], zero outside that +interval, increasing up to d/2 and decreasing thereafter. For0<=u<=d/2, +J=d*u^2/2-2*u^3/3, whose u derivative is u(d-2u)>=0; symmetry proves the rest. +Thus on d in[d0,d1], u in[u0,u1], all nonnegative, + + J_lower=min(J(d0,u0),J(d0,u1)), + J_upper=J(d1, clamp(d1/2,u0,u1)). (9) + +This includes intervals crossing either zero-support threshold or the maximum. +It is not sufficient to sample only the two corners for the UPPER bound. +The global maximum is J(d,d/2)=d^3/24. + +If a centered normal variance lies in[vlo,vhi] with vlo>0, its density at +x>=0 is bounded below by + + exp(-x^2/(2vlo))/sqrt(2pi*vhi) + +and above by exp(-x^2/(2vhi))/sqrt(2pi*vlo). Each actual centered normal +density decreases in x>=0. Use the lower density at the right cell endpoint +and the upper at the left, and round the two density values outward to1/S. +For B the variance interval is[vlo/4,vhi/4], NOT[vlo,vhi]. + +Use[0,R]x[0,T], R=12,T=4, with n subdivisions in each variable. On a cell, +u0=beta0^2,u1=beta1^2. Multiply (9), the two density bounds, the exact area +(R/n)(T/n), and symmetry factor2. Summing nonnegative lower/upper cell bounds +gives a lower/upper integral over the rectangle without a derivative-error or +floating-quadrature hypothesis. + +The optimized implementation uses common coordinate denominator qcoord=2n^2: +d_i=2Rin/qcoord, u_k=2T^2 k^2/qcoord. The extra2 includes d/2 exactly. +_jnum returns l^2(3M-l) in these integer units. Multiplication by +2RT/[n^2*6*qcoord^3*S^2] restores the integration area, J denominator, and two +densities. test_full_rectangle_sum_against_fraction_reference independently +uses actual Fraction coordinates and the explicit cell formula, not those units. + +## 5. Explicit omitted-domain tails + +Since J(d,u)<=d_+^3/24, the union of D>R and |B|>T bounds the omitted region. +Double-counting their overlap only enlarges the upper bound. Integration by +parts in the centered Gaussian density of variance v gives + + E[D^3;D>R]=(v R^2+2v^2)p_D(R), + E[D_+^3]=2v^2 p_D(0). + +Also for T>0, x/T>=1 on x>=T and integration of x*p_B(x) gives + + P(|B|>T)<=2(v/4)p_B(T)/T=v*p_B(T)/(2T). + +Independence of B,D under the UNTILTED law in (1) therefore bounds the tail by + + tail <= (vR^2+2v^2)p_D(R)/24 + +[2v^2 p_D(0)/24]*[v p_B(T)/(2T)]. (10) + +Use vhi in the polynomial prefactors and the uniform density upper bounds +from section4. This bounds all parameters in(5), not just v=2. The computed +upper tail of Gamma is less than0.000000001492544918. Lower Gamma omits +the tail; upper Gamma ADDS it. Removing it from the upper sum is not certified. +Divide only after multiplying Gamma by the positive p0 interval, using the +opposite z0 endpoint for each quotient. This produces(2). + +## 6. Execution, sensitivity, and review boundary + +Reproduce with Python standard library only: + + python -B -S test_enclosure.py + python -B -O -S test_enclosure.py + python -B -S enclose.py --grid 2048 + python -B -O -S enclose.py --grid 2048 + +The first12 methods failed for the missing implementation, with no import/harness +errors. The final15 methods pass in both modes; three later checks add independent +unrounded exponential sums,221 root-split exact J integrations, and an independent +64-cell Fraction-coordinate sum. Other coverage includes sqrt/outward rounding, +Gaussian density parameter variation, image tails, boundary/rectangle cases, +normalizer positivity, grid nesting and CLI/input guards. A few loose binary64 +math.exp/math.erf comparisons occur ONLY in the test file as sanity screens; +no certified endpoint depends on them or on its printed decimal pi sanity check. + +Eight isolated wrong-source variants were actually run through all15 tests in +both modes and rejected by intended assertions, zero errors: doubled J; omitted +B variance/4; omitted symmetry2; omitted upper tail; omitted normalizer; inward +sqrt; inward exponential upper rounding; and a weakened image-exponential bound. +Those variants and raw test-first/failure streams are retained in the owner +execution delivery, not substituted into this production checker. Grids512,1024, +2048 are nested enclosure diagnostics. Agreement/convergence of grid outputs +alone is NOT the certification argument; the extrema and tails above are. + +On the frozen source, normal and optimized grid2048 stdout is byte-identical to +RESULTS.json. No hosted workflow is added here; existing general CI does not +run this standalone checker or formalize this numerical proof in Lean. A new +nonauthor read must inspect the interval directions, cells, infinite tails, +periodic inputs, source mapping and actual execution before accepting this +candidate. The prior #358 theorem review does not cover these new files. + +No original mathematical/Lean/gate/workflow/status files are changed. #358's +separate integration is not held by this follow-through. Existing source-admission, +provenance and full-field scientific obligations remain governed separately. diff --git a/coefficients/lm006_wrong_sign_20261006_r20/RESULTS.json b/coefficients/lm006_wrong_sign_20261006_r20/RESULTS.json new file mode 100644 index 000000000..53b5921f4 --- /dev/null +++ b/coefficients/lm006_wrong_sign_20261006_r20/RESULTS.json @@ -0,0 +1 @@ +{"arithmetic": "integer/Fraction; outward fixed-point scale 10^36", "coefficient": ["0.001305365507", "0.001338803452"], "gamma": ["0.021429752302", "0.021978691924"], "grid": 2048, "independently_reviewed": false, "meaning": "author-side outward rational enclosure conditional on the #358 coefficient formula", "p0": ["0.196810857928", "0.196810857929"], "scientific_effect": "NONE", "scope": "d2, L24, b6/5, original axes, six pins and gap r^3/6; no finite-r error bound", "source_commit": "64c0a203b94105f0fccbe6f8116a94e13431f84e", "tail_gamma_upper": "0.000000001492544918", "z0": ["3.230978535287", "3.230978535288"]} diff --git a/coefficients/lm006_wrong_sign_20261006_r20/SOURCES.json b/coefficients/lm006_wrong_sign_20261006_r20/SOURCES.json new file mode 100644 index 000000000..e51a4dfb5 --- /dev/null +++ b/coefficients/lm006_wrong_sign_20261006_r20/SOURCES.json @@ -0,0 +1,53 @@ +{ + "schema_version": 1, + "scientific_effect": "NONE", + "author": { + "provider": "OpenAI", + "model": "GPT-6 Astra Pro", + "session": "r20-sign-coefficient-enclosure-20261006-1105" + }, + "files": { + "NOTE.md": { + "bytes": 12359, + "sha256": "1a145132e05aa2721397d30fd3c422bbaab496ac8c24b947e416a3f4e0e0a526", + "git_blob": "a79f080851bba69a03ec4b8348dc93d04143bf62" + }, + "RESULTS.json": { + "bytes": 624, + "sha256": "98eff91444a190a4bc521e010e1e2b8071affe5175b6d2403516777e92d0d17f", + "git_blob": "53b5921f40f95a2623795b6cfe9ec47420705ad3" + }, + "enclose.py": { + "bytes": 7215, + "sha256": "157e02ee22699b4fa2efdde1894824b92b962900dbb8da9bd65acee41ae91e88", + "git_blob": "e680ddb7aa0abd4b6aab2cac6a54c1ff28efc782" + }, + "test_enclosure.py": { + "bytes": 6738, + "sha256": "a065f504272630c1a3fadc9e85500982af38902acadc1059b0503ad3aa571bec", + "git_blob": "a05992a4e5d9845618aee6ea53d62e08ee776940" + } + }, + "dependencies": [ + { + "repository": "d6g8k5htny-coder/Math-", + "commit": "64c0a203b94105f0fccbe6f8116a94e13431f84e", + "path": "reviews/lm006_wrong_sign_asymptotic_20261006/NOTE.md", + "git_blob": "ea914c1b8e0b8180b645f3f626e2081ab87700b9", + "sha256": "00d57d987c28ef5f2e3f6467c9e343fb60ffb3ad5806d004f245fe16914fbb61", + "consumed": "Equations (3)-(5),(18)-(20): exact coefficient and fixed object, not a new proof of the asymptotic theorem" + }, + { + "repository": "d6g8k5htny-coder/Math-", + "commit": "a952d25d11400561da10324dbb40e42c9da4ea6c", + "path": "imports/lifetime_parent_20260925/UNIFORM_MATRIX_CAP_AND_LIFETIME.md", + "git_blob": "dfed3b8d318a3ab1950957f393307733a4bef3f2", + "consumed": "Section1 image-sum covariance definition only; no global theorem imported" + } + ], + "external_context": { + "source": "NIST DLMF 7.6.1", + "url": "https://dlmf.nist.gov/7.6", + "scope": "Classical power-series context; explicit alternating bounds derived in NOTE" + } +} diff --git a/coefficients/lm006_wrong_sign_20261006_r20/enclose.py b/coefficients/lm006_wrong_sign_20261006_r20/enclose.py new file mode 100644 index 000000000..e680ddb7a --- /dev/null +++ b/coefficients/lm006_wrong_sign_20261006_r20/enclose.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python3 +"""Outward rational enclosure of the coefficient in Math-#358. + +All certified arithmetic is integer/Fraction. No floating arithmetic, quadrature +library, simulation, or Lean proof. Source theorem and scope remain prerequisites. +""" +import argparse +from fractions import Fraction as F +from functools import lru_cache +from math import isqrt +import json + +SCALE=10**36 + +def ceil_ratio(n,d): + return -((-n)//d) + +def fixed(x): + x=F(x) + return x.numerator*SCALE//x.denominator,ceil_ratio(x.numerator*SCALE,x.denominator) + +def sqrt_bounds(x): + x=F(x) + if x<0:raise ValueError('nonnegative radicand required') + a=isqrt(x.numerator*SCALE*SCALE//x.denominator) + b=a if F(a*a,SCALE*SCALE)==x else a+1 + return F(a,SCALE),F(b,SCALE) + +@lru_cache(maxsize=1) +def pi_bounds(): + def atan(z): + # 81 terms ends positive, hence upper; preceding partial sum is lower. + z=F(z);s=F(0) + for k in range(81): + term=(-1)**k*z**(2*k+1)/(2*k+1) + s+=term + return s-term,s + a,b=atan(F(1,5));c,d=atan(F(1,239)) + return 16*a-4*d,16*b-4*c + +def exp_neg(x): + x=F(x) + if x<0:raise ValueError('nonnegative argument required') + if x==0:return F(1),F(1) + shifts=0 + while x>F(1,8):x/=2;shifts+=1 + # Alternating series: even degree 22 upper; odd degree 23 lower. + term=s=F(1) + for k in range(1,24): + term*=-x/k;s+=term + lo=fixed(s)[0];hi=fixed(s-term)[1] + for _ in range(shifts): + lo=lo*lo//SCALE;hi=ceil_ratio(hi*hi,SCALE) + return F(max(lo,0),SCALE),F(min(hi,SCALE),SCALE) + +@lru_cache(maxsize=1) +def inv_sqrt_2pi(): + lo,hi=pi_bounds();a=sqrt_bounds(2*lo)[0];b=sqrt_bounds(2*hi)[1] + return 1/b,1/a + +def cdf_positive(z): + z=F(z) + if not 0<=z<=1:raise ValueError('CDF series interface requires 0<=z<=1') + if z==0:return F(1,2),F(1,2) + term=s=z + # Integrate exp(-t²/2), alternating with decreasing terms on [0,1]. + for k in range(1,34): + term*=-z*z*F(2*k-1,2*k*(2*k+1));s+=term + c,d=inv_sqrt_2pi() + return F(1,2)+c*s,F(1,2)+d*(s-term) + +@lru_cache(maxsize=1) +def image_bounds(): + # Positive Taylor lower sum certifies e^288 > 10^125, no decimal log input. + term=total=F(1) + for k in range(1,401):term*=F(288,k);total+=term + if total<=10**125:raise ArithmeticError('exponential image bound failed') + q=F(1,10**125) + s2=q*(1+q)/(1-q)**3 + s4=q*(1+11*q+11*q*q+q**3)/(1-q)**5 + # H>=1; drop the negative contribution -6 A2 for upper m4 error. + return {'exp288_lower_gt_10pow125':True, + 'm2_error':2*24**2*s2,'m4_error':2*24**4*s4} + +@lru_cache(maxsize=1) +def parameters(): + images=image_bounds();eps=F(1,10**24) + if max(images['m2_error'],images['m4_error'])>=eps: + raise ArithmeticError('periodic input enclosure not established') + m2=(1-eps,F(1));m4=(F(3),3+eps) + delta=(m4[0]-m2[1]**2,m4[1]-m2[0]**2) + v=(m2[0]*delta[0],m2[1]*delta[1]) + # a=m2*b>0, z0=(a²+delta)Phi(a/sqrt(delta))+a sqrt(delta)phi(a/sqrt(delta)). + a=(m2[0]*F(6,5),m2[1]*F(6,5)) + sigma=(sqrt_bounds(delta[0])[0],sqrt_bounds(delta[1])[1]) + z=(a[0]/sigma[1],a[1]/sigma[0]) + Phi=(cdf_positive(z[0])[0],cdf_positive(z[1])[1]) + inv=inv_sqrt_2pi() + ex=(exp_neg(z[1]**2/2)[0],exp_neg(z[0]**2/2)[1]) + phi=(inv[0]*ex[0],inv[1]*ex[1]) + z0=((a[0]**2+delta[0])*Phi[0]+a[0]*sigma[0]*phi[0], + (a[1]**2+delta[1])*Phi[1]+a[1]*sigma[1]*phi[1]) + p0=(phi[0]/sigma[1],phi[1]/sigma[0]) + return {'m2':m2,'m4':m4,'delta':delta,'variance_D':v,'z0':z0,'p0':p0} + +def density(x,var): + x=F(x);lo,hi=map(F,var) + if x<0 or not 0R and |B|>T; J<=D_+³/24. + tail_d=(v[1]*R*R+2*v[1]**2)*d_pdf[-1][1]/24 + mean_d3=2*v[1]**2*d_pdf[0][1] + tail_b=mean_d3/24*(v[1]/(2*T))*b_pdf[-1][1] + tail=tail_d+tail_b + gamma=(low,high+tail) + coeff=(gamma[0]*p['p0'][0]/p['z0'][1],gamma[1]*p['p0'][1]/p['z0'][0]) + return {'grid':n,'gamma':gamma,'coefficient':coeff,'tail':tail,'parameters':p} + +def decimal_bound(x,places=12,upper=False): + scale=10**places;x=F(x) + n=ceil_ratio(x.numerator*scale,x.denominator) if upper else x.numerator*scale//x.denominator + return str(n//scale)+'.'+str(n%scale).zfill(places) + +def output(n): + r=enclosure(n) + pairs=lambda a:[decimal_bound(a[0]),decimal_bound(a[1],upper=True)] + return {'scientific_effect':'NONE','independently_reviewed':False, + 'meaning':'author-side outward rational enclosure conditional on the #358 coefficient formula', + 'source_commit':'64c0a203b94105f0fccbe6f8116a94e13431f84e', + 'grid':n,'coefficient':pairs(r['coefficient']),'gamma':pairs(r['gamma']), + 'tail_gamma_upper':decimal_bound(r['tail'],places=18,upper=True), + 'z0':pairs(r['parameters']['z0']),'p0':pairs(r['parameters']['p0']), + 'arithmetic':'integer/Fraction; outward fixed-point scale 10^36', + 'scope':'d2, L24, b6/5, original axes, six pins and gap r^3/6; no finite-r error bound'} + +def main(): + parser=argparse.ArgumentParser(description=__doc__) + parser.add_argument('--grid',type=int,default=512) + args=parser.parse_args() + try:result=output(args.grid) + except (ValueError,TypeError,ArithmeticError) as exc: + print('ENCLOSURE_FAIL: '+str(exc),file=__import__('sys').stderr);return 1 + print(json.dumps(result,sort_keys=True));return 0 +if __name__=='__main__':raise SystemExit(main()) diff --git a/coefficients/lm006_wrong_sign_20261006_r20/test_enclosure.py b/coefficients/lm006_wrong_sign_20261006_r20/test_enclosure.py new file mode 100644 index 000000000..a05992a4e --- /dev/null +++ b/coefficients/lm006_wrong_sign_20261006_r20/test_enclosure.py @@ -0,0 +1,129 @@ +"""Arithmetic and enclosure regressions; not an independent proof review.""" +from fractions import Fraction as F +from pathlib import Path +import importlib.util +import itertools +import json +import math +import subprocess +import sys +import unittest +P=Path(__file__).with_name('enclose.py') +class EnclosureTests(unittest.TestCase): + def setUp(self): + self.assertTrue(P.is_file(), 'enclosure implementation missing') + spec=importlib.util.spec_from_file_location('enclose',P) + self.m=importlib.util.module_from_spec(spec); spec.loader.exec_module(self.m) + def test_rational_rounding(self): + for x in (F(0),F(1,3),F(7,9),F(23,7)): + lo,hi=self.m.fixed(x) + self.assertLessEqual(F(lo,self.m.SCALE),x) + self.assertGreaterEqual(F(hi,self.m.SCALE),x) + self.assertLessEqual(hi-lo,1) + def test_square_root_enclosure(self): + for x in (F(0),F(1,7),F(2),F(9,4),F(100)): + lo,hi=self.m.sqrt_bounds(x) + self.assertLessEqual(lo*lo,x);self.assertGreaterEqual(hi*hi,x) + def test_exponential_bounds(self): + for x in (F(0),F(1,8),F(1),F(3),F(25),F(36),F(40)): + lo,hi=self.m.exp_neg(x) + self.assertTrue(0<=lo<=hi<=1) + self.assertLess(hi-lo,F(1,10**30)) + # This binary64 comparison is only a loose supplemental screen. + self.assertAlmostEqual(float((lo+hi)/2),math.exp(-float(x)),places=14) + a,b=self.m.exp_neg(F(1,2));c,d=self.m.exp_neg(1) + self.assertTrue(a*a<=d and b*b>=c) + def test_exponential_against_unrounded_alternating_sums(self): + for x in (F(1,8),F(1,2),F(1)): + # Distinct high-order rational reference, without scaling or rounding. + ref_hi=sum(((-x)**k/F(math.factorial(k)) for k in range(61)),F(0)) + ref_lo=ref_hi+(-x)**61/F(math.factorial(61)) + lo,hi=self.m.exp_neg(x) + self.assertLessEqual(lo,ref_lo) + self.assertGreaterEqual(hi,ref_hi) + def test_pi_and_cdf(self): + lo,hi=self.m.pi_bounds() + self.assertTrue(F('3.14159265358979323846264338327950288')0 and u-t>0:value+=primitive(right)-primitive(left) + self.assertEqual(value,self.m.j(d,u)) + def test_full_rectangle_sum_against_fraction_reference(self): + # Independent coordinate-based sum, not the optimized integer units. + n=8;v=self.m.parameters()['variance_D'];low=high=F(0) + for i,k in itertools.product(range(n),repeat=2): + d0,d1=F(12*i,n),F(12*(i+1),n) + b0,b1=F(4*k,n),F(4*(k+1),n) + jl,ju=self.m.cell_bounds(d0,d1,b0*b0,b1*b1) + dl=self.m.density(d1,v)[0];du=self.m.density(d0,v)[1] + bl=self.m.density(b1,(v[0]/4,v[1]/4))[0] + bu=self.m.density(b0,(v[0]/4,v[1]/4))[1] + low+=2*(d1-d0)*(b1-b0)*jl*dl*bl + high+=2*(d1-d0)*(b1-b0)*ju*du*bu + actual=self.m.enclosure(n) + self.assertEqual(actual['gamma'][0],low) + self.assertEqual(actual['gamma'][1],high+actual['tail']) + # Check normalization after, not within, the untilted Gaussian integral. + p=self.m.parameters() + self.assertEqual(actual['coefficient'][0],low*p['p0'][0]/p['z0'][1]) + self.assertEqual(actual['coefficient'][1],(high+actual['tail'])*p['p0'][1]/p['z0'][0]) + def test_invalid_inputs(self): + for value in (0,1,True,3.0): + with self.assertRaises((ValueError,TypeError)):self.m.enclosure(value) + with self.assertRaises(ValueError):self.m.sqrt_bounds(F(-1)) + with self.assertRaises(ValueError):self.m.exp_neg(F(-1)) + with self.assertRaises(ValueError):self.m.cdf_positive(F(2)) + def test_cli(self): + results=[] + for flags in (['-B','-S'],['-B','-O','-S']): + r=subprocess.run([sys.executable,*flags,str(P),'--grid','32'],capture_output=True,text=True,timeout=40) + self.assertEqual((r.returncode,r.stderr),(0,'')) + self.assertFalse(json.loads(r.stdout)['independently_reviewed']);results.append(r.stdout) + self.assertEqual(*results) +if __name__=='__main__':unittest.main(verbosity=2)