import numpy as np

from ..helpers import article
from ._gauss_legendre import gauss_legendre
from ._helpers import C1Scheme

source = article(
    authors=["T.N.L. Patterson"],
    title="The optimum addition of points to quadrature formulae",
    journal="Math. Comp.",
    volume="22",
    year="1968",
    pages="847-856",
    url="https://doi.org/10.1090/S0025-5718-68-99866-9",
)


def gauss_patterson(index):
    # Gauss-Patterson quadrature.
    # <https://people.sc.fsu.edu/~jburkardt/datasets/quadrature_rules_patterson/quadrature_rules_patterson.html>
    degree = 3 * 2 ** index - 1 if index > 0 else 1

    points = np.sort(_get_points(index))

    # weights
    if index < 6:
        weights = _get_weights(points)
    elif index == 6:
        # _get_weights is flawed with round-off for index > 5. Use explicit values from
        # <https://people.sc.fsu.edu/~jburkardt/datasets/quadrature_rules_patterson/gp_o127_w.txt>.
        s = np.array(
            [
                5.053609520786252e-05,
                1.807395644453884e-04,
                3.777466463269846e-04,
                6.326073193626335e-04,
                9.383698485423815e-04,
                1.289524082610417e-03,
                1.681142865421470e-03,
                2.108815245726633e-03,
                2.568764943794020e-03,
                3.057753410175531e-03,
                3.572892783517299e-03,
                4.111503978654693e-03,
                4.671050372114322e-03,
                5.249123454808859e-03,
                5.843449875835640e-03,
                6.451900050175737e-03,
                7.072489995433555e-03,
                7.703375233279742e-03,
                8.342838753968157e-03,
                8.989275784064136e-03,
                9.641177729702537e-03,
                1.029711695795636e-02,
                1.095573338783790e-02,
                1.161572331995513e-02,
                1.227583056008277e-02,
                1.293483966360737e-02,
                1.359157100976555e-02,
                1.424487737291678e-02,
                1.489364166481518e-02,
                1.553677555584398e-02,
                1.617321872957772e-02,
                1.680193857410386e-02,
                1.742193015946417e-02,
                1.803221639039129e-02,
                1.863184825613879e-02,
                1.921990512472777e-02,
                1.979549504809750e-02,
                2.035775505847216e-02,
                2.090585144581202e-02,
                2.143898001250387e-02,
                2.195636630531782e-02,
                2.245726582681610e-02,
                2.294096422938775e-02,
                2.340677749531401e-02,
                2.385405210603854e-02,
                2.428216520333660e-02,
                2.469052474448768e-02,
                2.507856965294977e-02,
                2.544576996546477e-02,
                2.579162697602423e-02,
                2.611567337670610e-02,
                2.641747339505826e-02,
                2.669662292745036e-02,
                2.695274966763303e-02,
                2.718551322962479e-02,
                2.739460526398143e-02,
                2.757974956648187e-02,
                2.774070217827968e-02,
                2.787725147661370e-02,
                2.798921825523816e-02,
                2.807645579381725e-02,
                2.813884991562715e-02,
                2.817631903301660e-02,
            ]
        )
        weights = np.concatenate([s, np.array([0.2818881418019236e-01]), s[::-1]])
    elif index == 7:
        s = np.array(
            [
                0.69379364324108267170e-05,
                0.25157870384280661489e-04,
                0.53275293669780613125e-04,
                0.90372734658751149261e-04,
                0.13575491094922871973e-03,
                0.18887326450650491366e-03,
                0.24921240048299729402e-03,
                0.31630366082226447689e-03,
                0.38974528447328229322e-03,
                0.46918492424785040975e-03,
                0.55429531493037471492e-03,
                0.64476204130572477933e-03,
                0.74028280424450333046e-03,
                0.84057143271072246365e-03,
                0.94536151685852538246e-03,
                0.10544076228633167722e-02,
                0.11674841174299594077e-02,
                0.12843824718970101768e-02,
                0.14049079956551446427e-02,
                0.15288767050877655684e-02,
                0.16561127281544526052e-02,
                0.17864463917586498247e-02,
                0.19197129710138724125e-02,
                0.20557519893273465236e-02,
                0.21944069253638388388e-02,
                0.23355251860571608737e-02,
                0.24789582266575679307e-02,
                0.26245617274044295626e-02,
                0.27721957645934509940e-02,
                0.29217249379178197538e-02,
                0.30730184347025783234e-02,
                0.32259500250878684614e-02,
                0.33803979910869203823e-02,
                0.35362449977167777340e-02,
                0.36933779170256508183e-02,
                0.38516876166398709241e-02,
                0.40110687240750233989e-02,
                0.41714193769840788528e-02,
                0.43326409680929828545e-02,
                0.44946378920320678616e-02,
                0.46573172997568547773e-02,
                0.48205888648512683476e-02,
                0.49843645647655386012e-02,
                0.51485584789781777618e-02,
                0.53130866051870565663e-02,
                0.54778666939189508240e-02,
                0.56428181013844441585e-02,
                0.58078616599775673635e-02,
                0.59729195655081658049e-02,
                0.61379152800413850435e-02,
                0.63027734490857587172e-02,
                0.64674198318036867274e-02,
                0.66317812429018878941e-02,
                0.67957855048827733948e-02,
                0.69593614093904229394e-02,
                0.71224386864583871532e-02,
                0.72849479805538070639e-02,
                0.74468208324075910174e-02,
                0.76079896657190565832e-02,
                0.77683877779219912200e-02,
                0.79279493342948491103e-02,
                0.80866093647888599710e-02,
                0.82443037630328680306e-02,
                0.84009692870519326354e-02,
                0.85565435613076896192e-02,
                0.87109650797320868736e-02,
                0.88641732094824942641e-02,
                0.90161081951956431600e-02,
                0.91667111635607884067e-02,
                0.93159241280693950932e-02,
                0.94636899938300652943e-02,
                0.96099525623638830097e-02,
                0.97546565363174114611e-02,
                0.98977475240487497440e-02,
                0.10039172044056840798e-01,
                0.10178877529236079733e-01,
                0.10316812330947621682e-01,
                0.10452925722906011926e-01,
                0.10587167904885197931e-01,
                0.10719490006251933623e-01,
                0.10849844089337314099e-01,
                0.10978183152658912470e-01,
                0.11104461134006926537e-01,
                0.11228632913408049354e-01,
                0.11350654315980596602e-01,
                0.11470482114693874380e-01,
                0.11588074033043952568e-01,
                0.11703388747657003101e-01,
                0.11816385890830235763e-01,
                0.11927026053019270040e-01,
                0.12035270785279562630e-01,
                0.12141082601668299679e-01,
                0.12244424981611985899e-01,
                0.12345262372243838455e-01,
                0.12443560190714035263e-01,
                0.12539284826474884353e-01,
                0.12632403643542078765e-01,
                0.12722884982732382906e-01,
                0.12810698163877361967e-01,
                0.12895813488012114694e-01,
                0.12978202239537399286e-01,
                0.13057836688353048840e-01,
                0.13134690091960152836e-01,
                0.13208736697529129966e-01,
                0.13279951743930530650e-01,
                0.13348311463725179953e-01,
                0.13413793085110098513e-01,
                0.13476374833816515982e-01,
                0.13536035934956213614e-01,
                0.13592756614812395910e-01,
                0.13646518102571291428e-01,
                0.13697302631990716258e-01,
                0.13745093443001896632e-01,
                0.13789874783240936517e-01,
                0.13831631909506428676e-01,
                0.13870351089139840997e-01,
                0.13906019601325461264e-01,
                0.13938625738306850804e-01,
                0.13968158806516938516e-01,
                0.13994609127619079852e-01,
                0.14017968039456608810e-01,
                0.14038227896908623303e-01,
                0.14055382072649964277e-01,
                0.14069424957813575318e-01,
                0.14080351962553661325e-01,
                0.14088159516508301065e-01,
                0.14092845069160408355e-01,
            ]
        )
        weights = np.concatenate([s, np.array([0.14094407090096179347e-01]), s[::-1]])
    else:
        assert index == 8
        s = np.array(
            [
                0.945715933950007048827e-06,
                0.345456507169149134898e-05,
                0.736624069102321668857e-05,
                0.125792781889592743525e-04,
                0.190213681905875816679e-04,
                0.266376412339000901358e-04,
                0.353751372055189588628e-04,
                0.451863674126296143105e-04,
                0.560319507856164252140e-04,
                0.678774554733972416227e-04,
                0.806899228014035293851e-04,
                0.944366322532705527066e-04,
                0.109085545645741522051e-03,
                0.124606200241498368482e-03,
                0.140970302204104791413e-03,
                0.158151830411132242924e-03,
                0.176126765545083195474e-03,
                0.194872642236641146532e-03,
                0.214368090034216937149e-03,
                0.234592462123925204879e-03,
                0.255525589595236862014e-03,
                0.277147657465187357459e-03,
                0.299439176850911730874e-03,
                0.322381020652862389664e-03,
                0.345954492129903871350e-03,
                0.370141402122251665232e-03,
                0.394924138246873704434e-03,
                0.420285716355361231823e-03,
                0.446209810101403247488e-03,
                0.472680758429262691232e-03,
                0.499683553312800484519e-03,
                0.527203811431658386125e-03,
                0.555227733977307579715e-03,
                0.583742058714979703847e-03,
                0.612734008012225209294e-03,
                0.642191235948505088403e-03,
                0.672101776960108194646e-03,
                0.702453997827572321358e-03,
                0.733236554224767912055e-03,
                0.764438352543882784191e-03,
                0.796048517297550871506e-03,
                0.828056364077226302608e-03,
                0.860451377808527848128e-03,
                0.893223195879324912340e-03,
                0.926361595613111283368e-03,
                0.959856485506936206261e-03,
                0.993697899638760857945e-03,
                0.102787599466367326179e-02,
                0.106238104885340071375e-02,
                0.109720346268191941940e-02,
                0.113233376051597664917e-02,
                0.116776259302858043685e-02,
                0.120348074001265964881e-02,
                0.123947911332878396534e-02,
                0.127574875977346947345e-02,
                0.131228086370221478128e-02,
                0.134906674928353113127e-02,
                0.138609788229672549700e-02,
                0.142336587141720519900e-02,
                0.146086246895890987689e-02,
                0.149857957106456636214e-02,
                0.153650921735128916170e-02,
                0.157464359003212166189e-02,
                0.161297501254393423070e-02,
                0.165149594771914570655e-02,
                0.169019899554346019117e-02,
                0.172907689054461607168e-02,
                0.176812249885838886701e-02,
                0.180732881501808930079e-02,
                0.184668895851282540913e-02,
                0.188619617015808475394e-02,
                0.192584380831993546204e-02,
                0.196562534503150547732e-02,
                0.200553436203751169944e-02,
                0.204556454679958293446e-02,
                0.208570968849203942640e-02,
                0.212596367401472533045e-02,
                0.216632048404649142727e-02,
                0.220677418916003329194e-02,
                0.224731894601603393082e-02,
                0.228794899365195972378e-02,
                0.232865864987842738864e-02,
                0.236944230779380495146e-02,
                0.241029443242563417382e-02,
                0.245120955750556483923e-02,
                0.249218228238276930060e-02,
                0.253320726907925325750e-02,
                0.257427923948908888092e-02,
                0.261539297272236109225e-02,
                0.265654330259352828314e-02,
                0.269772511525294586667e-02,
                0.273893334695947541201e-02,
                0.278016298199139435045e-02,
                0.282140905069222207923e-02,
                0.286266662764757868253e-02,
                0.290393082998878368175e-02,
                0.294519681581857582284e-02,
                0.298645978275408290247e-02,
                0.302771496658198544480e-02,
                0.306895764002069252174e-02,
                0.311018311158427546158e-02,
                0.315138672454287935858e-02,
                0.319256385597434736790e-02,
                0.323370991590184336368e-02,
                0.327482034651233969564e-02,
                0.331589062145094394706e-02,
                0.335691624518616761342e-02,
                0.339789275244138669739e-02,
                0.343881570768790591876e-02,
                0.347968070469521146972e-02,
                0.352048336613417922682e-02,
                0.356121934322919357659e-02,
                0.360188431545532431869e-02,
                0.364247399027690353194e-02,
                0.368298410292403911967e-02,
                0.372341041620379550870e-02,
                0.376374872034296338241e-02,
                0.380399483285952829161e-02,
                0.384414459846013158917e-02,
                0.388419388896099560998e-02,
                0.392413860322995774660e-02,
                0.396397466714742455513e-02,
                0.400369803358421688562e-02,
                0.404330468239442998549e-02,
                0.408279062042157838350e-02,
                0.412215188151643401528e-02,
                0.416138452656509745764e-02,
                0.420048464352596631772e-02,
                0.423944834747438184434e-02,
                0.427827178065384480959e-02,
                0.431695111253279479928e-02,
                0.435548253986604343679e-02,
                0.439386228676004195260e-02,
                0.443208660474124713206e-02,
                0.447015177282692726900e-02,
                0.450805409759782158001e-02,
                0.454578991327213285488e-02,
                0.458335558178039420335e-02,
                0.462074749284080687482e-02,
                0.465796206403469754658e-02,
                0.469499574088179046532e-02,
                0.473184499691503264714e-02,
                0.476850633375474925263e-02,
                0.480497628118194150483e-02,
                0.484125139721057135214e-02,
                0.487732826815870573054e-02,
                0.491320350871841897367e-02,
                0.494887376202437487201e-02,
                0.498433569972103029914e-02,
                0.501958602202842039909e-02,
                0.505462145780650125058e-02,
                0.508943876461803986674e-02,
                0.512403472879005351831e-02,
                0.515840616547381084096e-02,
                0.519254991870341614863e-02,
                0.522646286145300596306e-02,
                0.526014189569259311205e-02,
                0.529358395244259896547e-02,
                0.532678599182711857974e-02,
                0.535974500312596681161e-02,
                0.539245800482555593606e-02,
                0.542492204466865704951e-02,
                0.545713419970309863995e-02,
                0.548909157632945623482e-02,
                0.552079131034778706457e-02,
                0.555223056700346326850e-02,
                0.558340654103215637610e-02,
                0.561431645670402467678e-02,
                0.564495756786715368885e-02,
                0.567532715799029830087e-02,
                0.570542254020497332312e-02,
                0.573524105734693719020e-02,
                0.576478008199711142954e-02,
                0.579403701652197628421e-02,
                0.582300929311348057702e-02,
                0.585169437382850155033e-02,
                0.588008975062788803205e-02,
                0.590819294541511788161e-02,
                0.593600151007459827614e-02,
                0.596351302650963502011e-02,
                0.599072510668009471472e-02,
                0.601763539263978131522e-02,
                0.604424155657354634589e-02,
                0.607054130083414983949e-02,
                0.609653235797888692923e-02,
                0.612221249080599294931e-02,
                0.614757949239083790214e-02,
                0.617263118612191922727e-02,
                0.619736542573665996342e-02,
                0.622178009535701763157e-02,
                0.624587310952490748541e-02,
                0.626964241323744217671e-02,
                0.629308598198198836688e-02,
                0.631620182177103938227e-02,
                0.633898796917690165912e-02,
                0.636144249136619145314e-02,
                0.638356348613413709795e-02,
                0.640534908193868098342e-02,
                0.642679743793437438922e-02,
                0.644790674400605734710e-02,
                0.646867522080231481688e-02,
                0.648910111976869964292e-02,
                0.650918272318071200827e-02,
                0.652891834417652442012e-02,
                0.654830632678944064054e-02,
                0.656734504598007641819e-02,
                0.658603290766824937794e-02,
                0.660436834876456498276e-02,
                0.662234983720168509457e-02,
                0.663997587196526532519e-02,
                0.665724498312454708217e-02,
                0.667415573186258997654e-02,
                0.669070671050613006584e-02,
                0.670689654255504925648e-02,
                0.672272388271144108036e-02,
                0.673818741690825799086e-02,
                0.675328586233752529078e-02,
                0.676801796747810680683e-02,
                0.678238251212300746082e-02,
                0.679637830740619795480e-02,
                0.681000419582894688374e-02,
                0.682325905128564571420e-02,
                0.683614177908911221841e-02,
                0.684865131599535812903e-02,
                0.686078663022780697951e-02,
                0.687254672150094831613e-02,
                0.688393062104341470995e-02,
                0.689493739162046825872e-02,
                0.690556612755588354803e-02,
                0.691581595475321433825e-02,
                0.692568603071643155621e-02,
                0.693517554456992049848e-02,
                0.694428371707782549438e-02,
                0.695300980066273063177e-02,
                0.696135307942366551493e-02,
                0.696931286915342540213e-02,
                0.697688851735519545845e-02,
                0.698407940325846925786e-02,
                0.699088493783425207545e-02,
                0.699730456380953992594e-02,
                0.700333775568106572820e-02,
                0.700898401972830440494e-02,
                0.701424289402572916425e-02,
                0.701911394845431165171e-02,
                0.702359678471225911031e-02,
                0.702769103632498213858e-02,
                0.703139636865428709508e-02,
                0.703471247890678765907e-02,
                0.703763909614153052319e-02,
                0.704017598127683066242e-02,
                0.704232292709631209597e-02,
                0.704407975825415053266e-02,
                0.704544633127951476780e-02,
                0.704642253458020417748e-02,
                0.704700828844548013730e-02,
            ]
        )
        weights = np.concatenate([s, np.array([0.704720354504808967346e-02]), s[::-1]])

    return C1Scheme(f"Gauss-Patterson {index}", degree, weights, points, source)


