/* distInverte.js
Esta unidade define os elementos para se obter
as inversas das distribuições de probabilidade.
Tem que ser usada junto com a unidade "distGlobais.js"
e com a unidade com a função que se quer inverter.
A função que se quer inverter, juntamente com seus
parâmetros, deve ser colocada dentro
de um objeto do tipo "ObjetPiloto"
*/
/* ************ CLASS OBJETOPILOTO *****************
Encapsula as propriedades e métodos necessários para a
criação de um objeto a ser usado como parâmetro das funções
zbrac e "inverte" na geração da inversa de uma função.
Os parâmetros da função são propriedades do objeto.
O método "func(x)" deve retornar um objeto da classe
"Resultado" onde a propriedade "valor" é a que contém
o resultado da função.
Pré-requisito:
* classe Resultado (em distGlobais.js)
*/
function ObjetoPiloto(par1, par2){
this.par1=par1
this.par2=par2
this.func=function func(x){
var R = new Resultado()
if(erro) return R.msg('mensagem de erro')
return R.val(função(x,this.par1,this.par2))
}// method func
}// objetoPiloto
function SIGN(a,b){
if(b >= 0.0) return Math.abs(a)
else return -Math.abs(a)
}// function SIGN
/* *********** FUNCTION ZBRAC(obj, y, x1, x2, NTRY) ****
Calcula um intervalo que contenha a raiz da função obj.func(x)=y.
O objeto passado à função deverá ter o método func(x), que por
sua vez deverá retornar um objeto da classe "Resultado".
x1 e x2 são os limites inferior e superior de uma proposta
inicial de intervalo.
A função zbrac retorna um objeto da classe "Resultado". Esse objeto
possui as propriedades "x1" que contém o limite inferior do
intervalo e "x2" o limite superior de um intervalo que contém
a raiz. NTRY é o número de tentativas de se encontrar o intervalo.
Pré-requisito:
* classe Resultado
*/
function zbrac(obj, y, x1,x2,NTRY){
var R = new Resultado()
var f1, f2, G, j
if(x1==x2) return R.msg('Os valores iniciais em zbrac
tem que ser diferentes')
G = obj.func(x1)
if(G.erro) return R.msg(G.valor)
f1 = G.valor-y
if(G.erro) return R.msg(G.valor)
G = obj.func(x2)
if(G.erro) return R.msg(G.valor)
f2 = G.valor-y
for(j=1;j<=NTRY;j++){
if(f1*f2 < 0.0) {R.x1=x1; R.x2=x2; return R}
if(Math.abs(f1)zbrac')
}// function zbrac
/* ********** FUNCTION INVERTE(obj,y,x1,x2,tol) ******************
Calcula a raiz da função obj.func(x)=y.
O objeto passado à função deverá ter o método func(x), que por
sua vez deverá retornar um objeto da classe "Resultado".
x1 e x2 são os limites inferior e superior do intervalo que
pode conter a raiz
A função "inverte" retorna um objeto da classe "Resultado". Esse objeto
possui a propriedade "valor" que contém o valor de x tal que
obj.func(x)=y
Pré-requisito:
* classe Resultado
* função zbrac
* função SIGN(a,b)
* variável global ITMAX=100
*/
function inverte(obj,y ,x1,x2,tol){
var R = new Resultado()
var iter,a,b,c,d,e,min1,min2,fa,fb,fc,p,q,r,s,tol1,xm,G
G = zbrac(obj,y,x1,x2,50)
if(G.erro)return R.msg(G.valor)
x1=G.x1
x2=G.x2
a=x1
b=x2
c=x2
G = obj.func(a)
if(G.error) return R.msg(G.valor)
fa= G.valor-y
G = obj.func(b)
if(G.error) return R.msg(valor)
fb= G.valor-y
if((fa>0.0 && fb>0.0) || (fa<0.0 && fb<0.0)) return R.msg('Não tem uma raiz nesse intervalo em inverte
')
fc = fb
for(iter=1;iter<=ITMAX;iter++){
if((fb>0.0 && fc>0.0) || (fb<0.0 && fc<0.0)){
c=a
fc=fa
d=b-a
e=d }// if fb e fc mesmo sinal
if(Math.abs(fc)= tol1 && Math.abs(fa)>Math.abs(fb)){
s = fb/fa
if(a==c){
p=2.0*xm*s
q=1.0-s}
else {
q=fa/fc
r=fb/fc
p=s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0))
q=(q-1.0)*(r-1.0)*(s-1.0)}// if (a==c) else
if(p>0.0) q=-q
p=Math.abs(p)
min1=3.0*xm+q-Math.abs(tol1*q)
min2=Math.abs(e*q)
if(2.0*p<(min1tol1) b+=d
else b+=SIGN(tol1,xm)
G = obj.func(b)
if(G.error) return R.msg(G.valor)
fb = G.valor-y
}// for iter
return R.msg('Excedeu o número de iterações em inverte
')
}// function inverte