Qual Ă© o prĂłximo membro ...? - Estamos procurando uma fĂłrmula para o enĂ©simo termo da sequĂȘncia, gerando funçÔes e transformação Z

VocĂȘ pode baixar o arquivo com o cĂłdigo e os dados na postagem original no meu blog

A Wolfram Language possui quatro recursos totalmente impressionantes: FindSequenceFunction , RSolve , DifferenceRootReduce e FindFormula . Neste artigo, discutiremos seus recursos e falaremos sobre as funçÔes que estĂŁo intimamente relacionadas a eles - para procurar FindLinearRecurrence recursĂŁo linear FindLinearRecurrence (coeficientes de uma equação de recorrĂȘncia linear) que geram as ZTransform transformação Z GeneratingFunction e ZTransform .

A primeira função , FindSequenceFunction, procura uma expressĂŁo para seu enĂ©simo membro por uma sequĂȘncia de nĂșmeros sem exigir mais nada.

 Hold @ FindSequenceFunction[{1, 1, 2, 3, 5, 8, 13}, n] 



 FindSequenceFunction[ {-2, 4Sqrt[Pi], -16, 16Sqrt[Pi], -128/3, 32Sqrt[Pi], -1024/15, 128Sqrt[Pi]/3, -8192/105, 128Sqrt[Pi]/3}, n] 



A segunda função , RSolve, resolve equaçÔes de recorrĂȘncia de vĂĄrios tipos. Os elementos podem parecer a[f[n]], a[f[f[n]]], a[f[f[ texto...f[n] texto...]]], onde f tem a forma: n + A (equaçÔes da diferença aritmĂ©tica), B * n - equaçÔes geomĂ©tricas ou da diferença q), B * n + a (equaçÔes da diferença funcional aritmĂ©tico-geomĂ©trica), B * n ^ d (função geomĂ©trica da potĂȘncia equaçÔes da diferença), (A * n + B) / (C * n + D) (equaçÔes da diferença funcional fracionĂĄria linear).

 RSolve[ { a[n + 3]==2 * a[n], a[1]==α, a[2]==ÎČ, a[3]==Îł }, a, n ] 



 RSolve[ { v[n]==(2 * Pi * v[n - 2]) / n, v[2]==Pi, v[3]==(4 * Pi) / 3 }, v @ n, n ] 



A terceira função - DifferenceRootReduce - procura por uma relação de recorrĂȘncia para uma sequĂȘncia de nĂșmeros, cujo enĂ©simo membro possui uma determinada forma.

 DifferenceRootReduce[-2 * n * Pi * Factorial[(n * 2) - 1], n ] 



 RSolve[ { (-8 * y[n]) + n * y[2 + n]==0, y[-1]==1/4, y[0]==0, y[1]==-2, y[2]==4Sqrt[Pi] }, y, n ] 



Essa função pode fazer muito mais, digamos, verificar identidades com relação Ă s sequĂȘncias, por exemplo:

 DifferenceRootReduce[Fibonacci[2 * n]==Fibonacci[n] * LucasL[n], n] 