def _get_points(index):
    def _pm(a):
        a = np.asarray(a)
        return np.concatenate([-a[::-1], +a])

    if index == 0:
        return np.array([0.0])
    if index == 1:
        new_points = [0.7745966692414834]
    elif index == 2:
        new_points = [0.4342437493468025, 0.9604912687080203]
    elif index == 3:
        new_points = [
            0.2233866864289669,
            0.6211029467372264,
            0.8884592328722570,
            0.9938319632127550,
        ]
    elif index == 4:
        new_points = [
            0.1124889431331866,
            0.3311353932579768,
            0.5313197436443756,
            0.7024962064915271,
            0.8367259381688688,
            0.9296548574297401,
            0.9815311495537401,
            0.9990981249676676,
        ]
    elif index == 5:
        new_points = [
            0.5634431304659279e-01,
            0.1682352515522075,
            0.2777498220218243,
            0.3833593241987304,
            0.4836180269458411,
            0.5771957100520458,
            0.6629096600247806,
            0.7397560443526947,
            0.8069405319502176,
            0.8639079381936905,
            0.9103711569570043,
            0.9463428583734029,
            0.9721828747485818,
            0.9886847575474295,
            0.9972062593722220,
            0.9998728881203576,
        ]
    elif index == 6:
        new_points = [
            0.2818464894974569e-01,
            0.8445404008371088e-01,
            0.1404242331525602,
            0.1958975027111002,
            0.2506787303034832,
            0.3045764415567140,
            0.3574038378315322,
            0.4089798212298887,
            0.4591300119898323,
            0.5076877575337166,
            0.5544951326319325,
            0.5994039302422429,
            0.6422766425097595,
            0.6829874310910792,
            0.7214230853700989,
            0.7574839663805136,
            0.7910849337998483,
            0.8221562543649804,
            0.8506444947683502,
            0.8765134144847053,
            0.8997448997769401,
            0.9203400254700124,
            0.9383203977795929,
            0.9537300064257611,
            0.9666378515584165,
            0.9771415146397057,
            0.9853714995985203,
            0.9914957211781061,
            0.9957241046984072,
            0.9983166353184074,
            0.9995987996719107,
            0.9999824303548916,
        ]
    elif index == 7:
        new_points = [
            0.014093886410782462614e00,
            0.042269164765363603212e00,
            0.070406976042855179063e00,
            0.098482396598119202090e00,
            0.12647058437230196685e00,
            0.15434681148137810869e00,
            0.18208649675925219825e00,
            0.20966523824318119477e00,
            0.23705884558982972721e00,
            0.26424337241092676194e00,
            0.29119514851824668196e00,
            0.31789081206847668318e00,
            0.34430734159943802278e00,
            0.37042208795007823014e00,
            0.39621280605761593918e00,
            0.42165768662616330006e00,
            0.44673538766202847374e00,
            0.47142506587165887693e00,
            0.49570640791876146017e00,
            0.51955966153745702199e00,
            0.54296566649831149049e00,
            0.56590588542365442262e00,
            0.58836243444766254143e00,
            0.61031811371518640016e00,
            0.63175643771119423041e00,
            0.65266166541001749610e00,
            0.67301883023041847920e00,
            0.69281376977911470289e00,
            0.71203315536225203459e00,
            0.73066452124218126133e00,
            0.74869629361693660282e00,
            0.76611781930376009072e00,
            0.78291939411828301639e00,
            0.79909229096084140180e00,
            0.81462878765513741344e00,
            0.82952219463740140018e00,
            0.84376688267270860104e00,
            0.85735831088623215653e00,
            0.87029305554811390585e00,
            0.88256884024734190684e00,
            0.89418456833555902286e00,
            0.90514035881326159519e00,
            0.91543758715576504064e00,
            0.92507893290707565236e00,
            0.93406843615772578800e00,
            0.94241156519108305981e00,
            0.95011529752129487656e00,
            0.95718821610986096274e00,
            0.96364062156981213252e00,
            0.96948465950245923177e00,
            0.97473445975240266776e00,
            0.97940628167086268381e00,
            0.98351865757863272876e00,
            0.98709252795403406719e00,
            0.99015137040077015918e00,
            0.99272134428278861533e00,
            0.99483150280062100052e00,
            0.99651414591489027385e00,
            0.99780535449595727456e00,
            0.99874561446809511470e00,
            0.99938033802502358193e00,
            0.99976049092443204733e00,
            0.99994399620705437576e00,
            0.99999759637974846462e00,
        ]
    else:
        assert index == 8
        new_points = [
            0.704713845933674648514e-02,
            0.211398533783310883350e-01,
            0.352278828084410232603e-01,
            0.493081047908686267156e-01,
            0.633773999173222898797e-01,
            0.774326523498572825675e-01,
            0.914707508403553909095e-01,
            0.105488589749541988533,
            0.119483070065440005133,
            0.133451100421161601344,
            0.147389598111939940054,
            0.161295490111305257361,
            0.175165714086311475707,
            0.188997219411721861059,
            0.202786968183064697557,
            0.216531936228472628081,
            0.230229114119222177156,
            0.243875508178893021593,
            0.257468141491069790481,
            0.271004054905512543536,
            0.284480308042725577496,
            0.297893980296857823437,
            0.311242171836871800300,
            0.324522004605921855207,
            0.337730623318886219621,
            0.350865196458001209011,
            0.363922917266549655269,
            0.376901004740559344802,
            0.389796704618470795479,
            0.402607290368737092671,
            0.415330064175321663764,
            0.427962357921062742583,
            0.440501534168875795783,
            0.452944987140767283784,
            0.465290143694634735858,
            0.477534464298829155284,
            0.489675444004456155436,
            0.501710613415391878251,
            0.513637539655988578507,
            0.525453827336442687395,
            0.537157119515795115982,
            0.548745098662529448608,
            0.560215487612728441818,
            0.571566050525742833992,
            0.582794593837318850840,
            0.593898967210121954393,
            0.604877064481584353319,
            0.615726824608992638014,
            0.626446232611719746542,
            0.637033320510492495071,
            0.647486168263572388782,
            0.657802904699713735422,
            0.667981708447749702165,
            0.678020808862644517838,
            0.687918486947839325756,
            0.697673076273711232906,
            0.707282963891961103412,
            0.716746591245747095767,
            0.726062455075389632685,
            0.735229108319491547663,
            0.744245161011347082309,
            0.753109281170558142523,
            0.761820195689839149173,
            0.770376691217076824278,
            0.778777615032822744702,
            0.787021875923539422170,
            0.795108445051100526780,
            0.803036356819268687782,
            0.810804709738146594361,
            0.818412667287925807395,
            0.825859458783650001088,
            0.833144380243172624728,
            0.840266795261030442350,
            0.847226135891580884381,
            0.854021903545468625813,
            0.860653669904299969802,
            0.867121077859315215614,
            0.873423842480859310192,
            0.879561752026556262568,
            0.885534668997285008926,
            0.891342531251319871666,
            0.896985353188316590376,
            0.902463227016165675048,
            0.907776324115058903624,
            0.912924896514370590080,
            0.917909278499077501636,
            0.922729888363349241523,
            0.927387230329536696843,
            0.931881896650953639345,
            0.936214569916450806625,
            0.940386025573669721370,
            0.944397134685866648591,
            0.948248866934137357063,
            0.951942293872573589498,
            0.955478592438183697574,
            0.958859048710200221356,
            0.962085061904651475741,
            0.965158148579915665979,
            0.968079947017759947964,
            0.970852221732792443256,
            0.973476868052506926773,
            0.975955916702011753129,
            0.978291538324758539526,
            0.980486047876721339416,
            0.982541908851080604251,
            0.984461737328814534596,
            0.986248305913007552681,
            0.987904547695124280467,
            0.989433560520240838716,
            0.990838611958294243677,
            0.992123145530863117683,
            0.993290788851684966211,
            0.994345364356723405931,
            0.995290903148810302261,
            0.996131662079315037786,
            0.996872143485260161299,
            0.997517116063472399965,
            0.998071634524930323302,
            0.998541055697167906027,
            0.998931050830810562236,
            0.999247618943342473599,
            0.999497112467187190535,
            0.999686286448317731776,
            0.999822363679787739196,
            0.999913081144678282800,
            0.999966730098486276883,
            0.999992298136257588028,
            0.999999672956734384381,
        ]

    return np.concatenate([_get_points(index - 1), _pm(new_points)])


