/* Programa    raizes012.c
   Assunto:		Estudo das raizes de uma função definida no programa.
   
	Condicionantes:
	Programa sem erros
         
	Descrição:	Varre um intervalo com uma malha dada 
		procurando quando f troca 	de sinal.
		Leia uma expansão dos comentários ao final do programa.
	Palavras-chave:	troca de sinal, raiz, varredura             
	por Tarcisio Praciano Pereira - 10 lições para aprender C
	Sobral, Agosto de 2003   - UVA
*/
                  

#include <stdio.h>
#include <math.h>
#include "traducao.h"
#include "ambiente.h"

real	absol(real x);
real	f(real	x);
real	df(real	x);

inteira	principal()
{
	real	a=-5,b=5,delta=0.3; // (10) valores default (pre-definidos)
	real	epsilon; // (40) Valor será atribuido pelo programa ver (40)
	int	teste=1; // (50) caso não encontre raizes, teste=1
	imprima("Forneça-me o intervalo [a,b] para busca de raizes: \n");
	a = entrada_float("a = ", a);
	b = entrada_float("b = ", b);
	imprima("Forneça-me o passo  delta da malha para a  busca:\n");
	imprima("Sugestão  0.01 <  delta   <  0.5  \n");
	delta = entrada_float("delta  = ", delta);
	// (41) para me garantir contra o usuário...
	se (delta < 1) {epsilon = 0.1*delta;}
		senao { epsilon = 0.1;}	
	imprima("Sua busca de raízes no intervalo [%f , %f] \n ",a,b);	
	imprima("Precisão da malha: %f \n ", delta);		
	imprima("Erro  (módulo máximo): %f \n ", epsilon);	
	apeteco2();
	enquanto ( a <= b)
	{
		// imprima(" x = %f %f \n ", a, f(a));
		se ( (f(a)*f(a+delta)<=0)  )
			{
			teste = 0; // se tiver raiz
			imprima("Raíz provável por secância da função no intervalo \n");
			imprima("%s%f%s%f%s \n","[", a, ",", a+delta,"]");
			imprima("valor de f no ponto %f  é %f  \n",a,f(a));
			imprima("valor de f no ponto %f  é %f  \n",a+delta,f(a+delta));
			}
		senao 
			{
				// (40) troca de sinal da derivada e valor pequeno de f
				se ( (df(a)*df(a+delta)<=0) && (fabs(f(a)*f(a+delta) ) < epsilon)  )
				{
				teste = 0; // se tiver raiz
				imprima("Raíz provável por tangência da função no intervalo \n");
				imprima("%s%f%s%f%s \n","[", a, ",", a+delta,"]");
				imprima("valor de f no ponto %f  é %f  \n",a,f(a));
				imprima("valor de f no ponto %f  é %f  \n",a+delta,f(a+delta));				
				}
			}	
		a = a + delta; 	
	}
	se (teste)
		{
		// (50) Se não tiver achado raízes então teste = 1 - Verdadeiro
		imprima("Nenhuma raíz foi encontrada no intervalo dado !\n");
		imprima("Rode, novamente, o programa, com passo mais fino...\n");
		}
 	voltar(0);
}

// (60) escolha uma função ligando ou desligando - apagando o símbolo //
real	f(real	x)
{
	// voltar( (x+3)*(x+3)*(x-2)); 
	voltar(  (x-1)*(x-1)*( 1 + 7*(x+1)*(x+1) )    ); 
	// voltar(x*x);
	// voltar x;
}

// calcula derivada aproximada de uma função  f  
real	df(real x)
{
	real delta = 0.0001;	// variável local
	voltar( (f(x+delta) - f(x))/delta);
}

/*

(10) Este programa tem valores pre-definidos para todas as variáveis.
		Ao passar por uma entrada de dados, você pode dar "enter" para
		usar os valores pre-definidos. Esta é uma opção na primeira
		vez que rodar o programa 

(40)	Observe que num ponto de tangência o valor de f é uma
	ordem de grandeza menor do que a variação na malha (passo da
	malha). Neste caso use  epsilon = delta*delta

(41)	Se o usuário usar a norma da malha muito grande (um inteiro)
	eu vou garantir que a precisão no cálculo da raiz seja pequena.

(50) Em C, C++ e várias outras linguagens de programação o zero é
o Falso e qualquer coisa diferente de zero é verdadeiro. Porisso
definimos  teste = 1  no início do programa. Achando alguma raiz
teste = 0  o que evita que o programa diga, ao final, que não
acho nenhuma raiz.

(60) O símbolo //  transforma a linha em que ele se encontra, em um
	comentário, a partir do ponto em que ele estiver. Desta forma eu
	posso definir diversas equações para uma função, e 
	ligar uma em que eu esteja interessado  e 
	desligar as outras. 
	
	

*/