Aqui, LucasL Ă© uma sequĂȘncia de nĂșmeros Luc (na verdade, Ă© uma sequĂȘncia de Fibonacci, apenas os primeiros membros nĂŁo sĂŁo 1, 1, mas 1, 3.

 Hold @ DifferenceRootReduce @ LucasL @ n 



 DifferenceRootReduce[LucasL[n]==Fibonacci[n - 1] + Fibonacci[n + 1]] 



Como encontrar uma fĂłrmula de recorrĂȘncia para uma sequĂȘncia?


O mĂ©todo de pesquisa para um membro comum de uma sequĂȘncia geralmente Ă© baseado na necessidade de selecionar uma equação de recorrĂȘncia.

Pode funcionar assim: vamos procurar o enĂ©simo membro da sequĂȘncia no formato f[n]= sumi=1ka[i]f[n−i]. Vamos ter os primeiros membros da sequĂȘncia:

 sequence = {1, 0, 1, 2, 5, 12, 29, 70, 169, 408, 985, 2378, 5741, 13860, 33461} 



Vamos tentar encontrar uma expressĂŁo para o enĂ©simo termo no formulĂĄrio f[n]= sumi=11a[i]f[n−i]=a[1]f[n−1]:

 seauenseEq1 = MovingMap[ Function[ Dot[Part[#, 1;;1], {a @ 1}]==Part[#, -1] ], sequence, 1 ] 



 Hold @ Solve @ seauenseEq1 



Como vocĂȘ pode ver, nĂŁo hĂĄ soluçÔes.

Vamos tentar pesquisar agora no formulĂĄrio f[n]= sumi=12a[i]f[n−i]=a[1]f[n−1]+a[2]f[n−2]:

 seauenseEq2 = MovingMap[ Function[ Dot[Part[#, 1;;2], {a @ 1, a @ 2}]==Part[#, -1] ], sequence, 2 ] 



 Hold @ Solve @ seauenseEq2 



Como vemos, acabou. Portanto, o enĂ©simo termo tem a forma: f[n]=f[n−1]+2f[n−2].

Na verdade, existe uma função FindLinearRecurrence que permite encontrar recursão linear, semelhante à maneira como fizemos:

 Hold @ FindLinearRecurrence @ sequence 



Usando a função LinearRecurrence , LinearRecurrence pode estender a sequĂȘncia:

 LinearRecurrence[{2, 1}, sequence[[1;;2]], 50] 



Ou combine tudo em uma linha, construindo uma função que: estenda a sequĂȘncia, produza uma equação de diferença e encontre uma fĂłrmula geral para o enĂ©simo termo:

 sequenseExtension[list_, n_] := Module[ {lr, eq}, lr = FindLinearRecurrence @ list; eq = Flatten[ { a[k]==Total[ Table[ a[k + -i] * Part[lr, i], {i, 1, Length @ lr} ] ], Table[a[i], list[[i]]], {i, 1, Length @ lr}] } ]; <| "" -> eq, "" -> FullSimplify[a[k] /. Part[RSolve[eq, a, k], 1]], "" -> LinearRecurrence[lr, Part[list, Span[1, Length[lr]]], n] |> ]; 

 Hold @ sequenseExtension[{1, 1, 2, 3, 5}, 20] 



 Hold @ sequenseExtension[{1, 2, 2, 1, 1, 2, 2, 1}, 20] 



 Hold @ sequenseExtension[ {1, 0, -1, 0, 2, 0, -2, 0, 3, 0, -3, 0, 4, 0, -4}, 25 ] 



Como encontrar a fĂłrmula para o enĂ©simo membro de uma sequĂȘncia?


ConversĂŁo Z


A transformação Z consiste em calcular uma sĂ©rie da forma  sumn=0 inftyf(n)z−nde função discreta f(n). Essa transformação nos permite reduzir a equação de recorrĂȘncia para definir a sequĂȘncia na equação da imagem da função f(n), que Ă© semelhante Ă  transformada de Laplace, que reduz as equaçÔes diferenciais Ă s algĂ©bricas.

Veja como funciona:

 Grid[ Transpose[ Function[ { #, Map[TraditionalForm, Map[FullSimplify, ZTransform[#, n, z]]] } ][ { f[n - 2], f[n - 1], f @ n, f[n + 1], f[n + 2] } ] ], Background -> White, Dividers -> All ] 



Vejamos um exemplo, digamos, pegue a conhecida sequĂȘncia de Fibonacci:

 fibonacciEq = f[n]==f[n - 1] + f[n - 2]; initialConditions = {f[1] -> 1, f[2] -> 1}; 

É claro que ele deve ser reescrito no formulĂĄrio, como mostrado abaixo, para que construçÔes como f(−1)depois de aplicar a transformação Z.

 fibonacciEq = f[n + 2]==f[n + 1] + f[n]; initialConditions = {f[0] -> 1, f[1] -> 1}; 

Realizamos a transformação Z:

 fibonacciEqZTransformed = ReplaceAll[fibonacciEq, pattern:f[__] :> ZTransform[pattern, n, z]] 



Resolvemos a equação para a imagem da função f - ZTransform [f [n], n, z]:

 fZTransformed = ReplaceAll[ ZTransform[f @ n, n, z], Part[Solve[fibonacciEqZTransformed, ZTransform[f @ n, n, z]], 1] ] 



Realizamos a transformação Z inversa, substituindo as condiçÔes iniciais ao mesmo tempo (substituĂ­mos n por n-1 na expressĂŁo final para que nossa sequĂȘncia tenha a indexação correta (do primeiro, nĂŁo do termo zero):

 ReplaceAll[InverseZTransform[fZTransformed /. initialConditions, z, n], n -> (n - 1) ] 



Naturalmente, isso pode ser automatizado criando sua prĂłpria contraparte do RSolve:

 myRSolve[eq_, initials_, f_, n_] := Module[ {z, initialsInner, eqZTransformed, fZTransformed}, initialsInner = ReplaceAll[initials, f[x_] :> f[x - 1]]; eqZTransformed = ReplaceAll[eq, pattern:f[__] :> ZTransform[pattern, n, z]]; fZTransformed = ReplaceAll[ZTransform[f @ n, n, z], Part[Solve[eqZTransformed, ZTransform[f @ n, n, z]], 1] ]; FullSimplify[ InverseZTransform[fZTransformed /. initialsInner, z, n] /. n -> (n - 1) ] ]; 

 myRSolve[ { f[n + 2]==(2 * f[n + 1]) + -(5 * f[n]) }, {f[1] -> 20, f[2] -> 0}, f, n ] 



 RSolve[ { f[n + 2]==(2 * f[n + 1]) + -(5 * f[n]), f[1]==20, f[2]==0 }, f, n ] 



Mas, é claro, o RSolve contém muito mais possibilidades para resolver uma grande variedade de equaçÔes discretas, nas quais não iremos nos aprofundar mais detalhadamente:

 RSolve[a[n]==(n * a[n]) + n, a, n], RSolve[ { a[n + 1]==(2 * a[n]) + (3 * a[n]) + 4, a[0]==0 }, a, n ], RSolve[ y[n + 1 * 3]==(2 * y[n + 1 * 6]) + n * 2, y, n ] 







Gerando funçÔes


Gerando função de sequĂȘncia a(n)essa Ă© uma função G(x), cuja expansĂŁo na sĂ©rie Taylor (ou, mais amplamente, Laurent) tem a forma - G(x)= sumi=0 inftya(n)xn. Em outras palavras, os coeficientes de potĂȘncias de x na expansĂŁo da função em uma sĂ©rie determinam nossa sequĂȘncia.

Função Say G(x)= frac11−xĂ© uma função geradora da sequĂȘncia 1, 1, 1, 1, ...:

 Series[1 / (1 + -x), {x, 0, 10}] 



Uma função G(x)= frac11−x−x2Ă© uma função geradora da sequĂȘncia de Fibonacci 1, 1, 2, 3, 5, 8, 13, ...:

 Series[(1 * 1) + (-x) + -(x * 2), {x, 0, 10} ] 



HĂĄ tambĂ©m um tipo de função geradora - uma função geradora exponencial, que para a sequĂȘncia a(n)tem a forma - G(x)= sumi=0 infty fraca(n)n!Xn.

Digamos, para as seqĂŒĂȘncias 1, 1, 1, 1 ... e 1, 1, 2, 3, 5, 8, 13, ... as funçÔes geradoras exponenciais sĂŁo as seguintes - exe  frac1 sqrt5e− frac2x1+ sqrt5 left(e sqrt5x−1 right):

 ReplaceAll[Normal[Series[E ^ x, {x, 0, 10}]], Power[x, n_] :> ((x ^ n) * Factorial[n]) ] 



 ReplaceAll[ Normal[ FullSimplify[ Series[ Plus[E, (-(2 * x * 1)) + 5 * ((E * 5 * x) - 1) * 5 ], {x, 0, 10} ] ] ], Power[x, n_] :> ((x ^ n) * Factorial[n]) ] 



A função de produção na Wolfram Language pode ser encontrada por duas funçÔes - GeneratingFunction e FindGeneratingFunction (exponencial com ExponentialGeneratingFunction ):

 GeneratingFunction[-(m * Factorial[n]), {n, m}, {x, y}] 



 TraditionalForm[ FullSimplify[ ExponentialGeneratingFunction[-(n * Factorial[n - 1] * Factorial[2 * n]), n, x] ] ] 



Existem muitos mĂ©todos para encontrar um membro comum de uma sequĂȘncia usando funçÔes geradoras. NĂŁo vamos nos aprofundar nisso em detalhes, digamos, apenas uma boa teoria estĂĄ no site genfunc.ru .

Um dos métodos é semelhante à transformação Z:

 generatingFEq = ReplaceAll[ f[n + 2]==f[n + 1] + f[n], pattern:f[__] :> GeneratingFunction[pattern, n, z] ], generatingF = ReplaceAll[ GeneratingFunction[f @ n, n, z], Part[Solve[generatingFEq, GeneratingFunction[f @ n, n, z]], 1] ], nthTerm = SeriesCoefficient[generatingF, {z, 0, n}], FullSimplify[ ReplaceAll[ReplaceAll[nthTerm, {f[0] -> 1, f[1] -> 1}], n -> (n - 1) ], GreaterEqual[n, 1] ] 









OEIS - EnciclopĂ©dia de sequĂȘncia inteira on-line e integração com a Wolfram Language


Uma coleção absolutamente impressionante de sequĂȘncias numĂ©ricas estĂĄ disponĂ­vel na Internet - OEIS (EnciclopĂ©dia On-Line de SequĂȘncias Inteiras) . Foi criado por Neil Sloan durante sua carreira de pesquisador na AT&T Labs. A OEIS armazena informaçÔes sobre seqĂŒĂȘncias inteiras de interesse para amadores e especialistas em matemĂĄtica, combinatĂłria, teoria dos nĂșmeros, teoria dos jogos, fĂ­sica, quĂ­mica, biologia, ciĂȘncia da computação. No momento, 329085 seqĂŒĂȘncias sĂŁo coletadas lĂĄ. Um registro no OEIS inclui os primeiros elementos de uma sequĂȘncia, palavras-chave, descrição matemĂĄtica, sobrenomes dos autores, links para literatura; existe a possibilidade de traçar ou reproduzir uma representação musical da sequĂȘncia. Uma pesquisa no banco de dados pode ser realizada por palavras-chave e subsequĂȘncia.

Recentemente, a integração com esse banco de dados apareceu dentro da Wolfram Language (ao usĂĄ-lo, Ă© importante entender que este Ă© um desenvolvimento do usuĂĄrio - recentemente vocĂȘ pode fazer o upload do seu cĂłdigo para o RepositĂłrio de FunçÔes Wolfram ). Basta digitar o nĂșmero da sequĂȘncia em que vocĂȘ estĂĄ interessado ou uma lista de nĂșmeros.

 OEISSequenceData = ResourceFunction @ "OEISSequenceData"; OEISSequence = ResourceFunction @ "OEISSequence"; 

ResourceFunction ["OEISSequence"] - simplesmente retorna os primeiros membros da sequĂȘncia:

 Hold @ OEISSequence @ "A666" 



ResourceFunction ["OEISSequenceData"] - emite um conjunto de dados com informaçÔes completas do banco de dados:

 sequenceData[666] = OEISSequenceData[666, "Dataset"] 



Digamos que vocĂȘ possa "retirar" o cĂłdigo da Wolfram Language:

 Hold @ Normal @ sequenceData[666]["CodeWolframLanguageStrings"] 



Ou um conjunto de sequĂȘncias selecionadas aleatoriamente com informaçÔes de interesse para elas:

 randomSequences = Dataset @ Map[ Normal, OEISSequenceData[RandomInteger[{1, 300000}, 10], "Dataset"] ]; 

 Function[ Framed[#, FrameStyle -> None, FrameMargins -> 5, Background -> White] ][ Grid[ Join[ { Map[Style[#, Bold, 18]&, {"", "", "", " ", "  "} ] }, Map[ Function[ Map[ Function[ TextCell[#, LineIndent -> 0, FontSize -> 12, FontFamily -> "Open Sans Light"] ], { Style[Part[#, 1], 16], Row[Part[#, 4], "\n"], Row[Part[#, 3], "\n"], Style[Row[Part[#, 2], "; "], 10], ListLinePlot[Part[#, 2], ImageSize -> Full] } ] ], Values @ Normal @ randomSequences[All, {"Name", "Sequence", "References", "Formulae"}] ] ], Dividers -> {{None, {LightGray}, None}, {None, {LightGray}, None}}, ItemStyle -> Directive[FontSize -> 12, FontFamily -> "Open Sans Light"], ItemSize -> {{15, 25, 10, 15, 15}, Automatic}, Alignment -> {Left, Center}, Background -> {None, {LightOrange, White}} ] ] 



Procure uma fĂłrmula em potencial


Por fim, gostaria de mencionar a função FindFormula , que, com base em um determinado conjunto de nĂșmeros, cria uma fĂłrmula que pode descrevĂȘ-los. Podemos aceitar as dependĂȘncias, vocĂȘ pode escolher muito de diferentes classes de funçÔes.

 data = Table[ { x, Sin[2 * x] + Cos[x] + RandomVariate[NormalDistribution[0, 0.2]] }, {x, RandomReal[{-10, 10}, 1000]} ]; ListPlot[data, Background -> White, ImageSize -> 600] 



 formulas = FindFormula[data, x] 



Como vocĂȘ pode ver, a Wolfram Language pegou uma função muito prĂłxima daquela com base na qual dados "ruidosos" foram construĂ­dos, a saber - Sin [2x] + Cos [x]:

 Plot[formulas, {x, -10, 10}, PlotStyle -> AbsoluteThickness[3], Prolog -> {AbsolutePointSize[5], Gray, Point @ data}, Background -> White, ImageSize -> 800, PlotLegends -> "Expressions" ] 



VocĂȘ pode criar mais dependĂȘncias, digamos 10:

 formulas = FindFormula[data, x, 10] 



 Plot[formulas, {x, -10, 10}, PlotStyle -> AbsoluteThickness[3], Prolog -> {AbsolutePointSize[5], LightGray, Point @ data}, Background -> White, ImageSize -> 800, PlotLegends -> "Expressions" ] 



É importante notar que existe uma função semelhante na funcionalidade que procura uma distribuição de probabilidade - FindDistribution .

Para cooperação - escreva uma mensagem pessoal em Habré ou no meu grupo VKontakte .
Canal do YouTube - seminĂĄrios on-line e vĂ­deos de treinamento.
Inscrição para novos cursos . Curso online pronto.

Source: https://habr.com/ru/post/pt475728/


All Articles