Bootstat 2021 tutorial - Marten Reehorst

Introduction

This is a notebook offers a tutorial on the numerical conformal bootstrap. Most of the material here is based on tutorials by others and most credit should go to them:

[1] Tutorial in 2017 by Miguel Paulos. (http://exact.ictp-saifr.org/boostrap2020/school/)
[2] Unpublished Kay Wiese
[3] Tasi Lecture Notes David-Simmons-Duffin.

This part of the tutorial uses only Mathematica to familiarize participants with the concepts involved in the conformal bootstrap. This will be done using a simplified (and inefficient) workflow to highlight the conceptual problems.

A second tutorial will later appear and show an example workflow using the tools that are actually used in real modern conformal bootstrap computations.

The exercises are not split into problems and solutions. Instead I walk through the process step by step explaining the solution. If you prefer to work out the solutions more independently I will include some guiding exercise questions below. You can then only look at the solution when you get stuck or when something about the questions isn’t clear.

Problem 1 (based on 10.5 from [3]): Bounding the 2D ising model using a simple 2 component functional search space.
	- Evaluate the function F[Δ,L,z,zb] at two points or at two linear combination of points. This gives you a 2 dimensional vector say vF for any value of (Δ,L). 
	- Is there any assumption on the spectrum under which the vectors F[Δ,L] cannot sum up to zero? Hint: Does the set {F[Δ,L] : (Δ,L) ∈ ϕ x ϕ} span more than an interval of π in polar coordinates? What angles do the different spin families reach? How does this change if you impose Δ>(SuperStar[Δ]) for some value (SuperStar[Δ]). Are there some angles that are only reached by (Δ,L=0) for Δ say smaller than 1?
	- If you do not find an interesting bound. Try the combination of F’s in vH below. 
	- If you manage to find a bound by looking at the plots of vF as a function of Δ try to find the same bound in an automated way. For this you will want to use LinearProgramming. Look at the documentation to find out how this can be useful. This function takes as its first argument an objective. We are interested in ( the existence of) any solution so you can take it to simply be an appropriately sized list of zeros. You will want to take m to be some (dense enough) grid (Δ,L) where Δ>(SuperStar[Δ]) and (SuperStar[Δ]) is the bound that you are trying to show. b should then be a 1 followed by zero’s in order to impose strict positivity on one term and non-negativity on all others.

Problem 1b: Three component search space using derivatives. We will see that quite an impressive bound can be found using just the first few derivatives around the point z=zb=1/2. Repeat problem 1 but instead of evaluating F at points in order to construct vF take derivatives around the point z=zb=1/2. You will see that this way a simple choice of a three component functional search space will give impressive bounds.

Problem 2: Ising kink by linear programming using discretized (z,zb) and (Δ,L) grids. This problem is borrowed from Miguel Paulos as presented on the 2017 Bootstrap conference in Brazil. See http://bootstrap.ictp-saifr.org/wp-content-uploads/2017/05/Problems2.pdf.

As an aside: Functional programming in Mathematica

Here should be some bad pun relating the functional in functional programming and the fact that we are looking for a functional ;)

The standard and recommended programming style in Mathematica is functional programming. You will rarely see For or While loops as you see in procedural programming. Instead you will apply functions to lists or lists of lists at some appropriate level.

Some symbols that are used as shorthand can initially be confusing. For example f@arg will give f[arg],  f/@{a,b,c} will give {f[a],f[b],f[c]},   f@@{a,b,c} will give f[a,b,c]. You can select any of these symbol combinations I mentioned such as /@ or any symbol or function you don’t know and hit F1 to get documentation on your selection. Try it on /@ you to see it is called Map. (This does not work for user defined functions. In that case you will have to search where they are defined or enter Definition[function]. )

Some cells below are grey. These are marked as Initialization Cells. When you run the first line of code you will be asked whether you want to run all of these. If you say yes all these definitions will be evaluated automatically. This means you don’t have to go through the whole notebook making sure you evaluate every possibly required line before you can run a section you want to run. (Cells that contain definitions that can be run instantaneously are marked as Initialization Cells. Cells that compute something computationally expensive are not so that the initialization does not take too much time. This means that some cells do require running an immediately preceding cell where something is computed and saved to a variable.)

Finally the definition using both SetDelayed, i.e. := followed by Set, i.e. = is used to indicate that the result of an evaluation should be saved to memory in order to save time on subsequent evaluations.

ClearAll[exampleMemoization];
exampleMemoization[arg_]:=exampleMemoization[arg]=(Wait[3];Print["This lengthy computation will be done only once. Note that on a second evaluation you won't see this Print message."];
1)

exampleMemoization[1]

Rerunning the line with ClearAll[exampleMemoization] will clear all saved values (and re-evaluate the definition).

Numerical Bounds on CFT data.

Here we show in practice how some bounds on CFT data can be found numerically by studying the crossing equation. Familiarity with the theory behind this, as presented  by Alessandro, will be assumed (see also for example [3] for great lecture notes on this).

Bounding the CFT data will be done by assuming some hypothesis on the spectrum and showing that the assumption leads to an inconsistency. Specifically we search search for a linear functional that, under the hypothesis, is non-negative on all terms in the crossing equation and positive on at least one term. The strictly positive term is often chosen to be the contribution of the identity operator. The existence of such a functional proves that the spectrum assumption is inconsistent, thus disproving such a CFT.

First we define a conformal block and a function F that is anti-symmetric under the exchange of the 1st and 3rd point. (I.e. an exchange of z <->zb or u<->v). We consider the D=2 case first since it is easy to compute the conformal block from its analytical expression in terms of Hypergeometric2F1’s.

For identical scalars the conformal block is (there is no dependence on Δ12,Δ34 here because we assume the scalars to be identical).

(* Memoizing to save time on repeat evaluations.*)
ClearAll[G2D,kk,FCrossing,FdividedByF00];
(* The 2d conformal block for identical external scalars:*)
G2D[Δ_,l_,z_,zb_]:=G2D[Δ,l,z,zb]=1/2*(kk[Δ+l,z]*kk[Δ-l,zb]+kk[Δ-l,z]*kk[Δ+l,zb]);
(* where kk is *)
kk[β_,z_]:=kk[β,z]=(z^(β/2))Hypergeometric2F1[β/2,β/2,β,z];
(* The anti function F found in the crossing equation which is anti-symmetric under 
	the exchange of the first and third point.*)
FCrossing[Δϕ_,Δ_,l_,z_,zb_]:=FCrossing[Δϕ,Δ,l,z,zb]=((G2D[Δ,l,z,zb])/((z^(Δϕ))(zb^(Δϕ))))-((G2D[Δ,l,1-z,1-zb])/((((1-z))^(Δϕ))(((1-zb))^(Δϕ))));
(* Sometimes one instead considers F divided by F[Δ=0,L=0,z,zb] , i.e. the one for the identity, 
	that way F for the identity vector is simply 1.*)
FdividedByF00[a_,Δ_,l_,z_,zb_]:=(((((1-z))^a)(((1-zb))^a)G2D[Δ,l,z,zb]-(z^a)(zb^a)G2D[Δ,l,1-z,1-zb])/((z^a)(zb^a)-(((1-z))^a)(((1-zb))^a)));
(* The latter matches what DSD calls H in the Tasi lecture notes.*)

The prefactor that G2D gets convolved with are poorly approximated by a rational function. This will become important when we want to apply semi-definite programming. However when you evaluate at z=zb=1/2 or take derivatives around z=zb=1/2.

D[FCrossing[1/8,x,0,z,zb],z]

While the conformal block is independent of the dimension Δϕ of the external operator the vector F does depend on it. So if we consider many values for Δϕ it can be useful to first save the Conformal Blocks and then separately compute the “dressing” with the Δϕ dependent factors. We will do so later but for this first section it does not matter.