def _get_weights(pts):
    """Given a number of points in [-1, 1], according to

        T.N.L. Patterson,
        On some Gauss and Lobatto based integration formulae,
        Math. Comp. 22 (1968), 877-881,
        https://doi.org/10.1090/S0025-5718-68-99865-7,

    one can compute the corresponding weights. One reads there:

    > Thus the weights of an n-point integration formula [...] are given by
    >
    >     omega_i = int_{-1}^{1} L_i(x) dx,
    >
    > (where L_i is the Lagrange polynomial for the point x_i). These weights can be
    > evaluated exactly in a numerically stable fashion using a Gauss formula with n/2
    > points when n is even and (n + 1)/2 points > when n is odd.
    """
    n = len(pts)

    # Gauss-Legendre of order k integrates polynomials of degree 2*k-1 exactly. L has
    # degree n-1, so k needs to be n/2 if n is even, and (n+1)/2 if n is odd.
    k = (n // 2) - 1 if n % 2 == 0 else (n + 1) // 2
    return np.array(
        [
            gauss_legendre(k).integrate(
                # Normalized Lagrange polynomial: Degree n-1, 0 at all x_j, 1 at x_i.
                lambda x: np.prod(
                    [(x - pts[j]) / (pts[i] - pts[j]) for j in range(n) if j != i],
                    axis=0,
                ).reshape(np.asarray(x).shape),
                np.array([-1, 1]),
            )
            for i in range(n)
        ]
    )
