
# Computation of (logarithmic) moments of Chebyshev polynomials scaled to 0..1

"The integral of x^k*log(x) on [0,1]."
logmoment(k::Int, ::Type{T} = Float64) where {T} = -one(T)/(k+1)^2

"Modified Chebyshev moments on [0,1]"
function modified_moments(N, ::Type{T} = Float64) where {T}
    c = zeros(T, N+1)
    c[1] = 1
    for n in 2:(N>>1 + 1)
        c[2n-1] = -one(T) / ((2n-3)*(2n-1))
    end
    c
end

"Modified logarithmic Chebyshev moments on [0,1]"
function modified_log_moments(N, ::Type{T} = Float64) where {T}
    # recurrence coefficients of Chebyshev
    chebA =  [BasisFunctions.rec_An(ChebyshevT{T}(N), k) for k in 0:N]
    chebB =  [BasisFunctions.rec_Bn(ChebyshevT{T}(N), k) for k in 0:N]
    chebC =  [BasisFunctions.rec_Cn(ChebyshevT{T}(N), k) for k in 0:N]
    # recurrence coefficients of shifted Chebyshev to [0,1]
    modchebA = 2chebA
    modchebC = chebC
    modchebB = similar(chebB)
    for n in 1:length(chebB)
        modchebB[n] = chebB[n] - chebA[n]
    end
    # Moments L[n,k] = ∫_0^1 log(x) x^k p_n(x) dx
    L = zeros(T, N+1,N+1)
    L[1,:] = [logmoment(k,T) for k in 0:N]
    for n in 0:N-1
        for k in 0:N-1
            if n == 0
                L[n+2,k+1] = modchebA[n+1]*L[n+1,k+2] + modchebB[n+1]*L[n+1,k+1]
            else
                L[n+2,k+1] = modchebA[n+1]*L[n+1,k+2] + modchebB[n+1]*L[n+1,k+1] - modchebC[n+1]*L[n,k+1]
            end
        end
    end
    L[:,1]
end

# The rules below are generated with the following code:

# function pretty_print_quadrule(x, w, ::Type{BigFloat})
#     print("x = BigFloat.([")
#     for t in x
#         print("\"", string(t), "\", ")
#     end
#     println("])")
#     print("w = BigFloat.([")
#     for y in w
#         print("\"", string(y), "\", ")
#     end
#     println("])")
# end
# T = BigFloat
# for N = 1:20
#     cheb = ChebyshevT{T}(N) → 0..1
#     bmom = vcat(modified_moments(N-1, T), modified_log_moments(N-1, T))
#     b = cheb ⊕ log*cheb
#     w, x = compute_gauss_rule(b, bmom)
#     pretty_print_quadrule(x, w, T)
# end

