Métodos computacionais / 2019

Davi C. Rodrigues
Aula 8

e-mail: davi@cosmo-ufes.org
página do curso: davi.cosmo-ufes.org/mc2019

Item 0: lembrete dos trabalhos de final de curso
item 1: revisão da última aula (vimos também a parte de interpolação numérica?)

Cap.8:  Problemas numéricos

8.1 Números no Mathematica

Em muitas linguagens é necessário declarar o tipo de número que as funções podem usar como argumento. Tal como não precisa-se declarar os tipos de variáveis, a declaração de tipo de número não é necessária para o Mathematica.

data = {
Join[{"Casos"},Range[10]],
Join[{"Caso n inteiro"},Table[Sin[π/n], {n,1,10}]],
Join[{"Caso n real" },Table[Sin[π/n], {n,1.,10.}]],
Join[{"Caso com desvio real"},Table[Sin[π/(n + 0.001)], {n,1,10}]],
Join[{"Caso com desvio racional"},Table[Sin[π/(n + (10^(-3)))], {n,1,10}]]
} ;
TableForm@data

Só para mostrar uma forma mais elegante de mostrar os mesmos dados...

Grid[data, Alignment->Left,Frame->All]

Head[(10^(-6))]

Head[1]

Head[1.]

Internamente, o primeiro caso é tratado de forma claramente diferente do segundo caso. 

O primeiro busca por identidades (exatas) do seno, nos outros dois casos, o tratamento da função seno é numérico,  usando ponto flutuante (que é uma representação aproximada de números reais).

Há 4 tipos de números no Mathematica: Integer, Rational, Real and Complex. Ao contrário da definição matemática desses conjuntos de números, todos esses tipos de números no Mathematica são disjuntos entre si. Em paticular o número 1 é necessariamente “Integer”, não é um caso particular de “Real”. Entretanto, “1.”  não é Integer e é Real.

Ademais, um Rational não é exatamente a mesma coisa que a divisão de dois inteiros.
3/4

Head[3/4 ]
Head[3] 
Head[4]

(3/4) /. ((x_)/(y_)) -> x+y

Semelhantemente com complexos

(3 + h 5) /. (x_ + h y_) -> x y
(3 + I 5) /. (x_ + I y_) -> x y

1 == 1.
5. + I 0. == 5.

1 === 1.
5. + I 0. === 5.

Para selecionar as partes real e imaginária, podemos usar diversas formas, por exemplo...

re[z_] := (1/2)(z + Conjugate[z])
re[2 + 3 I]

Ou simplesmente

Im[2 + 3 I]

ArcTan[(2/3)]

Abs[2+3I] (E^(I ArcTan[2/3]))

Abs[2+3I] (E^(I ArcTan[3/2]))

Abs[2+3I]

ArcTan

Exercício:

complexToPolar[x_]:= {Abs[x], ArcTan[Im[x]/Re[x]]}

N@complexToPolar[2 + 3I]

complexToPolar[(E^(π I/3))]

complexToPolar2[x_]:= Abs[x](E^(ArcTan[Im[x]/Re[x]] I ))

complexToPolar2[(E^(I π/3.))]
complexToPolar2[(E^(I π/3))]

8.2 Computação numérica

Precisão e acurácia

Primeiramente, segunda a definição usada em inglês e português no contexto científico (não computacional):

No contexto de representação por ponto flutuante de números reais, considere as seguintes representações de π:

3.1 - Baixa precisão, alta acurácia.
3.2345785634563456343 - Alta precisão, baixa acurácia.
3.1415926535897932385 - Alta precisão e acurácia

Alguns números especiais no Mathematica podem ser gerados com precisão (e acurácia) artbitrários (melhor dizendo, muito altas) usando...

N[π,500]
N[E,50]

Head@π

π + 0.01

2. π

2 π

As funções Accuracy e Precision

Essas funções quantificam acurácia e precisão, contudo os nomes dessas funções são inspirados nos conceitos acima,  o significado delas não são exatamente a mesma coisa. Em particular, elas não quantificam nada com respeito ao “valor verdadeiro”, pois esse não é conhecido.

A grosso modo, Accuracy se refere ao erro absoluto de um número, enquanto Precision ao erro relativo.

Accuracy

? Accuracy

Accuracy[1]
Accuracy[π]
Accuracy[1.]
Accuracy[1.000]
Accuracy[1.00000000000000000]
Accuracy[1.00000000000000000000]

MachineNumberQ[1.00``3]

Accuracy[1.00``3]

Esses dois valores de 15.9546 veremos em breve o que significam.

Alterar os valores ou a quantidade de casas à esquerda do ponto não altera o valor de Accuracy

Accuracy[10.00000000000000000]
Accuracy[22345.00000000000000000000]

Alterar os valores das cases à direita do ponto também não altara o valor de Accuracy

Accuracy[10.00000000000000001]
Accuracy[22345.00000000045600000003]

Pode-se forçar uma dada acurácia a um número das seguintes formas

Accuracy[2.2436]

SetAccuracy[230876876.2436, 4]
SetAccuracy[23.2436, 50]
23.2436``50
Accuracy[%]