(* This conformal block is symmetric under the exchange of 1 and 2*)
((#/.{z->zb,zb->z})/#)&@G2D[Δ,l,z,zb]

(* The vector F is (by construction) anti-symmetric under the exchange 1<->3*)
((#/.{z->1-zb,zb->1-z})/#)&@FCrossing[Δϕ,Δ,l,z,zb]//Simplify

Visualizing F

Let’s see what the functions F look like at some fixed value of z,zb as a function of x. Here we pick z=zb=0.51. We show a few Δϕ values:

Δϕvalues={0.05,0.1,0.15};
Plot[Evaluate[FCrossing[#,Δ,0,0.51,0.51]&/@Δϕvalues],{Δ,0,2},PlotLegends->Δϕvalues,AxesLabel->{"Δ","F"}]

Δ here is the conformal dimension of the internal operators exchanged in the ϕ x ϕ OPE. (We use ϕ to denote the first scalar. In the case of the Ising model perhaps σ would have been more appropriate.)

Different Δϕ looks somewhat different but are in general continuously connected to each other. This explains why considering different external dimensions gives different but continuously connected bounds.

We can also look what F[z=zb=0.51] looks like for spinning operators. We are interested in unitary theories for which the unitarity bound (Subscript[Δ, L])≥L+d-2 holds. So we plot only that:

lvalues=Range[0,6,2];
Plot[FCrossing[0.1,Δ,#,0.51,0.51],{Δ,#,#+2},PlotLegends->"L="<>ToString[#]]&/@lvalues

You (probably) have seen in the lectures by Alessandro Vichi that the search for a linear functional corresponds to finding a separating plane between the vectors spanned by the operators in the CFT. Here we start by looking at the simplest example of a two dimensional linear functional in which case we only have to look at the angles of V[x,l]. In order for the V[x,l] to be able to add up to zero the convex hull of these V’s should contain 0. Equivalently when we look at V[x,l] in polar coordinates the spectrum must cover more than π worth of angles. Otherwise a “separating” plane / functional exists and the spectrum is excluded.

A simple example with a 2-dimensional functional:

This section is based on [3].

One can parameterize the space of linear functionals acting on F in many ways. One standard way is in terms of derivatives around the self-dual point z=zb=1/2. Another way is to evaluate F at some points.

Here we will consider the simplest functionals, i.e. just evaluating F at some points in (z,zb).

The subspace below is chosen to give a nice bound but other choices are possible and would give other (likely weaker) bounds. Feel free to play around with this.

(* a specific choice of a 2-dimensional functional subspace*)
ClearAll[vH]
vH[Δ_,l_]:={FdividedByF00[1/8,Δ,l,1/2,3/5]-FdividedByF00[1/8,Δ,l,1/2,1/3],
	FdividedByF00[1/8,Δ,l,1/2,3/5]-FdividedByF00[1/8,Δ,l,1/3,1/4]};

We are looking for a separating plane. In the case of a 2D functional we only have to look at the polar coordinate angle θ. There is a separating plane if there is any interval of size π without any operator in the CFT spectrum.

First we can look what angles are reached by the scalar family of operators.

Plot[ToPolarCoordinates[vH[Δ,0]][[2]],{Δ,0,4}]

(*ToPolarCoordinates[vH[(10^(-6)),0]][[2]]//N[#,50]&*)

This looks much more promising. We see that the scalar operators span ~ [-1.74336,1.32507]. The complement is an interval that is a bit larger than π so we can exclude any theory that does not have additional operators. So we know that we need spinning operators as well. Most notably we need to include a stress tensor.

spin0Maxθ=FindMaximum[ToPolarCoordinates[vH[Δ,0]][[2]],{Δ,0.3210188280837586},WorkingPrecision->30]

spin0Maxθ[[1]]-ToPolarCoordinates[vH[(10.^(-4)),0]][[2]]

The stress tensor provides an operator on the other side of the unit circle so that no separating plane exists as long as we have a scalar operator between 0.161 and 1.04:

vT=vH[2,2]//Simplify//N;
vTθ=ToPolarCoordinates[vT][[2]]

(*We pre-compute some points so that the Manipulate figure works better below.*)
pts=Sort[{0.001`,0.001`,0.0010612040816326532`,0.001`,0.05986629373930803`,0.12368410169520885`,0.1832728116228045`,0.24169262760372764`,0.30506395780124357`,0.36420618997045434`,0.4282999363562579`,0.49122478879538894`,0.5499205432062149`,0.6135678118336336`,0.6729859824327472`,0.7312352590851882`,0.7944360499542219`,0.8534077427949505`,0.9173309498522719`,0.9800852629629209`,1.0386104780452645`,1.102087207344201`,1.1613348386148323`,1.2255339841020565`,1.2885642356426081`,1.3473653891548547`,1.411118056883694`,1.4706416265842281`,1.5289963023380897`,1.592302492308544`,1.6513795842506933`,1.7154081904094354`,1.778267902621505`,1.8368985168052692`,1.9004806452056262`,1.9598336755776782`,2.018017812003057`,2.0811534626450294`,2.1400600152586966`,2.2039180820889563`,2.263547050890911`,2.322007125746193`,2.3854187148180683`,2.444601205861638`,2.5087352111218006`,2.571700322435291`,2.630436335720476`,2.6941238632222535`,2.753582292695726`,2.811871828222526`,2.8751128779659187`,2.9341248296810063`,3.`,0.030433146869654017`,0.09177519771725845`,0.15347845665900667`,0.2124827196132661`,0.2733782927024856`,0.33463507388584895`,0.3962530631633561`,1.0093478705040928`,1.0703488426947327`,1.1317110229795166`,1.1934344113584445`,1.2570491098723324`,1.3179648123987313`,1.3792417230192744`,1.440879841733961`,1.4998189644611588`,1.5606493973233169`,1.6218410382796187`,1.6833938873300642`,1.74683804651547`,1.807583209713387`,1.8686895810054476`,1.9301571603916523`,1.9889257437903676`,2.0495856373240433`,2.110606738951863`,2.1719890486738267`,2.233732566489934`,2.292777088318552`,2.3537129202821307`,2.4150099603398534`,2.476668208491719`,2.5402177667785457`,2.6010683290778833`,2.6622800994713645`,2.967062414840503`,0.01571657343482701`,0.07582074572828323`,0.13858127917710777`,0.1978777656180353`,0.25753546015310663`,0.31984951584354626`,0.38022962656690523`,0.9947165667335068`,1.0544796603699986`,1.1168991151618588`,1.1773846249866384`,1.2412915469871946`,1.3032645240206697`,1.3633035560870645`,1.4259989493088274`,1.4852302955226935`,1.5448228498307033`,1.6070717652940814`,1.6673867357903789`,1.7311231184624527`,1.792925556167446`,1.8527940489053583`,1.9153189027986393`,1.974379709684023`,2.03380172466355`,2.095880100798446`,2.1560245319662616`,2.218825324289445`,2.2781620696047318`,2.337860023014162`,2.400214337578961`,2.4606347071766788`,2.524476488950173`,2.586384325756587`,2.64635821759592`,2.9505936222607545`,0.04514972030448103`,0.10772964970623365`,0.1683756341409056`,0.2892211252518646`,0.34942063192815165`,1.0239791742746787`,1.0862180250194668`,1.1465229307971745`,1.2094841977302506`,1.2728066727574703`,1.3326651007767931`,1.3951798899514842`,1.4557607341590946`,1.5144076333996241`,1.5764759448159305`,1.636610311265156`,2.0034717778967126`,2.0653695499845366`,2.12533337710528`,2.1879535653813917`,2.2486398086904225`,2.3073921070323724`,2.3695658175500993`,2.4298055831007455`,2.49270170980676`,2.5559590446069183`,2.983531207420252`,0.008358286717413505`,0.06784351973379563`,0.13113269043615833`,0.1905752886204199`,0.24961404387841712`,0.31245673682239494`,0.3722179082686798`,0.9874009148482139`,1.0465450692076317`,1.1094931612530299`,1.1693597318007354`,1.2334127655446254`,1.2959143798316388`,1.3553344726209597`,1.4185585030962606`,1.4779359610534608`,1.5369095760843965`,1.5996871288013126`,1.659383160020536`,1.7232656544359441`,1.7855967293944754`,1.8448462828553138`,1.9078997740021326`,1.9671066926308507`,2.0259097683333036`,2.088516781721738`,2.148042273612479`,2.211371703189201`,2.2708545602478214`,2.3299335743801777`,2.392816526198515`,2.452617956519158`,2.5166058500359867`,2.579042324095939`,2.638397276658198`,2.9423592259708804`,0.03779143358706752`,0.09975242371174606`,0.16092704539995611`,0.2812997089771751`,0.34202785290700033`,1.0166635223893858`,1.0782834338571`,1.1391169768883456`,1.2014593045443476`,1.2649278913149014`,1.3253149565877622`,1.3872108064853794`,1.4483202879465278`,1.5071132989303915`,1.5685626710696237`,1.6292256747723872`,1.99619876084354`,2.0574775936542897`,2.1179700580285714`,2.179971307027609`,2.241186187590178`,2.300084597675462`,2.361639368916115`,2.4224077717202994`,2.4846849591492397`,2.5480884056927318`,2.9752968111303773`,0.08379797172277084`,0.14602986791805722`,0.3272422948646976`,1.1854095181725415`,1.2491703284297635`,1.3106146682097006`,1.3712726395531694`,2.2262789453896894`,2.285469578961642`,2.3457864716481467`,2.407612148959407`,2.468651457834199`,0.11570687570072125`,0.17582422288185506`,0.29714254152655406`,1.2175090909161534`,1.2806854542000392`,1.3400152449658238`,2.314699616389283`,2.377492266184084`,2.437203394481192`,2.991765603710126`,0.004679143358706752`,0.06385490673655184`,0.1274083960656836`,0.1869240501216122`,0.2456533357410724`,0.3087603473118192`,0.36821204911956706`,0.9837430889055674`,1.042577773626448`,1.1057901842986153`,1.1653472852077837`,1.2294733748233408`,1.2922393077371235`,1.3513499308879071`,1.4148382799899775`,1.4742887938188445`,1.532952939211243`,1.5959948105549282`,1.6553813721356145`,1.7193369224226898`,1.7819323160079903`,1.8408723998302916`,1.9041902096038794`,1.9634701841042643`,2.02196379016818`,2.0848351221833834`,2.144051144435588`,2.2076448926390784`,2.267200805569366`,2.3259703500631854`,2.3891176205082916`,2.4486095811903983`,2.5126705305788937`,2.575371323265615`,2.634416806189337`,2.938242027825943`,0.034112290228360764`,0.09576381071450225`,0.1572027510294814`,0.2773390008398303`,0.3383314633964246`,1.0130056964467393`,1.0743161382759163`,1.135413999933931`,1.197446857951396`,1.260988500593617`,1.3216398844932469`,1.3832262647523268`,1.4446000648402444`,1.5034661316957751`,1.5646060341964703`,1.6255333565260028`,1.992562252316954`,2.0535316154891667`,2.114288398490217`,2.175980177850718`,2.237459377040056`,2.2964308429970073`,2.3576761445991226`,2.4187088660300766`,2.4806765838204794`,2.5441530862356387`,2.9711796129854404`,0.07980935872552704`,0.1423055735475825`,0.3235459053541219`,1.1813970715795898`,1.2452309377084791`,1.306939596115185`,1.367288097820117`,2.2225521348395674`,2.281815824283187`,2.3418232473311544`,2.4039132432691837`,2.4646430825054386`,0.11171826270347746`,0.17209992851138034`,0.29318183338920933`,1.213496644323202`,1.2767460634787549`,1.3363401728713085`,2.3110458617108276`,2.3735290418670916`,2.4335044887909687`,2.9876484055651886`,0.13485698480663305`,0.3161531263329706`,1.23735215626591`,1.2995894519261544`,2.33389679869717`,2.396515431888738`,0.10374103670898985`,0.16465133977043084`,1.2688672820361857`,1.3289900286822776`,2.365602593233107`,2.426106677410522`,0.14975416228853194`,1.2531097191510479`,1.314289740304216`,2.349749695965139`,2.41131105464963`,0.11969548869796505`,1.2846248449213236`,2.381455490501076`,2.995882801855063`,0.002839571679353376`,0.061860600237929934`,0.12554624888044624`,0.18509843087220834`,0.24367298167240004`,0.30691215255653137`,0.3662091195450107`,0.9819141759342441`,1.0405941258358564`,1.1039386958214081`,1.163341061911308`,1.2275036794626986`,1.290401771689866`,1.349357660021381`,1.4129781684368359`,1.4724652102015363`,1.5309746207746664`,1.5941486514317362`,1.6533804781931538`,1.7173725564160627`,1.7801001093147475`,1.8388854583177805`,1.9023354274047528`,1.9616519298409711`,2.0199908010856187`,2.0829942924142064`,2.1420555798471423`,2.2057814873640176`,2.2653739282301384`,2.3239887379046893`,2.38726816766318`,2.446605393526018`,2.510702870850347`,2.573535822850453`,2.632426570954906`,2.9361834287534747`,0.03227271854900739`,0.09376950421588034`,0.15534060384424403`,0.27535864677115796`,0.33648326864113676`,1.011176783475416`,1.0723324904853246`,1.1335625114567238`,1.1954406346549202`,1.2590188052329747`,1.319802348445989`,1.3812339938858007`,1.4427399532871026`,1.501642548078467`,1.5626277157598936`,1.6236871974028109`,1.9907439980536608`,2.051558626406605`,2.11244756872104`,2.1739846132622724`,2.2355959717649947`,2.29460396565778`,2.3556945324406264`,2.416859413184965`,2.4786723961560995`,2.5421854265070922`,2.9691210139129716`,0.07781505222690513`,0.14044342636234514`,0.3216977105988341`,1.1793908482831141`,1.2432612423478369`,1.3051020600679273`,1.3652958269535906`,2.220688729564506`,2.279988946943959`,2.3398416351726583`,2.402063790424072`,2.4626388948410587`,0.10972395620485556`,0.17023778132614298`,0.29120147932053697`,1.2114904210267263`,1.2747763681181126`,1.334502636824051`,2.3092189843716`,2.3715474297085954`,2.431655035945857`,2.98558980649272`,0.1329948376213957`,0.3143049315776828`,1.2353824609052677`,1.2977519158788966`,2.331915186538674`,2.3946659790436264`,0.10174673021036795`,0.16278919258519348`,1.2668975866755434`,1.3271524926350198`,2.363620981074611`,2.4242572245654106`,0.14789201510329458`,1.2511400237904056`,1.3124522042569584`,2.347768083806643`,2.4094616018045185`,0.11770118219934314`,1.2826551495606813`,2.37947387834258`,2.9938242027825943`,0.12927054325092097`,0.3106085420671071`,1.294076843784381`,2.390967073353403`,0.15906489821471875`,1.2629581959542593`,2.3596577567576187`,0.14416772073281986`,1.2472006330691214`,1.3087771321624428`,2.3438048594896506`,2.4057626961142953`,1.2787157588393971`,2.3755106540255877`,0.1367191319918704`,0.3180013210882584`,1.3014269879734122`,2.3983648847338497`,1.270836977396828`,2.367584205391603`,0.1516163094737693`,0.12168979519658696`,1.2865945402819658`,2.383437102659572`,2.9979414009275316`,0.001919785839676688`,0.06086344698861898`,0.12461517528782755`,0.18418562124750643`,0.24268280463806385`,0.3059880551788875`,0.36520765475773254`,0.9809997194485824`,1.0396023019405605`,1.1030129515828047`,1.1623379502630702`,1.2265188317823776`,1.289483003666237`,1.348361524588118`,1.412048112660265`,1.4715534183928822`,1.529985461556378`,1.59322557187014`,1.6523800312219237`,1.716390373412749`,1.7791840059681263`,1.837891987561525`,1.9014080363051895`,1.9607428027093246`,2.019004306544338`,2.082073877529618`,2.1410577975529197`,2.2048497847264867`,2.2644604895605247`,2.3229979318254412`,2.386343441240624`,2.445603299693828`,2.5097190409860737`,2.5726180726428716`,2.631431453337691`,2.9351541292172403`,0.031352932709330705`,0.0927723509665694`,0.15440953025162535`,0.2743684697368218`,0.3355591712634929`,1.0102623269897544`,1.0713406665900287`,1.1326367672181203`,1.1944375230066824`,1.2580339575526536`,1.3188835804223602`,1.3802378584525377`,1.4418098975105318`,1.500730756269813`,1.561638556541605`,1.6227641178412147`,1.9898348709220142`,2.050572131865324`,2.1115271538364517`,2.17298683096805`,2.2346642691274643`,2.293690526988166`,2.354703726361379`,2.415934686762409`,2.4776703023239093`,2.5412015966428187`,2.9680917143767376`,0.07681789897759418`,0.13951235276972646`,0.3207736132211902`,1.1783877366348763`,1.2422763946675157`,1.3041832920442986`,1.3642996915203276`,2.2197570269269757`,2.2790755082743455`,2.3388508290934102`,2.4011390640015167`,2.4616368010088685`,0.1087268029555446`,0.1693067077335243`,0.2902113022862008`,1.2104873093784885`,1.2737915204377914`,1.333583868800422`,2.308305545701986`,2.3705566236293474`,2.4307303095233013`,2.984560506956486`,0.132063764028777`,0.31338083420003887`,1.2343976132249466`,1.2968331478552677`,2.3309243804594257`,2.3937412526210706`,0.100749576961057`,0.1618581189925748`,1.2659127389952225`,1.326233724611391`,2.362630174995363`,2.4233324981428552`,0.1469609415106759`,1.2501551761100846`,1.3115334362333295`,2.3467772777273948`,2.4085368753819627`,0.1167040289500322`,1.2816703018803604`,2.378483072263332`,2.9927949032463603`,0.12833946965830229`,0.30968444468946316`,1.2931580757607524`,2.3900423469308474`,0.15813382462210007`,1.2619733482739381`,2.3586669506783706`,0.14323664714020118`,1.2462157853888003`,1.307858364138814`,2.3428140534104025`,2.4048379696917395`,1.277730911159076`,2.3745198479463396`,0.13578805839925173`,0.31707722371061453`,1.3005082199497833`,2.397440158311294`,1.2698521297165068`,2.366593399312355`,0.15068523588115063`,0.120692641947276`,1.2856096926016447`,2.382446296580324`,2.996912101391297`,0.12647732247306492`,1.2913205397134946`,2.3881928940857358`,0.1562716774368627`,0.14137449995496382`,1.2757612157984337`,2.3725382357878435`,0.13392591121401437`,0.3152290289553267`,1.2678824343558646`,2.364611787153859`,0.14882308869591326`,1.2836399972410024`,2.380464684421828`,0.13020161684353965`,0.15999597180733743`,0.14509879432543854`,1.279700606519718`,2.3765014601048358`,0.1376502055844891`,1.2718218250771491`,2.3685750114708513`,0.152547383066388`,1.287579387962287`,2.3844279087388203`,2.998970700463766`}];
HatPts=Function[x,If[Sow[x];x>spin0Maxθ[[2,1,2]],0.97,1]*Append[Normalize[vH[x,0]],x]]/@pts;
colors=(Hue[Rescale[#,{0,3}]]&/@Last/@HatPts);
vertexColorOption:=VertexColors->colors;

Below we show the angle for the L=0 and L=2 families of operators. (Odd L are not exchanged in the OPE of two identical scalars due to their permutation symmetry.) For the L=0 we indicate the Δ value by the color of the line.

Show[
Legended[ListLinePlot[HatPts[[All,1;;2]]
,PlotRange->{{-1.05,1.05},{-1.05,1.05}}
,AspectRatio->1
,ColorFunction->Function[{x,y},Hue@y]
]/.HoldPattern[VertexColors->Automatic]:>vertexColorOption

,BarLegend[{Hue,{0,3}},LegendLabel->"(Subscript[Δ, s])     ",LabelStyle->{Black,16}]]
,
ParametricPlot[{Normalize[vH[x,2]]},{x,2,3},Mesh->False,PlotRange->{{-1.05,1.05},{-1.05,1.05}},PlotStyle->ColorData[97][2]]
,Graphics[{ColorData[97][2],AbsolutePointSize[4],Point[Normalize[vH[2,2]]]}]
,Graphics[{Dashed,Line[{FromPolarCoordinates[{1,vTθ}],
FromPolarCoordinates[{1,vTθ+π}]}]}]
]

Another way of phrasing: In order for the vectors in the spectrum to add up to zero the convex hull of those operators in the figure above has to contain 0. This happens for example if the spectrum includes the stress tensor, a scalar operator to the left of the dashed line and any scalar operator to the right (such as for example the identity operator).

The orange line corresponds to the spin-2 family of operators. The stress tensor at the start of this spectrum is represented by the orange dot. The brightly colored line corresponds to the spin-0 spectrum and the color represents the value of Δ. The dashed line gives a separating plane unless there is a scalar operator with a dimension 0.161<(Subscript[Δ, s])<1.03 so that it lies on the other side of it.

roots=FindRoot[ToPolarCoordinates[vH[Δ,0]][[2]]-(vTθ+π),{Δ,#}]&/@{0.15,1.05}

Show[
Plot[ToPolarCoordinates[vH[Δ,0]][[2]](*-(vTθ+π)*),{Δ,0.1,1.1}]
,
Graphics[Point[{Δ,ToPolarCoordinates[vH[Δ,0]][[2]]}/.roots]]
]

Same but here you can manipulate ((Subscript[Δ, s])^max) to see it progress:

Manipulate[
Column[{
Dynamic["((Subscript[Δ, s])^max)="<>ToString[HatPts[[ii,3]]]]
,
Show[
Legended[ListLinePlot[HatPts[[1;;ii,1;;2]]
,PlotRange->{{-1.05,1.05},{-1.05,1.05}}
,AspectRatio->1
,ColorFunction->Function[{x,y},Hue@y]
]/.HoldPattern[VertexColors->Automatic]:>vertexColorOption

,BarLegend[{Hue,{0,3}},LegendLabel->"(Subscript[Δ, s])     ",LabelStyle->{Black,16}]]
,
ParametricPlot[{Normalize[vH[Δ,2]]},{Δ,2,3},Mesh->False,PlotRange->{{-1.05,1.05},{-1.05,1.05}},PlotStyle->ColorData[97][2]]
,Graphics[{ColorData[97][2],AbsolutePointSize[4],Point[Normalize[vH[2,2]]]}]
,Graphics[{Dashed,Line[{FromPolarCoordinates[{1,vTθ}],
FromPolarCoordinates[{1,vTθ+π}]}]}]
]
}]
,{ii,1,Length[HatPts]}]

It turns out that higher spin operators are not important to consider for this small vector space (they lie in between) the stress tensor and -π/2. As an exercise try adding them in the above figure.

The 2D ising model has (Subscript[Δ, ϕ])=1/8 and (Subscript[Δ, ϵ])=1 so the upper bound is already quite close to being saturated by the 2D Ising model.

Say we wanted to exclude a CFT with a stress tensor and without any scalar operator with a dimension below 1.05. We would then look for a functional that is positive on the stress tensor and non-negative on all scalar operators with Δ>1.05. In the above we found such a functional. It is given by.

(* We subtract a little bit to make sure the functional is STRICTLY positive on at least one term, namely the stress tensor.*)
(* the functional is given by the vector perpendicular to the plane itself.*)
α=FromPolarCoordinates[{1,(vTθ-(10^(-5)))+π/2}]

(*Strictly positive term:*)
α.vH[2,2]

(* Positive for all x>1.05*)
Plot[α.vH[Δ,0],{Δ,1,1.1}]

Plot[α.vH[Δ,0],{Δ,1,3}]

One can try to repeat this game with a higher dimensional search space for the functional to find stronger bounds. The reader is encouraged to try this with for example a 3-dimensional functional. However, as the dimensionality of the search space increases this will quickly become cumbersome to solve by hand. So now we will look for an automatized way to find a functional.

Find α automatically

Here we found α by hand by looking at the plots. How would we solve this problem automatically?

Above we checked positivity on all Δ by plotting the function. Of course we only checked certain regions so strictly speaking we should be more careful. How do we automate this process? There are multiple ways, one more rigorous than the other. Here we will consider the simplest approach: discretizing the space Δ.

Another more rigorous way to demand positivity for all x is using a theorem that relates positivity of a matrix of polynomials M(x) to the existence of a certain decomposition which can be found or whose existence can be ruled out using semi-definite programming (the number of constraints in the resulting semi-definite program is finite and controlled by the order of the polynomial). We will see this later.

tab0=vH[#,0]&/@Join[Range[1.05,3,0.05],{4.,6.,9.,14.}];
tab2=vH[#,2]&/@Join[Range[2,3,0.05],{4.,6.,9.,14.}];

Note that vH[0,0] is 0 so we can leave out the identity operator. In other cases it will be essential not to forget it!

What if we forget the higher spins:

LinearProgramming[{0,0},tab0,Join[{1},Array[0&,43]],None]

Plot[{17.34195609570456`,-1.0028685415669276`}.vH[x,0],{x,1,1.1}]

This is positive below 1.036... So I think I can already predict it is probably not positive on the stress tensor:

(* We did not demand positivity on the stress tensor and indeed did not get it.*)
{17.34195609570456`,-1.0028685415669276`}.vH[2,2]

So let’s add the stress tensor also to the positivity constraints.

VList=Join[tab0,tab2];
bVec=Join[{1},Array[0&,Length[VList]-1]];
solα=LinearProgramming[{0,0},VList,bVec,None]

solα.vH[2,2]

Plot[solα.vH[x,0],{x,0,2}]

It dips below zero between 0 and 1.05 as was allowed.

What if we look for a bound that is better than we think is possible given our analytical analysis above:

tab0=vH[#,0]&/@Join[Range[0.95,3,0.05],{4.,6.,9.,14.}];
tab2=vH[#,2]&/@Join[Range[2,3,0.05],{4.,6.,9.,14.}];

VList=Join[tab0,tab2];
bVec=Join[{1},Array[0&,Length[VList]-1]];
solα=LinearProgramming[{0,0},VList,bVec,None]

No solution can be found.

a 3-dimensional functional

nmax=8; (* Compute derivatives {m,n} up to m+n<nmax.*)

We pick derivatives in the σ and τ directions (you could also take derivatives in the z or zb directions).

(* First we compute the series up to nmax of ((FCrossing[identity])^(-1))*)
(((1-z))^(Δϕ))(((1-zb))^(Δϕ))(z^(Δϕ))(zb^(Δϕ))/((z^(Δϕ))(zb^(Δϕ))-(((1-z))^(Δϕ))(((1-zb))^(Δϕ)))/.{z->1/2+κ a+I κ b,zb->1/2+κ a-I κ b};
ser=Series[a κ%,{κ,0,nmax}]//Simplify;
globalPrefactor=Normal[%]/.κ->1;

ClearAll[F,s1,v1,v2,v3];
F[Δϕ_,Δ_,l_,z_,zb_]=FCrossing[Δϕ,Δ,l,z,zb]*globalPrefactor;
Table[
With[{l=l},
v0[l]=F[Δϕ,Δ,l,z,zb]/.{z->1/2+a+I b,zb->1/2+a-I b};
v1[l]=D[v0[l],a]/.{a->0,b->0}//Simplify;
v2[l]=D[v0[l],a,a,a]/3!/.{a->0,b->0}//Simplify;
v3[l]=D[v0[l],a,b,b]/2!/.{a->0,b->0}//Simplify;
]
,{l,{0,2,4}}];

We consider the first three non-zero components.

ClearAll[vecF3dimensional];
vecF3dimensional[l_]={v1[l],v2[l],v3[l]};

We normalize on the identity (we can get rid of one of the components by dividing the others by it and we are back to 2 so we again only need to consider the polar angle of a vector).

vecF3dimensional[0]/.Δϕ->1/8/.Δ->0

ClearAll[vecFreduced];
vecFreduced[l_]:=-{v2[l]/v1[l],v3[l]/v1[l]};

Here when we divide by v1 we have to be careful. It works here and we find the correct bound but that is because

Plot[
ToPolarCoordinates[vecFreduced[0]/.Δϕ->1/8][[2]]
,{Δ,0,5},PlotRange->All]

(* We precompute points for a plot (for permformance reasons in the Manipulate below).*)
Block[{Δϕ=1/8},
	pts2=Sort@{0.058885922380101395`,0.12272501003188614`,0.18233358948596648`,0.24077288523213833`,0.30416534624999353`,0.3633272990701443`,0.4274424171619785`,0.4903882515459042`,0.5491035777321255`,0.61277206919003`,0.6722100524502302`,0.730478752002522`,0.7937006168264971`,0.8526919734527677`,0.9166364953507217`,0.9794117335407672`,1.0379564635331082`,1.1014543587971328`,1.160721745863453`,1.2249422982014564`,1.2879935668315514`,1.3468143272639421`,1.410588252968016`,1.4701316704743856`,1.5285058042728468`,1.591833103342991`,1.6509298942154311`,1.7149798503595546`,1.7778605227957696`,1.83651068703428`,1.9001140165444739`,1.9594868378569634`,2.017690375461544`,2.080847078337808`,2.1397732730163677`,2.2036526329666106`,2.263301484719149`,2.321781052763779`,2.385213786080093`,2.444416011198702`,2.5085714015889944`,2.571557508271378`,2.630313106756058`,2.694021870512421`,2.7535001260710796`,2.8118090979218295`,2.875071235044263`,2.9341028639689917`,3.`,0.029442961190050698`,0.09080546620599377`,0.15252929975892632`,0.2115532373590524`,0.2724691157410659`,0.33374632266006893`,0.9480241144457444`,1.0086840985369376`,1.0697054111651205`,1.1310880523302929`,1.1928320220324546`,1.2564679325165038`,1.3174039470477468`,1.3787012901159792`,1.4403599617212008`,1.499318737373616`,1.560169453807919`,1.6213814987792112`,2.967051431984496`,0.014721480595025349`,0.07484569429304758`,0.13762715489540622`,0.19694341342250943`,0.25662100048660214`,0.31895583445503123`,0.932330304898233`,0.9940479160388525`,1.0538309373491144`,1.116271205563713`,1.1767768839479538`,1.24070511535898`,1.302698756939649`,1.3627578086899605`,1.4254741073446084`,1.4847252039240009`,1.544337629040383`,1.6066073010611013`,2.9505771479767438`,0.044164441785076045`,0.10676523811893995`,0.1674314446224464`,0.22616306129559538`,0.28831723099552975`,1.0233202810350228`,1.0855798849811267`,1.1459048990968728`,1.2088871601169555`,1.2722307496740277`,1.3321091371558444`,1.3946447715419976`,1.4552458160977932`,1.5139122708232313`,2.983525715992248`,0.007360740297512674`,0.06686580833657449`,0.13017608246364618`,0.18963850145423794`,0.24869694285937022`,0.3115605903525124`,0.9244834001244773`,0.9867298247898098`,1.0458937004411113`,1.108862782180423`,1.1687493149057033`,1.2328237067802181`,1.2953461618856004`,1.3547860679769514`,1.4180311801563121`,1.4774284371991933`,1.5364217166566148`,1.599220202202046`,2.9423400059728677`,0.03680370148756337`,0.09878535216246687`,0.15998037219068637`,0.2188581493273239`,0.28039317336829783`,1.0160021897859801`,1.0776426480731236`,1.1384964757135827`,1.200859591074705`,1.2643493410952658`,1.3247565421017957`,1.3866730308289883`,1.447802888909497`,1.5066155040984237`,2.975288573988372`,0.022082220892538022`,0.08282558024952066`,0.14507822732716627`,0.3263510785575501`,1.1848044529902042`,1.248586523937742`,1.3100513519936978`,1.3707295494029699`,0.11474512407541304`,0.17488251705420643`,1.216914729159206`,1.2801121582527895`,1.3394617322098932`,2.991762857996124`,0.003680370148756337`,0.06287586535833795`,0.12645054624776617`,0.18598604547010222`,0.24473491404575426`,0.3078629683012529`,0.9205599477375994`,0.9830707791652884`,1.0419250819871098`,1.1051585704887779`,1.164735530384578`,1.2288830024908373`,1.291669864358576`,1.3508001976204467`,1.414309716562164`,1.4737800538367893`,1.5324637604647307`,1.5955266527725187`,2.93822143497093`,0.03312333133880704`,0.09479540918423032`,0.15625483597480633`,0.21520569334318815`,0.2764311445546819`,1.0123431441614588`,1.073674029619122`,1.1347922640219377`,1.1968458065535799`,1.2604086368058849`,1.3210802445747714`,1.3826871604724837`,1.4440814253153489`,1.5029671207360198`,2.971170002986434`,0.018401850743781686`,0.07883563727128412`,0.14135269111128623`,0.3226534565062906`,1.180790668469079`,1.244645819648361`,1.3063750544666735`,1.3667436790464653`,0.1107551810971765`,0.17115698083832642`,1.2129009446380807`,1.2761714539634086`,1.3357854346828688`,2.987644286994186`,0.011041110446269011`,0.1339016186795262`,0.31525821240377183`,1.2367644110695992`,1.2990224594126247`,0.10277529514070341`,0.1637059084065664`,1.2682900453846466`,1.32843283962882`,0.1488037635430463`,1.252527228227123`,1.3137276495207222`,0.11873506705364958`,0.17860805327008644`,1.2840528625421705`,2.9958814289980618`,0.0018401850743781686`,0.060880893869219674`,0.12458777813982616`,0.18415981747803434`,0.24275389963894628`,0.3060141572756232`,0.9185982215441606`,0.9812412563530277`,1.0399407727601089`,1.1033064646429553`,1.1627286381240154`,1.2269126503461467`,1.2898317155950636`,1.3488072624421945`,1.41244898476509`,1.4719558621555875`,1.5304847823687888`,1.5936798780577548`,2.936162149469961`,0.031283146264428865`,0.09280043769511204`,0.15439206786686632`,0.2133794653511203`,0.2744501301478739`,1.0105136213491983`,1.0716897203921212`,1.1329401581761154`,1.1948389142930171`,1.2584382846611943`,1.319242095811259`,1.3806942252942314`,1.4422206935182749`,1.501142929054818`,2.969110717485465`,0.01656166566940352`,0.07684066578216585`,0.13948992300334623`,0.3208046454806609`,1.1787837762085163`,1.2426754675036706`,1.3045369057031613`,1.364750743868213`,0.10876020960805823`,0.16929421273038642`,1.210894052377518`,1.274201101818718`,1.3339472859193566`,2.985585001493217`,0.009200925371890843`,0.1320388505715862`,0.3134094013781421`,1.2347940589249087`,1.2971843106491125`,0.10078032365158514`,0.1618431402986264`,1.2663196932399563`,1.326594690865308`,0.1469409954351063`,1.2505568760824324`,1.31188950075721`,0.11674009556453131`,0.17674528516214644`,1.28208251039748`,2.993822143497093`,0.005520555223134506`,0.12831331435570617`,1.2935080131220882`,0.0967903806733486`,0.15811760408274633`,1.2623789889505752`,0.14321545921922624`,1.2466161717930515`,1.3082132032301856`,0.11275015258629477`,0.17301974894626643`,1.2781418061080991`,0.13576438678746622`,0.31710702342940156`,1.300860608176137`,0.10477026662982168`,0.1655686765145064`,1.2702603975293372`,0.1506665316509863`,0.12073003854276787`,1.2860232146868609`,2.997940714499031`,0.0009200925371890843`,0.05988340812466053`,0.12365639408585616`,0.1832467034820004`,0.2417633924355423`,0.3050897517628084`,0.9176173584474412`,0.9803264949468975`,1.0389486181466085`,1.102380411720044`,1.1617251919937341`,1.2259274742738016`,1.2889126412133076`,1.3478107948530682`,1.4115186188665532`,1.4710437663149865`,1.5294952933208177`,1.5927564907003728`,2.9351325067194765`,0.030363053727239783`,0.09180295195055291`,0.15346068381289632`,0.21246635135508635`,0.2734596229444699`,1.0095988599430679`,1.0706975657786209`,1.1320141052532042`,1.193835468162736`,1.257453108588849`,1.318323021429503`,1.3796977577051053`,1.441290327619738`,1.500230833214217`,2.9680810747349806`,0.015641573132214433`,0.0758431800376067`,0.13855853894937623`,0.3198802399678461`,1.177780330078235`,1.2416902914313255`,1.303617831321405`,1.3637542762790869`,0.10776272386349908`,0.16836282867641642`,1.2098906062472368`,1.2732159257463729`,1.3330282115376004`,2.9845553587427327`,0.00828083283470176`,0.13110746651761618`,0.31248499586532724`,1.2338088828525633`,1.2962652362673563`,0.099782837907026`,0.16091175624465637`,1.2653345171676111`,1.3256756164835517`,0.14600961138113627`,1.2495717000100872`,1.3109704263754538`,0.11574260981997217`,0.17581390110817643`,1.2810973343251346`,2.9927925007466083`,0.004600462685945422`,0.12738193030173617`,1.292588938740332`,0.09579289492878945`,0.15718622002877633`,1.26139381287823`,0.14228407516525624`,1.2456309957207061`,1.3072941288484294`,0.11175266684173563`,0.17208836489229642`,1.277156630035754`,0.13483300273349622`,0.3161826179165867`,1.2999415337943807`,0.10377278088526254`,0.1646372924605364`,1.2692752214569918`,0.1497351475970163`,0.11973255279820873`,1.2850380386145157`,2.9969110717485465`,0.002760277611567253`,0.12551916219379616`,1.2907507899768198`,0.15532345192083633`,0.14042130705731623`,0.10975769535261737`,0.17022559678435642`,1.2751862778910632`,0.1329702346255562`,1.2673048693123015`,0.1478723794890763`,0.11773758130909046`,1.2830676864698254`,0.12924469840967617`,0.15904898813671636`,0.14414684327319627`,0.11374763833085391`,1.2791269821804443`,0.13669577084143622`,0.31803142894221637`,0.1665000605684764`,1.2712455736016826`,0.15159791570495632`,0.121727524287327`,1.287008390759206`,2.998970357249515`};
	FAtPts=Function[x,Append[Normalize[vecFreduced[0]]/.Δ->x,x]]/@pts2;
	colors2=(Hue[Rescale[#,{0,3}]]&/@Last/@FAtPts);
	vertexColorOption2=VertexColors->colors2;
]

vecFreduced[0]/.Δϕ->1/8/.Δ->100//N//ToPolarCoordinates

Limit goes to -π.

(* Lies within the spin-2 arc.*)
(*spin4Plot=Show[
ParametricPlot[{Normalize[vecFreduced[4]]/.Δϕ->1/8},{Δ,4,10},Mesh->False,PlotRange->{{-1.05,1.05},{-1.05,1.05}},PlotStyle->ColorData[97][3]]
,
Graphics[{ColorData[97][2],AbsolutePointSize[4],Point[Normalize[vecFreduced[2]/.Δϕ->1/8/.Δ->2]]}]
,
Graphics[{ColorData[97][4],AbsolutePointSize[4],Point[Normalize[vecFreduced[4]/.Δϕ->1/8/.Δ->4]]}]
]*)

(*{plt,xpts}=Reap[ParametricPlot[Normalize[vecFreduced[0]/.Δϕ->1/8],{Δ,0,3}
,PlotRange->All
,EvaluationMonitor:>Sow[Δ]]]*)

spin2Plot=Show[
ParametricPlot[{Normalize[vecFreduced[2]]/.Δϕ->1/8},{Δ,2,10},Mesh->False,PlotRange->{{-1.05,1.05},{-1.05,1.05}},PlotStyle->ColorData[97][2]]
,
Graphics[{ColorData[97][2],AbsolutePointSize[4],Point[Normalize[vecFreduced[2]/.Δϕ->1/8/.Δ->2]]}]
];

Manipulate[
Column[{
Dynamic["((Subscript[Δ, s])^max)="<>ToString[FAtPts[[ii,3]]]]
,
Show[
Legended[ListLinePlot[FAtPts[[1;;ii,1;;2]]
,PlotRange->{{-1.05,1.05},{-1.05,1.05}}
,AspectRatio->1
,ColorFunction->Function[{x,y},Hue@y]
]/.HoldPattern[VertexColors->Automatic]:>vertexColorOption2
,BarLegend[{Hue,{0,3}},LegendLabel->"(Subscript[Δ, s])     ",LabelStyle->{Black,16}]]

,
spin2Plot
]
}]
,{{ii,10},1,Length[FAtPts],1}]

θminT=vecFreduced[2]/.Δϕ->1/8/.Δ->2//ToPolarCoordinates[#][[2]]&//N[#,10]&

(*In this case positivity on the identity was already guaranteed by the normalization of the 3 component functional:*)
(*vecFreduced[0]/.Δϕ->1/8/.Δ->0*)

We see that we need an operator roughly above Δ>1.

Plot[ToPolarCoordinates[vecFreduced[0]/.Δϕ->1/8][[2]]-θminT+π,{Δ,0,2},PlotRange->All]

FindRoot[ToPolarCoordinates[vecFreduced[0]/.Δϕ->1/8][[2]]-θminT+π,{Δ,1.03}]

Here we find quite a good bound using just a quite naive 3 component functional!

Other Δϕ values

θminTV2=vecFreduced[2]/.Δ->2/.Δϕ->0.1//ToPolarCoordinates[#][[2]]&//N[#,10]&;
Plot[ToPolarCoordinates[vecFreduced[0]][[2]]-θminTV2+π/.Δϕ->0.1,{Δ,0,2},PlotRange->All]
FindRoot[ToPolarCoordinates[vecFreduced[0]/.Δϕ->0.1][[2]]-θminT+π,{Δ,1.03}]

allowedGap[deltaPhi_]:=With[{Δinsert=deltaPhi},
	Block[{Δϕ=Δinsert},
		θT[Δϕ]=vecFreduced[2]/.Δ->2//ToPolarCoordinates[#][[2]]&//N[#,10]&;
		{Plot[ToPolarCoordinates[vecFreduced[0]][[2]]-θT[Δϕ]+π,{Δ,0,2},PlotRange->All]
		,FindRoot[ToPolarCoordinates[vecFreduced[0]][[2]]-θT[Δϕ]+π,{Δ,1.03}]}
	]
]

threeComponentBound={#,allowedGap[#]}&/@{0.05,0.08,0.09,0.1,0.11,0.12,0.13,0.14}

ListPlot[{#1,#2[[2,1,2]]}&@@@threeComponentBound]

The bounds are not bad, but they don’t show the kink at all. A few more components would be required. (Also we did not check that the functional is positive on all other channels although it probably is.)

Numerics: Higher dimensional functional search space

Pick a grids for (z,zb) and (Δ,L)

First we set how many components the functional should have, the precision with which it should get evaluated, the max spin and dimension to be considered and the step size used to compute the grid in the dimension.

We reduce the infinite dimensional functional search space to a finite dimensional one by taking it to be some combination F[z,zb] for a grid of points in (z,zb). We demand positivity only on a fixed grid of pairs (Δ,L).

nmax=5;prec=30;LMax=8;step=1/10;DMax=40;
Zgrid=Table[{(1/2)+r (E^(I ϕ)),(1/2)+r (E^(-I ϕ))},{r,(1/nmax),(1/2)-(10^(-9)),(1/nmax)},{ϕ,0,(π/2)-(10^(-9)),(π/nmax)}]//Flatten[#,1]&;
Dgrid=Table[{Δ,L},{L,0,LMax,2},{Δ,L+(10^(-3)),DMax,step}]//Flatten[#,1]&;
DgridDense=Table[{Δ,L},{L,0,LMax,2},{Δ,L+(10^(-3)),DMax,step/3}]//Flatten[#,1]&; (*Used to check whether the positivity that we demanded implies positivity on the points in between.*)

It is more efficient to split the block computation into two parts. One that does the Δϕ independent computation and one that does the final convolution with the Δϕ dependent part.

Compute block tables

Compute tables of conformal blocks evaluated at the different (z,zb) points.

ClearAll[gridQ,G2Dnum,ConformalBlockTables]

gridQ[ls_]:=MatchQ[Dimensions[ls],{n_Integer,2}];


crossZgrid[Zgrid_?gridQ]:={1-#1,1-#2}&@@@Zgrid;
G2Dnum[Δ_?NumericQ,l_,Zgrid_?gridQ]:=G2Dnum[Δ,l,Zgrid]=(Re/@Map[
	SetPrecision[(kk[Δ+l,#[[1]]]*kk[Δ-l,#[[2]]]+kk[Δ-l,#[[1]]]*kk[Δ+l,#[[2]]]),prec]&,Zgrid]); 

(* Memoized, we will be reusing this for different values of Δϕ.*)
(* Outputs two list one for (z,zb) and one for (1-z,1-zb), one element of one such list has the format {{Δ,l},{G[Δ,l,zzb1],G[Δ,l,zzb2]...}}*)
ConformalBlockTables[Zgrid_List,Dgrid_List]:=ConformalBlockTables[Zgrid,Dgrid]=Module[{BlockTable,Δ,inds,i,L,CBlockTable},
	Table[
		{{d,G2Dnum[d[[1]],d[[2]],Zgrid]}, {d,G2Dnum[d[[1]],d[[2]],crossZgrid[Zgrid]]}}
	,{d,Dgrid}]//Transpose
];
(* If this takes long you can try replacing Table with ParallelTable to parallelize it.*)

Do the convolution with the Δϕ dependent part. This will need to be done multiple times for different values of Δϕ but it will be fast after the first time since we already saved the Δϕ-independent part of the computation.

ClearAll[FConvolvedBlocks]
FConvolvedBlocks[Δϕ_,Zgrid_,Dgrid_]:=FConvolvedBlocks[Δϕ,Zgrid,Dgrid]=Module[{FTable,z,zb,i,zzb,Czzb},
	{BlockTable,CrossedTable}=ConformalBlockTables[Zgrid,Dgrid];
	
	zzb=Table[(z^(Δϕ)) (zb^(Δϕ))/.z->Z[[1]]/.zb->Z[[2]],{Z,Zgrid}];
	Czzb=Table[(((1-z))^(Δϕ)) (((1-zb))^(Δϕ))/.z->Z[[1]]/.zb->Z[[2]],{Z,Zgrid}];
	FTable=MapIndexed[
		{#1,Re[SetPrecision[((BlockTable[[#2[[1]],2]])/zzb)-((CrossedTable[[#2[[1]],2]])/Czzb),prec]]}&,Dgrid];
	FTable
];

ClearAll[FConvolvedSingleBlock]
FConvolvedSingleBlock[Δϕ_,Zgrid_,DL_List]:=FConvolvedBlocks[Δϕ,Zgrid,{DL}][[1]];
FConvolvedSingleBlock[other___]:=(Print["invalid arg for FConvolvedSingleBlock"];Abort[])

We can also add a function (Subscript[D, (SuperStar[Δ])])F above to our constraints. This imposes that the functional should pass through Δ* increasing as Δ increases. Indeed we would demand positivity on Δ≥(SuperStar[Δ]) in a continuous way this would be required. Adding this can be helpful.
(Feel free to test the difference. You might find that no functional can be found even when a functional does exist. There are some downsides to the simplified methods presented in this notebook.)

ClearAll[DF];
DF[Δϕ_,{gap_,L_}]:=(eps^(-1))(FConvolvedSingleBlock[Δϕ,Zgrid,{gap+eps,L}][[2]]-FConvolvedSingleBlock[Δϕ,Zgrid,{gap,L}][[2]])

Find a functional using linear programming

(*VListWithLabelΔL should be the convolved block table including the {Δ,L} label as the first entry.
 The identity should not be included since it will be added here.*)
eps=(10^(-7));

CheckFunctional[Δϕ_,gap_,VListWithLabelΔL_,Zgrid_]:=
Module[{(*GappedTable,eps,numberOfComponentsFunctional,costvec,func,bvec*)},

	(*remove operators above gap, keep all spining operators*)
	GappedTable=Select[VListWithLabelΔL,#[[1,1]]>gap||#[[1,2]]>0&][[All,2]]; 
	(*add an operator at precisely the gap*)
	GappedTable=Prepend[GappedTable,FConvolvedSingleBlock[Δϕ,Zgrid,{gap,0}][[2]]];
	(*add the identity operator *)
	GappedTable=Prepend[GappedTable,FConvolvedSingleBlock[Δϕ,Zgrid,{0,0}][[2]]];
	(* Optional: add the vector (Subscript[D, Δ])F at the gap for normalization purposes *)
	GappedTable=Prepend[GappedTable,DF[Δϕ,{gap,0}]];
	(*rescale components of the vectors vector by dividing by the first one (essential for numeric stability)*)
	GappedTable=(#/GappedTable[[1]])&/@GappedTable; 

	(* positivity conditions, strict positivity on one entry and non-negativity on the rest*)
	bvec={1}~Join~Array[0&,Length[GappedTable]-1];
	(* trivial objective {0,...,0} suffices.*)
	numberOfComponentsFunctional=Length[GappedTable[[1]]];
	costvec=Array[0&,numberOfComponentsFunctional];
	
	debug={costvec,GappedTable*1.,bvec}; If[!FreeQ[debug,∞|Re],Abort[]];
	
	
	func=Check[LinearProgramming[costvec,GappedTable*1.,bvec,None],"nofunc"]; (*We multiply by 1. 
	Somehow the LinearProgramming fails when we do everything at high precision.*)
	(* If someone can solve this and find out why it is failing let me know.*)
Return[func];
];

Since we are asking what the maximal allowed gap is we know that if one point is disallowed so are all points above it. Similarly if a point is allowed all points below it also have to be disallowed. So we can locate the boundary by bisection.

(* Bisection routine to find the boundary between allowed and disallowed points for fixed Δϕ*)
Bisect[Δϕ_,llg_,uug_,cutoff_,Zgrid_,Dgrid_]:=Module[{gap,lg,ug,functional,goodfunc,Ftab},
	Ftab=FConvolvedBlocks[Δϕ,Zgrid,Dgrid];
	lg=Min[llg,uug];
	ug=Max[llg,uug];
	goodfunc="None";
	While[ug-lg>cutoff,
		gap=((lg+ug)/2)//N//N;
		functional=CheckFunctional[Δϕ,gap,Ftab,Zgrid];
		If[functional==="nofunc",lg=gap,ug=gap;goodfunc=functional];
	];
	Return[{Δϕ,{SetPrecision[ug,prec],SetPrecision[lg,prec],goodfunc}}];
];

(* TODO: add Δϕ to output.*)

(* Takes ~60 seconds on first run. Due to block computation. Afterwards it is fast (also for differen Δϕ) *)
CheckFunctional[1/8,1.35,FConvolvedBlocks[1/8,Zgrid,Dgrid],Zgrid]
(* Should output {-1.6316528837442066`,0.`,0.`,2.6316528837442066`,0.`,0.`}*)

CheckFunctional[1/8,1.0,FConvolvedBlocks[1/8,Zgrid,Dgrid],Zgrid]
(* Should find no functional.*)

resultBisection1over8=Bisect[1/8,0.01,1.5,(10^(-6)),Zgrid,Dgrid]

resultBound=Table[
	Bisect[Δϕ,0.01,1.5,(10^(-6)),Zgrid,Dgrid]
	,{Δϕ,{0.03,0.05,0.07,0.08,0.09,0.1,0.11,0.12,0.125,0.13,0.14,0.15}}]

plotBound[listOfBisectionResults_,plotOptions___]:=Show[
	ListPlot[Sort[{#1,Mean[#2[[1;;2]]]}]&@@@listOfBisectionResults,Joined->True,PlotMarkers->Automatic,plotOptions]
]

Show[
plotBound[resultBound]
,
Graphics[{PointSize[Large],Red,Point[{1/8,1}]}]
]

This bound can be strengthened by increasing the functional space, i.e. adding more points to the Zgrid. The kink will move closer to the Ising model if you do this. On the other hand the bound can be made more rigorous by demanding positivity for more spin and or a denser grid of Δ. If your bound changes notably under changes of Dgrid and LMax then you will need to include more terms.

Important Notes: 
1.) The rescaling of the VList by dividing by the first one (identity or special choice) appears to be essential for numerical stability. Without it I did not manage to get a reliable output.

2.) High precision makes LinearProgramming fail to find a solution. I don’t understand the cause exactly. However, for our purposes here MachinePrecision seems to work well enough. 

Later it will be important to use high precision, when we will be solving semi-definite programming problems using SDPB which is designed to deal with arbitrary precision

We can explicitly plot the action of α on V[Δ,L] and check for its positivity properties. We should see that the functional is positive everywhere where we demanded it. We will however see some dips towards zero. These are so called double zero’s and indicate that an operator with that dimension is present in the (approximate) solution to crossing at the boundary of the allowed and disallowed region. We see below that at the kink the behaviour of these double zeros changes.

ClearAll[plotFunctional]
plotFunctional[resFromOneBisection_, logOrNot:_?BooleanQ: True, spinPlotted : _Integer :0 , spinDF : _Integer : 0, plotOptions___]:=Module[{Δϕ,Δϵ,plotFunc},
With[{l=spinPlotted},
	Δϕ=resFromOneBisection[[1]];
	Δϵ=resFromOneBisection[[2,1]];
	plotFunc=If[logOrNot===True,ListLogPlot,ListPlot];
	plotFunc[Table[{x,resFromOneBisection[[2,3]].(((FConvolvedSingleBlock[Δϕ,Zgrid,{x,l}][[2]])/(DF[Δϕ,{resFromOneBisection[[2,2]],spinDF}])))},{x,l,l+5,0.002}]
		,PlotRange->{-5,Automatic},PlotLabel->"Δϕ="<>ToString[Δϕ,InputForm],plotOptions]
]]

plotFunctional[#,ImageSize->400]&/@resultBound

Before the kink there is an extra double zero in the extremal spectrum. The location of this zero moves as we change Δϕ. This makes the part before the kink more dependent on the Dgrid.

Some instability in the numerics

The LinearProgramming does not seem entirely reliable. There seems to be some randomness (much larger than our bisection error) in where the boundary is found depending on the starting point of the bisection. I think the issue is that sometimes at the edge the functional doesn’t get found even though it exists. We could try to make it more robust by retrying “allowed” points adding some small ϵ to the gap. The Semi-Definite programming tools that are used for real bootstrap problems will be much more reliable. There the result will be rigorous whether a functional is not found or not, either establishing a bound or establishing that for that search space no positive functional exists.

Bisect[0.04,0.1,2,(10^(-6)),Zgrid,Dgrid]
Bisect[0.04,0.2,2,(10^(-6)),Zgrid,Dgrid]

Comparing Dgrid choices

(* Much too low, will exclude all:*)
(*LMaxLow=8;stepLow=1/5;DMaxLow=2.5;
DgridLow=Table[{Δ,L},{L,0,LMaxLow,2},{Δ,L+(10^(-3)),DMaxLow,stepLow}]//Flatten[#,1]&;*)
(* This one still gives reasonable bounds.*)
(*LMaxLow=8;stepLow=1/10;DMaxLow=10;
DgridLow=Table[{Δ,L},{L,0,LMaxLow,2},{Δ,L+(10^(-3)),DMaxLow,stepLow}]//Flatten[#,1]&;*)
(* This one gives some bounds but they are much too strong. Notice how the Ising model has been excluded.*)
LMaxLow=8;stepLow=1/10;DMaxLow=5;
DgridLow=Table[{Δ,L},{L,0,LMaxLow,2},{Δ,L+(10^(-3)),DMaxLow,stepLow}]//Flatten[#,1]&;

(*Cases[ConformalBlockTables[Zgrid,DgridLow],Re[___],Infinity]*)

(*FConvolvedBlocks[1/8,Zgrid,DgridLow]//N*)

resultBoundLowΔmax=Table[
	Bisect[Δϕ,0.01,1.5,(10^(-6)),Zgrid,DgridLow]
	,{Δϕ,{0.05,0.07,0.08,0.09,0.1,0.125,0.14}}]

(* If you demand positivity on too few Δ you will exclude a consistent CFT!*)
Show[
plotBound[resultBound]
,
plotBound[resultBoundLowΔmax,PlotStyle->ColorData[97][2]]
]

plotFunctional/@resultBoundLowΔmax

Suggestions

1.) Now try bounding other operators with spin, for example the spin-2 sector. You will want to include the stress tensor at {2,2} and bound the gap (Subscript[Δ, T']) above that. (Getting numerically stable results turns out to not be so easy. See my attempt below.)
2.) For the scalar sector what if you assume there is an operator at {Δϕ,Δϵ}={1/8,1} and you bound the gap on the next operator (Subscript[Δ, ϵ']). Do you understand how to do this?
3.) Repeat the analysis above but use (non-vanishing) derivatives D[F[z,zb], {z,n}, {zb,m}] instead of a grid of (z,zb) values. This should be more effective (but a bit more of a hassle to set up).

Example (Subscript[Δ, T'])

(*Check gap above stress tensor:*)
CheckGapTp[Δϕ_,gapTp_,VListWithLabelΔL_,Zgrid_]:=
Module[{(*GappedTable,eps,numberOfComponentsFunctional,costvec,func,bvec*)},

	(*remove operators above gap, keep all spining operators*)
	GappedTable=Select[VListWithLabelΔL,Not[And[#[[1,2]]==2,#[[1,1]]<gapTp]]&][[All,2]]; 
	(*add an operator at precisely the gap*)
	GappedTable=Prepend[GappedTable,FConvolvedSingleBlock[Δϕ,Zgrid,{gapTp,2}][[2]]];
	(*add the identity operator *)
	GappedTable=Prepend[GappedTable,FConvolvedSingleBlock[Δϕ,Zgrid,{0,0}][[2]]];
	(* Optional: add the vector (Subscript[D, Δ])F at the gap for normalization purposes *)
	GappedTable=Prepend[GappedTable,DF[Δϕ,{gapTp,2}]];
	
	(*rescale components of the vectors vector by dividing by the first one (essential for numeric stability)*)
	GappedTable=(#/GappedTable[[1]])&/@GappedTable; 

	(* positivity conditions, strict positivity on one entry and non-negativity on the rest*)
	bvec={1}~Join~Array[0&,Length[GappedTable]-1];
	(* trivial objective {0,...,0} suffices.*)
	numberOfComponentsFunctional=Length[GappedTable[[1]]];
	costvec=Array[0&,numberOfComponentsFunctional];
	
	debug={costvec,GappedTable*1.,bvec}; If[!FreeQ[debug,∞|Re],Abort[]];
	
	
	func=Check[LinearProgramming[costvec,GappedTable*1.,bvec,None],"nofunc"]; (*We multiply by 1. 
	Somehow the LinearProgramming fails when we do everything at high precision.*)
	(* If someone can solve this and find out why it is failing let me know.*)
Return[func];
];

(* There seems to be a bug. If I take llg too low (below unitarity bound) it alters the final result.*)
(* It seems there is simply a region where lower gaps sometimes can be excluded than higher ones. If we did exact things this clearly would not be possible.*)
(* The bounds are okay enough, but it shows our rigorous semi-definite programming is better.*)
BisectAnyGap[CheckFunc_,Δϕ_,llg_,uug_,cutoff_,Zgrid_,Dgrid_]:=Module[{gap,lg,ug,functional,goodfunc,Ftab},
	Ftab=FConvolvedBlocks[Δϕ,Zgrid,Dgrid];
	lg=Min[llg,uug];
	ug=Max[llg,uug];
	goodfunc="None";
	While[ug-lg>cutoff,
		gap=((lg+ug)/2)//N//N;
		functional=CheckFunc[Δϕ,gap,Ftab,Zgrid];
		(*Print[gap," ",functional];*)
		(* Check numerical stability, doubles time taken so comment out to be faster.*)
		If[functional==="nofunc",
			functional=CheckFunc[Δϕ,gap-0.02*(ug-lg),Ftab,Zgrid];
			If[functional=!="nofunc",
				Print["Found α on retry (indicates numerical instability). Optimal bound might be lower."]];
		];
		If[functional==="nofunc",
			lg=gap,
			ug=gap;goodfunc=functional];
	];
	Return[{Δϕ,{SetPrecision[ug,prec],SetPrecision[lg,prec],goodfunc}}];
];
(* The ΔT' gap check seems to be numerically much more unstable. 
	I need to check whether I can do anything else in the normalization to improve this.*)

(* The following should be impossible and shows that this linear programming is unstable. It is much worse than the spin-0 problem. 
Probably we need to normalize better.*)
CheckGapTp[1/8,2.4,FConvolvedBlocks[1/8,Zgrid,Dgrid],Zgrid]
CheckGapTp[1/8,2.5,FConvolvedBlocks[1/8,Zgrid,Dgrid],Zgrid]
CheckGapTp[1/8,2.53,FConvolvedBlocks[1/8,Zgrid,Dgrid],Zgrid]
CheckGapTp[1/8,2.6,FConvolvedBlocks[1/8,Zgrid,Dgrid],Zgrid]
CheckGapTp[1/8,2.6083984375`30.,FConvolvedBlocks[1/8,Zgrid,Dgrid],Zgrid]
CheckGapTp[1/8,2.61,FConvolvedBlocks[1/8,Zgrid,Dgrid],Zgrid]
CheckGapTp[1/8,2.619,FConvolvedBlocks[1/8,Zgrid,Dgrid],Zgrid]

The behaviour was better for the scalar bound so I think we can perhaps improve the stability by picking a smarter normalization vector.

ClearAll[functionalAtVList];
functionalAtVList[Δϕ_,LOfGap : _Integer : 0,Zgrid_,Dgrid_,ApplyToDenserGrid_: "Off"]:=Module[{checkFunc(*,α*),out},
	checkFunc=Switch[LOfGap,0,CheckFunctional,2,CheckGapTp,_,Print["Bug"]];
	α=BisectAnyGap[checkFunc,Δϕ,LOfGap+0.001,LOfGap+2,(10^(-6)),Zgrid,Dgrid];
	out=MapAt[((α[[2,3]])/(DF[Δϕ,{α[[2,1]],LOfGap}])).#&,FConvolvedBlocks[Δϕ,Zgrid,If[ApplyToDenserGrid==="Off",Dgrid,ApplyToDenserGrid]],{All,2}]
];
(*Lgap is to specify the vector that was used as normalization which was chosen differently depending on which gap we want to find.*)

(* THIS ONE WORKS FOR BOTH SPIN-0 AND SPIN-2 (and can easily be extended to others).*)
ClearAll[plotFunctionalV2]
plotFunctionalV2[Δϕ_,LToPlot_,LOfGap_,Zgrid_,Dgrid_,ApplyToDenserGrid_: "Off",logOrNot:_?BooleanQ:True,plotOptions___]:=Module[{aux,plotFunc,αnormalized},
	aux=functionalAtVList[Δϕ,LOfGap,Zgrid,Dgrid,ApplyToDenserGrid];
	lastPointsWithNegativeFunctional=Select[aux,Negative[#[[2]]]&];
	aux=Cases[aux,{{Δ_,LToPlot},αF_}:>{Δ,αF}];
	
	plotFunc=If[logOrNot===True,ListLogPlot,ListPlot];
	plotFunc[
		aux
		(*Table[{x,αnormalized.(FConvolvedSingleBlock[Δϕ,Zgrid,{x,l}][[2]])},{x,l,l+3,0.002}]*)
		,PlotRange->{-5,Automatic},PlotLabel->"Δϕ="<>ToString[Δϕ,InputForm]
		,AxesLabel->{"(Subscript[Δ, ϕ])",StringReplace["(Subscript[Δ, l = LPH])","LPH"->ToString[LToPlot]]}
		,plotOptions]
]

res1over8Tp=BisectAnyGap[CheckGapTp,1/8,2,4,(10^(-6)),Zgrid,Dgrid]

We can look at the functional to see whether it dips in between the points we demanded positivity on.

plotFunctionalV2[1/8,0,2,Zgrid,Dgrid,DgridDense,True]

There are no visible dips, but let’s explicitly look at the points. (Negative points will not show up in the Logplot. On the other hand getting a readable visualization without the log scale is not easy due to the rapidly changing scale.)

(* The variable below gets set when you run plotFunctionalV2. Here we should find only points below the gap that we imposed. We see that there are also some points on which the functional is not quite negative.*)
lastPointsWithNegativeFunctional//N

We see a dip just after is because Dgrid was not dense enough. If we use the denser grid to find the functional we see no such dip.

plotFunctionalV2[1/8,0,2,Zgrid,DgridDense,DgridDense,True]
lastPointsWithNegativeFunctional//N

The latter output shows the points where the functional is negative. Here we should find only points below the gap that we imposed. We see that there are also some other points on which the functional is not quite negative.

We would have to check this against an even denser grid to see whether it still dips below zero in between. We can also plot the functional acting on the spin 2 sector.

plotFunctionalV2[1/8,2,2,Zgrid,Dgrid,DgridDense,True]

We see it is nice and positive everywhere above the gap even when tested on the denser grid.

(* We saw above that the default Dgrid is not good enough here. Indeed we exclude too much including the Ising model.*)
resultBoundTp=Table[
	BisectAnyGap[CheckGapTp,Δϕ,2.2,4,(10^(-6)),Zgrid,Dgrid]
	,{Δϕ,{0.05,0.07,0.08,0.09,0.1,0.125,0.14}}]

plotBound[resultBoundTp]

LMaxDense=12;stepDense=1/20;DMaxDense=44;
DgridDense=Table[{Δ,L},{L,0,LMaxDense,2},{Δ,L+(10^(-3)),DMaxDense,stepDense}]//Flatten[#,1]&;

LMaxDensest=12;stepDensest=1/40;DMaxDensest=50;
DgridDensest=Table[{Δ,L},{L,0,LMaxDensest,2},{Δ,L+(10^(-3)),DMaxDensest,stepDensest}]//Flatten[#,1]&;

res1over8TpDensest=BisectAnyGap[CheckGapTp,1/8,0.1,4,(10^(-3)),Zgrid,DgridDensest]

resultBoundTpDense=Table[
	BisectAnyGap[CheckGapTp,Δϕ,2.001,5,(10^(-6)),Zgrid,DgridDense]
	,{Δϕ,{0.05,0.07,0.08,0.09,0.1,0.125,0.14}}]

resultBoundTpDensest=Table[
	BisectAnyGap[CheckGapTp,Δϕ,2.1,4,(10^(-6)),Zgrid,DgridDensest]
	,{Δϕ,{0.05,0.07,0.08,0.09,0.1,0.125,0.14}}]

We see that the Dgrid makes an enormous difference here (or is it just chance and the randomness in bisections). So I would say that the default Dgrid above is far too small. This new bound makes somewhat more sense since it is above 3 and so does not include the 2D Ising model. On the other hand I would have expected it to be less constant. Maybe by increasing Zgrid too we can get good bounds that still show a peak.

Show[
plotBound[resultBoundTp]
,
plotBound[resultBoundTpDense,PlotStyle->ColorData[97][2]]
,PlotRange->All
]