const big_x1 = BigFloat.(["0.4999999999999999999999999999999999999999999999999999999999999999999999999999957", ])
const big_w1 = BigFloat.(["1.0", ])
const big_x2 = BigFloat.(["0.211324865405187117745425609749021272176199124364936561990698836758011163848551", "0.7886751345948128822545743902509787278238008756350634380093011632419888361514749", ])
const big_w2 = BigFloat.(["0.5000000000000000000000000000000000000000000000000000000000000000000000000000259", "0.4999999999999999999999999999999999999999999999999999999999999999999999999999741", ])
const big_x3 = BigFloat.(["0.1127016653792583114820734600217600389167078294708409173412426233886516908062983", "0.4999999999999999999999999999999999999999999999999999999999999999999999999999957", "0.8872983346207416885179265399782399610832921705291590826587573766113483091936996", ])
const big_w3 = BigFloat.(["0.2777777777777777777777777777777777777777777777777777777777777777777777777777783", "0.4444444444444444444444444444444444444444444444444444444444444444444444444444435", "0.2777777777777777777777777777777777777777777777777777777777777777777777777777783", ])
const big_x4 = BigFloat.(["0.0694318442029737123880267555535952474521373101851411811921390971150069362621467", "0.3300094782075718675986671204483776563997120651145428237035231072367364583996471", "0.6699905217924281324013328795516223436002879348854571762964769828255286829615636", "0.9305681557970262876119732444464047525478626898148588188078609457063963885589868", ])
const big_w4 = BigFloat.(["0.1739274225687269286865319746109997036176743479169467702462647873288657207063892", "0.3260725774312730713134680253890002963823256520830532297537352613642161665141882", "0.3260725774312730713134680253890002963823256520830532297537352588529504521363608", "0.1739274225687269286865319746109997036176743479169467702462646924539676606430575", ])
const big_x5 = BigFloat.(["0.04691007703066800360118656085030351743717404461873456856312774538495310585832495", "0.2307653449471584544818427896498955975163566965472200218989270432514549605914621", "0.5000000000000000000000000000000000000000000000000000000000797426589538788154181", "0.7692346550528415455181572103501044024836433034527799781012355866502245903569066", "0.9530899229693319963988134391496964825628259553812654314370407466671948296256858", ])
const big_w5 = BigFloat.(["0.1184634425280945437571320203599586813216300011062070077914363245751980472582409", "0.2393143352496832340206457574178190964561477766715707699864062992392239053715316", "0.2844444444444444444444444444444444444444444444444444444444573304920450434757956", "0.2393143352496832340206457574178190964561477766715707699864544060799612506070586", "0.1184634425280945437571320203599586813216300011062070077912456396135717532873701", ])
const big_x6 = BigFloat.(["0.03376524289842398609384922275300269543261713114385508756372519173669324957790098", "0.1693953067668677431693002024900473264967757178024149645927366470739082516964333", "0.3806904069584015456847491391596440322906946849299893249093024177128625328621882", "0.6193095930415984543152508608403559677093053150700106750906975822871374671378247", "0.8306046932331322568306997975099526735032242821975850354072633529260917483035732", "0.9662347571015760139061507772469973045673828688561449124362748082633067504220942", ])
const big_w6 = BigFloat.(["0.0856622461895851725201480710863664467634112507420219911993177198994728802711686", "0.1803807865240693037849167569188580558307609463733727411448696201185700189186321", "0.2339569672863455236949351719947754974058278028846052676558126599819571008101993", "0.233956967286345523694935171994775497405827802884605267655812659981957100810195", "0.1803807865240693037849167569188580558307609463733727411448696201185700189186256", "0.08566224618958517252014807108636644676341125074202199119931771989947288027117183", ])
const big_x7 = BigFloat.(["0.004929872133575382511273078541369005833050175678799509831107411346224851403894196", "0.05621464610426646944843588879386989279922531821579485139069338792689846975247951", "0.192287933937515541849713758599580029882154932092636671801817010573059843859954", "0.3984536481081884804663475670664267245733810143573168106648919508345540133232773", "0.6303829292704558125331985588105109567935632083246140000607245257050400884470481", "0.83556150914279693245080991327809828335238592867807829221382590113816878976327", "0.967225271993190330492166398923930257806838346389007730351566901746154753067759", ])
const big_w7 = BigFloat.(["0.01783956629577175664466161517779778330746762261739280193868888116464307618300876", "0.09200473466189314139337996394178583053265611188627297118565741860577372102041288", "0.1770039109583970541842419310398315314652008442538931692266384721379540913102143", "0.227630882575392394706842302518183045148130056062646081287058607732661591392765", "0.2272485914490278961711689421906388375849031602774791863163175474832987796256888", "0.1751216414188626855264193615824377275173037868653403184147776368054741810760185", "0.0831506726406550713732858835493252444443384180369754716308614360701945593918958", ])
const big_x8 = BigFloat.(["0.001731076483468685270312738321976022335247653348265799491291752676888324655463852", "0.02324239325675453541310616889139386853347071215419953798632062764425143212111116", "0.09674581137371957145465951844273824254653799833265552811149324227308844680975399", "0.2392034388083300373098325817761873300862438078606443203782515243905258660976843", "0.4377414076767430648608437870370205494748848997611776869673098571396591258307608", "0.6558058109441311212346397677935488371135950345845928481178266505564436739339613", "0.8471531551261965310775051873554285129614012469933877542714930228520273123505577", "0.9695608672869608660367505092846054315237604802943936622273926660421865678209417", ])
const big_w8 = BigFloat.(["0.00648051722632968580334106614227242117688991648717738051419594947334459502260248", "0.04249886199232947975876308636350701892667423974609345641479990672194805002887228", "0.1075793906538843862695869146830770045396978943792981645097158813680346763235746", "0.1750447315404564629273577322608578342561699810982462252671193876580950751308835", "0.2156888574332349972999088220266141505305931896033781190359618271951943097389702", "0.2125008990070870001049141617137792638781320237074018197374269892031613287174797", "0.1629674802715155610386405696905796745862955231428266578844571316431980172269869", "0.07723926187516242679748764711931263210554723183557817663632292673702394781061403", ])
const big_x9 = BigFloat.(["0.0008667056150679687310556652288569436907385437877138981057888864002168173244958056", "0.0122280227974677722385504897122547681746132158620974752074813304702917640058663", "0.05480618952483502181077931325849825384961877890619740899489187897956167653517274", "0.1479724698239139419056295126855349017672276520429764804253808066945167047226698", "0.2970327295923616776713877978535702864703987490795098148784984394014191846948765", "0.4876866420283321504345568480282204456865045811669770633300909323396820320457132", "0.6890765240440439634713012153821626128437843327643131136082765903924784802086815", "0.8626129599133903117371839678465821632020949373883030646894666014091469561601455", "0.9727063293384348507522097483930902940142000522105882750555178401920866287182623", ])
const big_w9 = BigFloat.(["0.003274998050208267294150508606138250683817401216433153311767094565563001679201521", "0.02313359082558968908460144360086466706488124569451662608076158761953109603160807", "0.06548060725856910278207153316883860438499930010336847275143993366561469729806786", "0.1218312674783635109299767023453009548358556338738575765857470968205141937769753", "0.173846779881900798110476532070518822473313843942857315313724461846196922415797", "0.2021610487996548918506456424823438545236363348536308756337183479670183496932752", "0.1940011564749999440632505455947670305529065622485673678531946231392676542355784", "0.1469746628249259371699540294690787861693361613628772591804787897776098200434126", "0.06929588840578785871487306266214902931125351670389135328916806459868426482607199", ])
const big_x10 = BigFloat.(["0.0005181961261082322472766705125340479900174875322281467529485321513894885979833173", "0.007465420091675458969500466087108891368802219689682897961139128243258364425744048", "0.03459491186740264883355418122867395454382629419333807279868225850754558414785065", "0.0975971115754346351913937631234074712307863612674323872325863975528816861786044", "0.206417705439011390678542948816149811668905321597780619366951240240363884154103", "0.3593223197305568860554706637412481214312776625092823039113159554783080462008666", "0.5409145569823813060562207909472447949677189410115970294850343468225381141652995", "0.7247101884173506583693766405048608650943421320009785899263353361616254227833195", "0.8792939364930664562292289635471936441225847549244316399022712337221415610078567", "0.9761172992753357690054548242993625400433499744882562766738928729785475675311865", ])
const big_w10 = BigFloat.(["0.001965567371635075131579256288544870059803127955115647264032642968078631060536703", "0.01432792816577584611857042476700654648649422540629984262180384241008794415186529", "0.04268191686661954873093685031206508271836823639234843167668804929665294052928837", "0.08508457499365887243509334455139864075115433485825750468759565514953919555209841", "0.1323019911493081912094714798178777091091080150778226083143129246153300131445892", "0.1708956795811918223417614118332969621708334291266240019249823757067261602912757", "0.1877671622133329938863531289790438941134765681225271869075098354721694488037552", "0.1744530516157494985126032352361095848091931713026742326752026513952084125816003", "0.1298293501440642503545269406245482685790299354859887555939751800285215578631445", "0.06069277789866390127910392759010844120253895627234178833389684295768569602184911", ])
const big_x11 = BigFloat.(["0.0003443027937109135938379257392787792195270698992816969762936160964556359137604324", "0.005013440864383067243350631424239433645064029252399323054292691041367933978740445", "0.02364331857940552032009849030947602840688383296539396136170458280031602132401195", "0.06832906693478315021724155223200949162548049943005956358316088710193697823676668", "0.1489678626315740314282860304118297803516562996303625981757521246031231427170625", "0.2688838656559724539423491761857709217537804019950614613561073810350146270995078", "0.4220897985161747732321112109047331469287654634290517346997682663343660208754401", "0.5930637127479588495458595939927986937605950267308572459511719743821404576187648", "0.7592028345589139171393141953611581168621813399181412693226876740966955975241855", "0.895370029154236793266330264734464498550020456534012095051569572437200644081219", "0.9794005414614251958306889531042697801706857543035411525475730358436694277191778", ])
const big_w11 = BigFloat.(["0.001308482060993663242256934335551828602557597584158319864496558916136475580582068", "0.00969288709408650133185273832612490903017063666717782862361318228555141531954964", "0.02966389152910070664026088218093860374186761085874794771767446706724502459211172", "0.06143343298637082474236249240006655872937604792306683029136169082125059831687015", "0.1004460191987578538388849340828766588722640884773582815408521130982985507869617", "0.1383922249121359956175747893411838985211421142619578716591922120708412482654264", "0.1653902823184988185876467092764404923048134540123907701310142247185824604911606", "0.1727117730020824070651803079243652850518442833088207015220610680720652237250866", "0.1552819614608011145886733180725256592817449838664247753879602818711437247875774", "0.1132688655746851899854851412461426927195457990615465803363035033863602674502828", "0.05241017986248692435982175281378341314467338397835009292547069769252501068438447", ])
const big_x12 = BigFloat.(["0.0002452842649772222144869997536432543470205814371170075690180054147088520992775438", "0.003593698020213691584953180824439056033669956241158510051647368882583871270772168", "0.01712292595159614370417434779200315632782276920007431158061911297835067104148647", "0.05020561232318819384573670192053134139721951029885763772161090595236481462236433", "0.1115235855573625644218104509890506301070703909739116102593900185940751708338317", "0.2060030029051239758752495933280674817971879824277011300806331528780271180801483", "0.3324626975136065400973675489452151731186473889850867214190447787726903983452818", "0.4826067009659319425485030369276700182993773813799224674012307668491958228063377", "0.6416794701239928589863342356411077314045630121734446869043875124123942657411672", "0.7907090871833554068663998980238029847238415941839073624406370514064356527864469", "0.9098838287655625921196627460245725561418481528176771869176662052248263188597252", "0.982347937715761951022141891215901227156130866563412648512060764471403968478102", ])
const big_w12 = BigFloat.(["0.0009331998830671428063097434802853682009550206244007777128833566469644722444453541", "0.006977495915143715985530451668181416880378092685376110400758040623857214633101594", "0.02169468902199853397715717399245055984405286952548586980559524949213660052353543", "0.04597069439559112469266362276166163303194960891828198574630707656287883134112197", "0.07752703869583178458842135271764051929635605596237314175811225613121850661805001", "0.1112525181837396068263131380719231904839616235119275896079063799871294167236009", "0.140273106008583333229227269735827131918570705030426981927389251409881630664525", "0.1575171300868296275541516487246811892573829874737442836958479223034436156494236", "0.1574083422236489759715520806009181432232319978495268878658371301577126086414867", "0.1372838327177858585860313720888032238952499990833424890457450322462456922961358", "0.09819669547418950067876642127280557873215905943121389372635589441374029408861288", "0.04496525739359079510387572488482204523575197990389998870726241002479111657595298", ])