With uncertainty dx, (RefLink[Accuracy, paclet:ref/Accuracy])[x] is -(RefLink[Log, paclet:ref/Log])[10,dx].

“Machine number” vs “arbitrary-precision number”.

Extraído do help do Mathematica (tutorial/MachinePrecisionNumbers)

Whenever the input contains any machine-precision numbers, the Wolfram Language does the computation to machine precision. [Unless otherwise specified]

(...) Computers have special hardware or microcode for doing floating-point calculations to a particular fixed precision. The Wolfram Language makes use of these features when doing machine-precision numerical calculations. 

The main advantage of using the built-in floating-point capabilities of your computer is speed. Arbitrary-precision numerical calculations, which do not make such direct use of these capabilities, are usually many times slower than machine-precision calculations. 

There are several disadvantages of using built-in floating-point capabilities. One already mentioned is that it forces all numbers to have a fixed precision, independent of what precision can be justified for them. 

A second disadvantage is that the treatment of machine-precision numbers can vary slightly from one computer system to another. In working with machine-precision numbers, the Wolfram Language is at the mercy of the floating-point arithmetic system of each particular computer. If floating-point arithmetic is done differently on two computers, you may get slightly different results for machine-precision Wolfram Language calculations on those computers.

Números de máquina podem ter diferentes valores para acurácia

$MachinePrecision

ScientificForm[100000000.234523452345+ π]

4.141592653589793`

{Accuracy[#], MachineNumberQ[#]} &/@ {1., 6.1234,20000000000000.1, 20000000000000000000.12 }

Accuracy[1.]
Accuracy[6.1234]
Accuracy[20000000000000.1]

MachineNumberQ[1]
MachineNumberQ[1.2]
MachineNumberQ[1.2``20]

Exemplos...

Precision

? Precision

Precision[1]
Precision[π]
Precision[1.]
Precision[1.000]
Precision[1.00000000000000000]
Precision[1.00000000000000000000]

$MachinePrecision

With absolute uncertainty dx, (RefLink[Precision, paclet:ref/Precision])[x] is -(RefLink[Log, paclet:ref/Log])[10,dx/x]. (i.e, Log10[x/dx])

Para o último exemplo do uso de Precision acima, a incerteza dx é 0.00000000000000000001, enquanto x é 1. (ou 1.000000000... neste caso dá na mesma). Logo

-Log[10,0.00000000000000000001]

Note que o resulado de Precision não precisa ser inteiro...

Precision[9.0000000000000000000000]

Isto pois Precision depende tanto do valor do número (x) quanto de sua incerteza (dx). Quanto maior for x e menor for dx, maior será a precisão.

Precision[1. (10^(-56))]
Precision[1.000000000000000000000000000000000 (10^(-56))]
Accuracy[1.0 (10^(-10))]
Accuracy[1.0``20 (10^(-10))]

Exemplo de uso de setprecision e setaccuracy

medida = 2.123456789;
incerteza = 0.0003456345;
incerteza=SetPrecision[incerteza,2]
acuracia=Accuracy[incerteza]
medida=SetAccuracy[medida,acuracia]

incerteza=SetPrecision[incerteza,2]  (*Para precisão de 1 algarismo significativo na incerteza*);
acuracia=Accuracy[incerteza];
medida=SetAccuracy[medida,acuracia];
{medida,incerteza}

Sobre Precision e Accuracy como critérios de convergência: PrecisionGoal, AccuracyGoal

Poderíamos comentar de outras variações sobre o tema acima, mas em termos de cálculos numéricos há uma diferença significativa, pois acurácia e precisão se referem a critérios de convergência de problemas cuja solução, em geral, é desconhecida.

With (RefLink[PrecisionGoal, paclet:ref/PrecisionGoal])->p and (RefLink[AccuracyGoal, paclet:ref/AccuracyGoal])->a, the Wolfram Language attempts to make the numerical error in a result of size x be less than (10^(-a))+(Abs[x])(10^(-p)).

f[x_]=Sin[x^2];
m=FindMinimum[f[x],{x,2},AccuracyGoal->∞,PrecisionGoal->20]

xsol = x /. m[[2]]

Precision[xsol]
Accuracy[xsol]
MachineNumberQ[xsol]

m = FindMinimum[f[x],{x,2}]

xsol = x /. m[[2]]

Precision[xsol]

m=FindMinimum[f[x],{x,2}, AccuracyGoal->8,PrecisionGoal->10, WorkingPrecision->20]

xsol = x /. m[[2]]

Precision[xsol]
Accuracy[xsol]

FindMinimum[f[x],{x,2},AccuracyGoal->18,PrecisionGoal->20]

m=FindMinimum[f[x],{x,2},AccuracyGoal->18,PrecisionGoal->20, WorkingPrecision->40]

xsol = x /. m[[2]]

Precision[xsol]
Accuracy[xsol]

Precision[1.23`20]
Accuracy[1.23`20]

19.910094888560604`

Precision[1.23``20]
Accuracy[1.23``20]

Exercício

Fazer exercícios 1 - 3 da página 281 e 282.