const x1 = [0.5, ]
const w1 = ["1.0", ])
const x2 = [0.2113248654051871, 0.7886751345948129, ]
const w2 = ["0.5", "0.5", ])
const x3 = [0.11270166537925831, 0.5, 0.8872983346207417, ]
const w3 = ["0.2777777777777778", "0.4444444444444444", "0.2777777777777778", ])
const x4 = [0.06943184420297371, 0.33000947820757187, 0.6699905217924281, 0.9305681557970263, ]
const w4 = ["0.17392742256872692", "0.32607257743127305", "0.32607257743127305", "0.17392742256872692", ])
const x5 = [0.046910077030668004, 0.23076534494715845, 0.5, 0.7692346550528415, 0.953089922969332, ]
const w5 = ["0.11846344252809454", "0.23931433524968324", "0.28444444444444444", "0.23931433524968324", "0.11846344252809454", ])
const x6 = [0.03376524289842399, 0.16939530676686773, 0.38069040695840156, 0.6193095930415985, 0.8306046932331322, 0.966234757101576, ]
const w6 = ["0.08566224618958518", "0.1803807865240693", "0.23395696728634552", "0.23395696728634552", "0.1803807865240693", "0.08566224618958518", ])
const x7 = [0.004929872133575383, 0.05621464610426647, 0.19228793393751553, 0.3984536481081885, 0.6303829292704558, 0.8355615091427969, 0.9672252719931903, ]
const w7 = ["0.017839566295771755", "0.09200473466189314", "0.17700391095839704", "0.2276308825753924", "0.2272485914490279", "0.1751216414188627", "0.08315067264065507", ])
const x8 = [0.0017310764834686852, 0.023242393256754534, 0.09674581137371957, 0.23920343880833003, 0.4377414076767431, 0.6558058109441312, 0.8471531551261965, 0.9695608672869609, ]
const w8 = ["0.006480517226329686", "0.04249886199232948", "0.10757939065388439", "0.17504473154045647", "0.215688857433235", "0.212500899007087", "0.16296748027151556", "0.07723926187516243", ])
const x9 = [0.0008667056150679687, 0.012228022797467772, 0.05480618952483502, 0.14797246982391393, 0.29703272959236166, 0.4876866420283322, 0.689076524044044, 0.8626129599133903, 0.9727063293384348, ]
const w9 = ["0.003274998050208267", "0.02313359082558969", "0.0654806072585691", "0.12183126747836351", "0.1738467798819008", "0.20216104879965488", "0.19400115647499994", "0.14697466282492594", "0.06929588840578786", ])
const x10 = [0.0005181961261082322, 0.007465420091675459, 0.03459491186740265, 0.09759711157543463, 0.2064177054390114, 0.3593223197305569, 0.5409145569823813, 0.7247101884173507, 0.8792939364930664, 0.9761172992753357, ]
const w10 = ["0.0019655673716350752", "0.014327928165775846", "0.04268191686661955", "0.08508457499365887", "0.13230199114930818", "0.1708956795811918", "0.187767162213333", "0.1744530516157495", "0.12982935014406424", "0.060692777898663904", ])
const x11 = [0.0003443027937109136, 0.005013440864383067, 0.02364331857940552, 0.06832906693478315, 0.14896786263157402, 0.26888386565597244, 0.4220897985161748, 0.5930637127479589, 0.7592028345589139, 0.8953700291542368, 0.9794005414614252, ]
const w11 = ["0.0013084820609936632", "0.009692887094086501", "0.029663891529100705", "0.06143343298637082", "0.10044601919875785", "0.13839222491213599", "0.1653902823184988", "0.1727117730020824", "0.15528196146080112", "0.11326886557468518", "0.05241017986248692", ])
const x12 = [0.0002452842649772222, 0.0035936980202136916, 0.017122925951596143, 0.050205612323188195, 0.11152358555736257, 0.20600300290512397, 0.3324626975136065, 0.48260670096593195, 0.6416794701239928, 0.7907090871833554, 0.9098838287655626, 0.9823479377157619, ]
const w12 = ["0.0009331998830671429", "0.006977495915143716", "0.021694689021998535", "0.04597069439559112", "0.07752703869583179", "0.1112525181837396", "0.14027310600858334", "0.15751713008682963", "0.15740834222364897", "0.13728383271778585", "0.09819669547418951", "0.04496525739359079", ])
