DISSERTAÇÃO DE MESTRADO ALGORITMO DE SÍNTESE DE CIRCUITOS ANALÓGICOS TRANSLINEARES UTILIZANDO DECOMPOSIÇÃO NÃO-PARAMÉTRICA

Livre

0
0
157
8 months ago
Preview
Full text

  

DISSERTAđấO DE MESTRADO

ALGORITMO DE SÍNTESE DE CIRCUITOS ANALÓGICOS

TRANSLINEARES UTILIZANDO DECOMPOSIđấO

NÃO-PARAMÉTRICA

  

Diogo Andrade

Brasília, agosto de 2014

  

UNIVERSIDADE DE BRASÍLIA

FACULDADE DE TECNOLOGIA

  

UNIVERSIDADE DE BRASÍLIA

FACULDADE DE TECNOLOGIA

DEPARTAMENTO DE ENGENHARIA ELÉTRICA

  

ALGORITMO DE SÍNTESE DE CIRCUITOS ANALÓGICOS

TRANSLINEARES UTILIZANDO DECOMPOSIđấO NấO-

PARAMÉTRICA

DIOGO ANDRADE

  

ORIENTADOR: SANDRO AUGUSTO PAVLIK HADDAD

DISSERTAđấO DE MESTRADO EM ENGENHARIA ELÉTRICA

PUBLICAđấO: PPGEA.DM Ố 574/14 BRASÍLIA/DF: AGOSTO – 2014

  FICHA CATALOGRÁFICA ANDRADE, DIOGO Algoritmo de Síntese de Circuitos Analógicos Translineares Utilizando Decomposição Não- Paramétrica [Distrito Federal] 1999. xvii, 157p., 210 x 297 mm (ENE/FT/UnB, Mestre, Dissertação de Mestrado – Universidade de Brasília. Faculdade de Tecnologia.

  Departamento de Engenharia Elétrica

  1.Síntese de circuitos analógicos 2.Translinear

  

3.Síntese automática 4.Decomposição não-paramétrica

I. ENE/FT/UnB II. Título (série)

  REFERÊNCIA BIBLIOGRÁFICA ANDRADE, D. (2014). Algoritmo de Síntese de Circuitos Analógicos Translineares Utilizando Decomposição Não-Paramétrica. Dissertação de Mestrado em Engenharia Elétrica, Publicação PGEA.DM 574/14, Departamento de Engenharia Elétrica, Universidade de Brasília, Brasília, DF, 157p.

  CESSÃO DE DIREITOS AUTOR: Diogo Andrade.

  TÍTULO: Algoritmo de Síntese de Circuitos Analógicos Translineares Utilizando Decomposição Não-Paramétrica. GRAU: Mestre ANO: 2014 É concedida à Universidade de Brasília permissão para reproduzir cópias desta dissertação de mestrado e para emprestar ou vender tais cópias somente para propósitos acadêmicos e científicos. O autor reserva outros direitos de publicação e nenhuma parte dessa dissertação de mestrado pode ser reproduzida sem autorização por escrito do autor. ____________________________ Diogo Andrade

SQS 216, BL I, AP 402.

  70.295-090 Brasília – DF – Brasil.

  RESUMO

ALGORITMO DE SÍNTESE DE CIRCUITOS ANALÓGICOS TRANSLINEARES

UTILIZANDO DECOMPOSIđấO NấO-PARAMÉTRICA Autor: Diogo Andrade Orientador: Sandro Augusto Pavlik Haddad Programa de Pós-graduação em Engenharia de Sistemas Eletrônicos e Automação Brasília, agosto de 2014

Neste trabalho, foi desenvolvido um algoritmo de síntese de circuitos translineares, útil

para converter polinômios multivariável adimensionais, incluindo equações diferenciais

lineares e não-lineares, em um ou mais polinômios translineares implementáveis em

circuitos translineares. Circuitos translineares podem ser utilizados para realizar

processamento de sinais inteiramente no domínio analógico e em modo-corrente,

dispensando conversão analógica-digital, permitindo o desenvolvimento de circuitos de

Este algoritmo e outro encontrado na literatura são implementados em uma ferramenta

computacional, e são comparados em termos de eficácia e eficiência. O algoritmo

desenvolvido neste trabalho mostrou-se mais eficiente e mais eficaz que o outro em alguns

casos. O algoritmo também foi validado ao ser aplicado em polinômios utilizados em

circuitos translineares publicados, e as realizações utilizadas nestes trabalhos foram

encontradas pelo algoritmo.

  

A ferramenta computacional foi implementada utilizando linguagem  de  programação  “C”,  

e não depende de pacotes de software proprietários. Seu código fonte foi disponibilizado

gratuitamente  sob  a  licença  geral  pública  “GNU  v.3”

  ABSTRACT

ANALOG TRANSLINEAR CIRCUITS SYNTHESIS ALGORITHM USING

NON-PARAMETRIC DECOMPOSITION Author: Diogo Andrade Supervisor: Sandro Augusto Pavlik Haddad Programa de Pós-graduação em Engenharia de Sistemas Eletrônicos e Automação Brasília, august of 2014

In this work, a Translinear circuit synthesis algorithm, useful to convert a generic

dimensionless multivariate polynomial, including linear and non-linear differential

equations, into one or more translinear polynomials that can be realized onto a Translinear

Circuit was developed. Translinear circuits allow current-mode signal processing entirely

into the analog domain, dispensing analog-to-digital conversion, resulting in ultra-

low power and ultra low-voltage signal processing circuits.

  

This algorithm and another one found in the literature are implemented into a

computer tool, and they are both compared regarding their efficiency and

effectiveness. The developed algorithm was shown to be more effective and more efficient

than the other in some cases. The algorithm was also validated by being applied to

polynomials used in published Translinear circuits implementations, and the circuit

realizations found in those works were also found by this algorithm.

  

The    computer    tool    was    implemented    using    “C”    programming language, and it is

not dependent on any proprietary software package. Its source code is freely available

under the GNU General Public License v.3.

  Dedicatória Dedico este trabalho à Carmem, minha esposa, e a Raquel, minha filha.

  Diogo Andrade Agradecimentos

Muitas pessoas contribuíram, diretamente ou indiretamente, par a realização deste tra-

balho. Agradeço a cada uma delas! Neste momento, faz-se necessário reconhecer publica-

mente a participação específica de algumas.

Agradeço inicialmente ao professor Sandro Haddad, que além de ter sido um ótimo ori-

entador, mostrou-se um grande amigo que sempre esteve me motivando nas horas mais

difíceis, e que acreditou em mim quando nem eu acreditava mais. Tudo o que aprendi de

microeletrônica desde que nos conhecemos, devo a ele.

A todos os colegas do LDCI, que formam uma família unida. São grandes amigos que

me auxiliaram bastante neste trabalho, em especial a Heider Madureira e a José Edil

Medeiros.

À minha filha Raquel, que me fez querer desistir tantas vezes deste trabalho para me

dedicar exclusivamente ao cuidado dela, e à minha esposa Carmem por não ter deixado

isso acontecer com o seu apoio e amor incondicionais.

À minha grande família: meus pais e irmãos, e aos pais e irmãos da Carmem, que tam-

bém sempre estiveram muito disponíveis para me ajudar nos cuidados da Raquel durante

as horas de trabalho mais intensos, e também por me darem apoio e incentivo incondici-

onais.

A Deus por abençoar minha jornada pela vida e colocar pessoas espetaculares em meu

caminho.

  Diogo Andrade

  SUMÁRIO 1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  19

2.7.1 Circuito da função Módulo [27] ..................................................

  38

3.4 Novo Algoritmo de decomposição não-paramétrica .......................

  3.3.4 Divisão recursiva por pares de polinômios-base, versão otimizada para minimizar a memória utilizada .............................................

  36

  31

3.3.3 Verificação Final .....................................................................

  3.3.2 Divisão recursiva por pares de polinômios-base, versão otimizada para minimizar tempo de execução...............................................

  28

  26

3.3.1 Geração do vetor de Polinômios-Base .........................................

  25

3.3 Algoritmo de decomposição não-paramétrica original [23] .............

  25

3.2 Análise Combinatória de um Algoritmo Trivial ...........................

  

3 Algoritmos de Decomposição Translinear não-paramétrica . . . . . . . . 25

3.1 Introdução ..............................................................................

  24

  23

2.8.1 Algoritmo de Grafos de David Ilsen [25] ......................................

  21

2.8 Outras Metodologias de Síntese Translinear ..............................

  17

2.7 Exemplo de Síntese: Circuito RMS-DC [26] ...................................

  1

1.1 Contextualização .....................................................................

  15

2.6.1 Transformação de Variáveis Dinâmicas ........................................

  14

2.6 Princípio Translinear Dinâmico [38] ............................................

  12

2.5 Decomposição Translinear Paramétrica ......................................

  11

2.4.2 Transformação de Variáveis Estáticas .........................................

  10

2.4.1 Geração de Polinômios-Base ......................................................

  7

2.4 Decomposição Translinear não-paramétrica ................................

  5

2.3 Princípio Translinear Estático ...................................................

  5

2.2 Metodologia de síntese de circuitos translineares utilizada .........

  5

2.1 Introdução ..............................................................................

  4 2 Revisão Bibliográfica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  3

1.5 Apresentação do manuscrito ......................................................

  3

1.4 Metodologia ............................................................................

  2

1.3 Objetivos .................................................................................

  1

1.2 Definição do problema ..............................................................

  39

  

3.4.1 Geração do Vetor de Polinômios-Base ........................................

  

5 Resultados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

5.1 Introdução ..............................................................................

  75 I.2 arquivo “main.h” ........................................................................

  

I Código fonte do aplicativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

I.1 arquivo “main.c’ ........................................................................

  69 REFERÊNCIAS BIBLIOGRÁFICAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

Anexos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

  

6 Conclusões . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

6.1 Proposta de Trabalhos Futuros .................................................

  66

  65

5.3.4 Circuito de Seno.......................................................................

  64

5.3.3 Circuito da função Módulo .......................................................

  61

5.3.2 Conversor RMS-DC ...................................................................

  61

5.3.1 Oscilador de segunda ordem ......................................................

  59

5.3 Aplicação do algoritmo desenvolvido em trabalhos publicados .....

  59

5.2 Comparativo de esforço computacional entre algoritmos .............

  58

  42

  57

4.4.2 Realizações de circuitos Translineares publicados .......................

  57

4.4.1 Polinômios aleatórios ...............................................................

  56

4.4 Polinômios utilizados para testar o algoritmo.............................

  4.3.1 Geração de vetores de polinômios extremamente reduzidos e nova medida de eficiência ..................................................................

  56

  55

4.3 Medida de Eficiência entre algoritmos .......................................

  55

4.2 Eficácia do algoritmo implementado ...........................................

  

4 Procedimento de validação e comparação entre algoritmos . . . . . . . . 55

4.1 Introdução ..............................................................................

  52

  48

3.5 Eliminação de polinômios translineares redundantes ....................

  

3.4.2 Divisão Recursiva por Pares de Polinômios-Base e verificação final

  80

  LISTA DE FIGURAS

  

1.1 Comparação entre consumo de potência por pólo entre filtros analógicos e digitais [15] 2

  

2.1 Fluxo do método de síntese de decomposição translinear. .................................... 6

  

2.2 Malha Translinear de 4 transistores................................................................. 7

  

2.3 Malha Translinear de 4 diodos com seguidores de tensão ..................................... 9

  

2.4 Princípio Translinear Dinâmico [38] ................................................................ 15

  

2.5 Arranjos distintos de correntes de capacitor. [38] ............................................... 16

  

2.6 Diagrama de blocos de um conversor RMS-DC [26] ............................................ 19

  

2.7 Malha translinear dinâmica RMS-DC [26] ........................................................ 19

  

2.8 Circuito RMS-DC [26]. ................................................................................ 20

  

2.9 Circuito retificador de onda completa. ............................................................. 22

  

2.10 Topologias de circuitos translineares contendo até seis transistores [25]................... 24

  3.2 Estrutura de topo da implementação do algoritmo original de decomposição não- paramétrica [23] .......................................................................................... 28

  

3.3 Obtenção de Polinômios-Base (PB’s) estritamente positivos (vetor ) ................... 29

  1

  

3.4 Divisão por um Polinômio-Base (PB) e fatoração do Resto (vetor ...................... 30

  2

  3.5 Divisão por pares de Polinômios-base e execução de decomposições parciais e Veri- ficação final, versão otimizada para tempo de execução. ...................................... 33

  

3.6 Sub-rotina de geração da lista de decomposições parciais ↵ x,n ............................... 35

  3.7 Divisão por pares de Polinômios-base e execução de decomposições primárias, versão otimizada para minimizar a memória utilizada. ................................................. 39

  

3.8 Sub-rotina de geração de decomposições primarias .......................................... 40

x

  

3.9 Sub-rotina de geração de decomposições secundarias y . ...................................... 41

  

3.10 Estrutura do novo algoritmo de decomposição não-paramétrica ............................ 42

  

3.11 Geração do Vetor de Polinômios-Base.............................................................. 42

  

3.12 Algoritmo de eliminação de polinômios-base estritamente negativos (vetor⌧ ). ......... 43

  1

  

3.13 Algoritmo de eliminação de polinômios-base (PB) redundantes(vetor ⌧ ). ............... 45

  2

  

3.14 Algoritmo de geração do vetor ⌧ de pares de polinômios-base (PB)....................... 47

  3

  

3.15 Algoritmo de geração do vetor ⌧ de polinômios-base (PB)................................... 50

  4

  

3.16 Divisão Recursiva por Pares de Polinômios Simultâneos. ..................................... 53

  

3.17 Eliminação de polinômios translineares redundantes ........................................... 54

  

4.1 Geração do vetor de polinômios-base extremamente reduzido ⌧ ............................ 57

  5

  

5.1 Circuito oscilador de segunda ordem [49].......................................................... 62

  

5.2 Circuito Seno compacto ................................................................................ 67

  

5.3 Saída do circuito Seno e seu valor ideal............................................................ 67

  LISTA DE TABELAS

  

2.1 Exemplo de geração de polinômios-base ........................................................... 12

  2.2 Número de topologias de circuitos translineares para um dado número de transistores [25] .......................................................................................................... 24

  

3.1 Exemplo de eliminação de Polinômis-Base estritamente negativos.......................... 44

  

3.2 Exemplo de vetor ⌧ .................................................................................... 47

  2

  

3.3 Vetor ⌧ gerado a partir de vetor ⌧ reduzido .................................................... 49

  3

  2

  

3.4 Vetor reduzido ⌧ ....................................................................................... 51

  3

  

4.1 Vetor de Polinômios de Entrada para avaliação dos algoritmos ............................. 58

  

5.1 Comparativo de eficiência computacional entre algoritmos com coeficientes [−1, . . . , +1]. 60

  

5.2 Comparativo de eficiência computacional entre algoritmos com coeficientes [−3, . . . , +3] 61

  5.3 Comparativo de eficiência computacional entre algoritmos com coeficientes [−3, . . . , +3] e vetores de polinômios-base extremamente reduzidos ......................................... 62

  LISTA DE SÍMBOLOS Símbolos Latinos

  [m] L Comprimento do canal do transistor MOS [m] q Carga do elétron

  1 /s] ⌘ x fator de escala do transistor “x” adimensional x combinação de vários fatores de escala de transistores adimensional

  2 ]

µ mobilidade de portadores de carga [V

  2 /C

  [V] ✏

S Permissividade dietética do semicondutor [Nm

  F Tensão de banda

  [C] Símbolos Gregos

  3 ] W Largura de um transistor MOS

  GHz Giga-Hertz [10

  I S Corrente de saturação [A] N A concentração de átomos receptores de elétrons [m

  V T Tensão Térmica [V]

  V SB Tensão Source-Bulk [V]

  V GS Tensão Gate-Source [V]

  V BE Tensão Base-Emissor [V]

  1 ]

  9 s

  Sobrescritos · Variação temporal

  Siglas A/D Analógico-Digital BiCMOS Bipolar-CMOS BJT Bipolar Junction Transistor

CMOS Complementary Metal-Oxide-Semiconductor

DC Direct Current DTL Dynamic Translinear DR Dynamic Range ECG Eletrocardiograma EMG Eletromiografia

FGMOS Floating Gate Metal-Oxide-Semiconductor

FPAA

  

Field Programmable Analog Array GB Giga Byte GNU GNU is Not Unix GPL General Public License LC Indutor-Capacitor LPF Low-Pass Filter LTK Lei das Tensões de Kirchoff MB Mega Byte MOS Metal-Oxide- Semiconductor PB Polinômio-Base PTAT Proportional To Absolute Temperature RAM Random Access Memory RFID Radio Frequency Identification RMS root mean square SAH Sentido Anti-Horário SH Sentido Horário SNR Signal to Noise Ratio STL Static Translinear Capítulo 1 Introdução

1.1 Contextualização

  Um grande desafio no desenvolvimento de circuitos integrados para dispositivos embarcados é

o consumo de potência. Estes dispositivos, de natureza portátil, são alimentados por baterias, ou

por sistemas de coleta de energia do ambiente [1,2], ou por transmissão de potência sem fio [3–10],

ou por uma combinação destas tecnologias. No caso de dispositivos embarcados implantados em

seres vivos, um baixo consumo de potência talvez seja a restrição de projeto mais relevante, pois

uma troca de bateria implica em um procedimento cirúrgico, o que traz riscos de infecções e custos

elevados para a manutenção destes dispositivos.

  A maioria dos dispositivos implantados realizam aquisição de sinais vitais, que pode ser acom-

panhada de processamento destes sinais no próprio dispositivo [11–14]. O paradigma de aquisição

mais utilizado nestes dispositivos é o da amplificação e discretização do sinal analógico medido

utilizando um conversor Analógico-Digital(A/D). Entretanto, o consumo de potência relacionado

à amplificação e conversão A/D pode ser relativamente elevado, tornando necessária a utilização

de tecnologias mais sofisticadas de fornecimento de potência.

  Um paradigma alternativo de aquisição e processamento de sinais analógicos é o dos filtros

  1

translineares . Esta classe de filtros é utilizada para fazer processamento de sinais inteiramente

no domínio analógico e em modo-corrente. Em [15], foi realizado um estudo comparativo entre

o consumo de potência utilizando filtros digitais e filtros analógicos translineares, levando-se em

consideração o consumo de potência da conversão A/D. Neste estudo, considerou-se o consumo

de potência de conversores A/D no estado da arte, bem como o de um conversor A/D ideal. Foi

constatado que, para uma boa precisão no processamento de sinais (faixa dinâmica de 90 dB), a

razão entre o consumo de potência em um filtro translinear e em um filtro digital com conversão

7 A/D ideal pode chegar a 10 , conforme visto na Fig. 1.1, onde a curva “A/D P min ” mostra o limite teórico mínimo de consumo de potência por pólo em um conversor A/D.

  Um nível tão baixo de consumo de potência permite o desenvolvimento de dispositivos implan-

  1 também chamados log-domain

  

tados que possam funcionar com uma única bateria durante toda a expectativa de vida de um

indivíduo. Assim, o processamento de sinais analógicos por meio de circuitos translineares tem

uma aplicação muito relevante em sistemas embarcados e em sistemas biomédicos implantados.

Combinando este paradigma de processamento de sinais com tecnologias de coleta de energia do

ambiente, como em [1, 2], abrem-se inúmeras possibilidades de novos circuitos em que o uso de

baterias ou de tecnologias de transmissão de potência sem fio sejam dispensáveis.

  

Figura 1.1: Comparação entre consumo de potência por pólo entre filtros analógicos e digitais [15]

Os circuitos translineares não tem sua aplicabilidade limitada à realização de filtros. Podem ser

utilizados para realizar um processamento de sinal avançado, incluindo qualquer função matemática

  2

descrita por um polinômio, como funções estáticas e equações diferenciais lineares e não-lineares.

  

Como estes circuitos operam em modo corrente, a tensão de alimentação do circuito deixa de ser

um fator limitante [16], possibilitando assim, circuitos processadores de sinais de baixíssima tensão

e baixíssimo consumo de potência, como nos trabalhos [17–21].

1.2 Definição do problema

  Partindo do fato de que circuitos translineares podem ser utilizados para construir circuitos

de baixíssimo consumo de potência, há o problema de complexidade do processo de síntese destes

circuitos. Como será visto no capítulo 2, existem várias metodologias na literatura, e as mais

sistematizadas tendem a utilizar blocos fundamentais na construção dos circuitos, o que tende a

torná-los super-dimensionados. Dentre as metodologias a serem apresentadas, a metodologia que

  2 instantâneas no tempo

  

utiliza o processo de “decomposição não-paramétrica” é a que produz os circuitos mais compactos,

ou seja, com o mínimo de transistores e capacitores possível. Entretanto, este processo depende

muito da “criatividade algébrica” do projetista para encontrar uma realização de circuito [22].

Assim, existe um “trade-off” entre a facilidade de sintetizar um circuito translinear e o tamanho

do circuito gerado pelo método escolhido.

  Em [23] um algoritmo de decomposição translinear não-paramétrica automatizada foi publi-

cado, e representou a primeira metodologia de síntese automática de circuitos translineares desen-

volvida, mas sua implementação não foi encontrada nas bases de dados pesquisadas. Em [24], o

autor afirma que implementou este algoritmo, mas sua implementação também não foi encontrada.

Já em [25], o autor propõe um algoritmo diferente, baseado em bancos de malhas translineares e

classificação de padrões utilizando teoria dos grafos, mas não utiliza o processo de decomposição

não-paramétrica, e utiliza pacotes de software de alto custo em sua implementação. Assim, não se

  3

encontra ainda uma implementação auto-contida de um processo de decomposição paramétrica

automatizado disponibilizada publicamente, e tampouco alguma análise e proposta de melhoria

em relação ao algoritmo apresentado em [23].

  Define-se assim o problema a ser resolvido neste trabalho como ausência de uma ferramenta

computacional gratuita e auto-contida que implemente um algoritmo de decomposição translinear

não-paramétrica automatizada. Este é um problema que se encontra na fronteira entre a teoria de

circuitos translineares, as teorias de álgebra combinatória, e ciências da computação.

  1.3 Objetivos Este trabalho tem como objetivos analisar e implementar o algoritmo de decomposição transli-

near não-paramétrica descrito em [23], e apresentar mudanças a este algoritmo que o tornam mais

eficaz, com a finalidade de produzir mais resultados, e mais eficiente, com a finalidade de reduzir o

tempo de computação necessário para encontrar todas os resultados possíveis. Esta implementação

deverá ser auto-contida, ou seja, não dependerá do uso de pacotes de software proprietários.

  Outro objetivo é publicar o código-fonte da Implementação resultante, tornando-a software livre, como uma forma de se estimular o desenvolvimento de circuitos translineares.

  1.4 Metodologia Este trabalho iniciou-se com o estudo dos princípios translineares estático e dinâmico, e em

seguida foi realizada uma pesquisa a respeito de metodologias de síntese destes circuitos. Os

documentos pesquisados foram: livros-texto, artigos e periódicos científicos relacionados a circuitos

e sistemas. Sítios eletrônicos na internet foram utilizados de forma complementar.

  Escolheu-se o algoritmo de decomposição não-paramétrica de [23], por ser uma metodologia

de síntese automática, para realizar um estudo mais profundo, e assim foi formulado um novo

  3 não depende de pacotes de software proprietários

  

algoritmo. Para validar e comparar os dois algoritmos, ambos foram implementados em linguagem

de programação “C”. Esta linguagem foi escolhida porque o autor do algoritmo de [23] afirma que

implementou o seu algoritmo nesta linguagem, e decidiu-se seguir a mesma metodologia.

  Definiu-se, então uma metodologia de validação e comparação dos algoritmos. Executou-se esta metodologia e os resultados foram colhidos e analisados.

1.5 Apresentação do manuscrito

  No capítulo 2 é feita uma revisão bibliográfica sobre princípio translinear, e a descrição da

metodologia de síntese de circuitos translineares que utiliza o processo de decomposição translinear.

No 3, três algoritmos de decomposição translinear não paramétrica são mostrados: Um algoritmo

trivial, o algoritmo original de [23], e o novo algoritmo desenvolvido neste trabalho. A metodologia

para se comparar os algoritmos é descrita no capítulo 4, e os resultados da comparação e validação

são descritos no capítulo 5. No capítulo 6, são apresentadas as conclusões e são propostos trabalhos

futuros a respeito do tema de decomposição translinear não-paramétrica automatizada. O Anexo

contém o código-fonte da ferramenta que implementa tanto o novo algoritmo quanto o algoritmo original. Capítulo 2 Revisão Bibliográfica

  2.1 Introdução Neste capítulo, é apresentada a metodologia de síntese de circuitos translineares utilizada neste

trabalho: decomposição translinear. Em seguida são apresentados os conceitos necessários para

a aplicação do método: o princípio transliner estático, o conceito de decomposição translinear

paramétrica e não-paramétrica, e o princípio translinear dinâmico. Como exemplo, a síntese de

um circuito RMS-DC [26] e de um circuito da função módulo [27] são mostradas. Em seguida,

um algoritmo de decomposição não-paramétrica trivial é mostrado como justificativa para que se

desenvolva algoritmos mais eficientes. O algoritmo de decomposição não-paramétrica de [23], que

é a referência para o algoritmo desenvolvido neste trabalho, é apresentado, e finalmente, outras

metodologias de síntese são brevemente apresentadas.

  A metodologia de síntese de decomposição translinear utilizada neste trabalho é uma extensão

das apresentadas em [23,27]. Nestes trabalhos a parte de implementação em hardware dos circuitos

e métodos de representação em espaço de estados de filtros transllineares são abordados com

detalhes, enquanto que neste trabalho, apenas conceitos básicos de transformação de equações

diferenciais são apresentados, e os detalhes a respeito de implementação em hardware não são

apresentados. A pesquisa realizada não encontrou publicações recentes a respeito de detalhes de

implementação de hardware. Entretanto, as metodologias de representação de filtros translineares

são bem detalhadas em [15].

  A metodologia de análise de circuitos Translineares fica implícita dentro do método de síntese apresentado. Metodologias de análise detalhadas podem ser encontradas em [23, 27, 28].

  2.2 Metodologia de síntese de circuitos translineares utilizada O método de decomposição translinear consiste em encontrar uma topologia de circuito ana-

lógico que realize um processamento de sinal contínuo no tempo dado por uma equação algébrica

adimensional, que por sua vez pode ser uma equação diferencial linear ou não-linear. O fluxo deste método pode ser visto na Fig. 2.1:

Figura 2.1: Fluxo do método de síntese de decomposição translinear: (a): circuitos estáticos, (b)

circuitos dinâmicos, adaptado de [23]

  Um ponto importante da metodologia apresentada é que, após ter sido obtido um polinômio

modo-corrente, a trajetória da síntese é igual para polinômios estáticos e para equações diferen-

ciais. Uma diferença significativa é que, no método de síntese de circuitos dinâmicos, pode ser

que as correntes de capacitores definidas não sejam compatíveis com os polinômios translineares

encontrados, fazendo com que o projetista tenha que voltar ao passo inicial.

  Exceto pela etapa de realização do circuito, que está fora do escopo deste trabalho, todas as

outras são descritas nas seções a seguir. A etapa de decomposição translinear pode ser realizada

por decomposição paramétrica ou não-paramétrica. O algoritmo de decomposição não paramétrica

de [23] é descrito com detalhes na seção 3.3, já da forma que foi implementada na ferramenta

  

desenvolvida neste trabalho, pois o autor especificou apenas o algoritmo abstrato, sem qualquer

estratégia de implementação.

  Este método é divergente, pois várias escolhas diferentes podem ser feitas no caminho, e múl-

tiplas soluções para se implementar o mesmo polinômio de entrada podem ser alcançadas, e elas

vão ter desempenho diferente quanto a: razão sinal ruído (SNR), faixa dinâmica (DR), tensão de

alimentação mínima, consumo de energia, largura de banda, sensibilidade a parâmetros de com-

ponentes, distorção harmônica, etc. Este tipo de análise está fora do escopo deste trabalho, ou

seja, a busca por uma realização de circuito translinear de alto desempenho deve ser feita de forma

subjetiva dentre as decomposições não-paramétricas encontradas pela ferramenta.

2.3 Princípio Translinear Estático

  O princípio Translinear Estático (STL —Static Translinear) foi proposto por Gilbert em 1975

[29]. Considerando um transistor bipolar de junção (BJT) como o dispositivo de referência para

esta definição, este princípio pode ser enunciado da seguinte forma:

Princípio STL: Dada uma malha que passa pelas junções base-emissor de um conjunto de tran-

sistores com a mesma tensão térmica V , e a mesma corrente de saturação I , sendo que o número

  T S

de transistores com a junção base-emissor no sentido horário (SH) da malha é igual ao número de

transistores com suas junções no sentido anti-horário (SAH), o produto das correntes de coletor

dos transistores com suas junções base-emissor no sentido horário é igual ao produto das correntes

dos transistores com suas junções base-emissor no sentido anti-horário. A esta malha dá-se o nome

  1 de “malha translinear”.

  

Figura 2.2: Malha Translinear de 4 transistores

A Fig. 2.2 mostra uma malha translinear de quatro transistores. Aplicando a lei das tensões

de Kirchoff (LTK) à esta malha translinear, a relação entre as tensões base-emissor é dada pela

1 Esta é a versão do autor baseada em outras formulações do princípio STL encontradas na literatura [27, 30–32]

  Eq. (2.1) (2.1)

  BE + V BE BE + V BE = 0 −V

  1

2 − V

  3

  4 Considerando a equação do BJT ideal dado pela Eq. (2.2), onde ⌘ é o fator de escala do BJT, x é a tensão térmica, I a corrente de saturação do transistor, e V é a tensão base-emissor

  V T S BEx

do transistor por onde flui a corrente de coletor I x , pode-se Isolar V BEx na Eq. (2.2) e obtém-se

a sua expressão dada pela Eq. (2.3). Substituindo-o na Eq. (2.1), obtém-se uma nova expressão,

dada pela Eq. (2.4)

  VBEx

  VT I x = ⌘ x I s e (2.2) ◆

  ✓ I x

  V BEx = V T ln (2.3) ⌘ x

  I S ◆ ◆ ◆ ◆ ✓ I ✓ I ✓ I ✓ I

  1

  2

  3

  4 V T ln T ln + V T ln T ln = 0 (2.4) − V − V ⌘

  I ⌘

I ⌘

I ⌘

  I

  1 S

  2 S

  3 S

  4 S

  2 Assumindo que os transistores operam à mesma temperatura e que são iguais , pode-se eliminar

  

I S e V T da Eq. (2.4), o que possibilita eliminar o logaritmo da equação, e o resultado é mostrado

na Eq. (??).

  ◆ ◆ ◆ ◆

✓ I ✓ I ✓ I ✓ I

  1

  3

  2

  4 V T ln + V T ln = V T ln + V T ln ⌘

  I S ⌘

  I S ⌘

  I S ⌘

  I S

  1

  3

  2

  4 ◆ ◆ ✓ I ✓ I

  3

  4 ln = ln

⌘ ⌘ ⌘ ⌘

1 I

  2 I

  1

  3

  2

  4 I

  I I

  I

  1

  3

  2

  4

=

⌘ ⌘ ⌘ ⌘

  1

  3

  2

  4 SAH

  I I SH

  I I = 0 (2.5)

  1

3 −

  2

  4 Assim, uma malha translinear em um circuito implementa uma diferença de produtos de correntes,

e esta relação pode ser generalizada na Eq. (2.6). Onde os fatores de escala ⌘ de cada produto

x

são combinados nas constantes SAH e SH , referentes aos transistores conectados no sentido anti-

horário e sentido horário respectivamente. Uma característica relevante do circuito translinear

estático, é que o seu comportamento dado pela Eq. (2.5) é invariante com a temperatura, pois os

  

3

termos V são iguais para todos os transistores. . T

Y Y

SAH

  

I j SH

I j = 0 (2.6)

j

2 SAH j

  2 SH

O princípio é válido não apenas para o BJT, mas também para qualquer dispositivo que apresente

uma relação I−V exponencial, como o transistor MOS em inversão fraca [33], diodos com seguidores

de tensão [34, 35], BJT lateral do transistor MOS [36], e transistores MOS com gate flutuante

(FGMOS) também em inversão fraca [37]. Como exemplo, mostra-se o transistor MOS e os diodos

com seguidores de tensão.

  2 Assume-se que os dispositivos possuem o mesmo modelo de grandes sinais e são bem-casados.

  3 Para maior clareza no desenvolvimento deste trabalho, as correntes I j , j ∈ SH serão denominadas “correntes

conectadas no SH”, enquanto que as correntes I j , j ∈ SAH serão denominadas “correntes conectadas no SAH”. Um

par de correntes em que uma é conectada no sentido SH e a outra no sentido SAH serão chamadas de “correntes

opostamente conectadas”.

  O transistor MOS em inversão fraca tem a corrente de dreno I dada pela Eq. (2.7), e sua DS

corrente de saturação, dada pela Eq.(2.8), depende apenas da tensão entre a fonte e o corpo V ,

  SB sendo os outros parâmetros constantes dadas pelo processo de fabricação [33].

  VGS −V DS W nVT nVT

  I DS =

  I M (V SB )e ) (2.7) (1 − e L √

  

−V

M 2q✏ N

  S A

  2 nVT

  I M (V SB ) = µV e (2.8)

  T √

  2

  2 F + V SB

Se V SB é igual para todos os transistores, então I M (V SB ) = I é uma constante, se V GS é menor

M

que a tensão limiar de entrada na região de inversão moderada V , e se V , o que faz o

  M DS T ≥ 3V

termo entre parênteses da Eq. (2.7) seja aproximadamente 1, então a Eq. (2.7) pode ser rescrita

na Eq. (2.9), que tem o mesmo formato da Eq. (2.2), que modela o BJT ideal:

  VGS

W

nVT

  I DS = I e (2.9) M

L

  

Assim, tomando os devidos cuidados, os transistores MOS podem ser utilizados em realizações de

circuitos translineares. Entretanto, para manter o transistor MOS em inversão fraca para corren-

tes mais altas, da ordem de µA, as dimensões dos transistores ficam muito grandes, o que limita

severamente a operabilidade em altas frequências devido às capacitâncias parasitas tomarem pro-

porções significativas. Entretanto, há uma vantagem em se utilizar transistores MOS: tecnologias

que implementam CMOS exclusivamente são baratas, bem como as que implementam exclusiva-

mente BJT, mas a tecnologia BiCMOS, que implementam ambos, são mais caras. Como o uso

de CMOS para circuitos digitais é mais econômico que o uso da tecnologia de BJT em termos de

consumo de energia, a tecnologia CMOS é mais adequada para circuitos de sinais mistos.

  Uma alternativa para operar em altas frequências com correntes mais altas, é utilizar diodos

passivos como dispositivo translinear e transistores MOS para construir amplificadores operacionais

configurados como seguidores de tensão. Assim, pode-se ter tensões iguais nos terminais p dos

diodos por meio do curto-circuito virtual, enquanto correntes distintas fluem em cada diodo. A

Figura 2.3 mostra um exemplo deste arranjo.

  

Figura 2.3: Malha Translinear de 4 diodos com seguidores de tensão

Para uma correta operação de um circuito translinear, os dispositivos devem ser devidamente

polarizados de modo que o comportamento exponencial seja mantido, e as devidas correntes devem

  

ser forçadas nos dispositivos apropriados para que as correntes resultantes desejadas sejam geradas.

Um exemplo de polarização de um circuito translinear será mostrado mais adiante no Capítulo 5

Este princípio translinear é chamado estático porque não são levados em consideração com-

portamentos transientes do circuito em sua formulação. Neste princípio, apenas o comportamento

estático, ou seja o comportamento DC do circuito, é modelado.

  O estudo a respeito de efeitos de segunda-ordem como distorção, ruído, etc. estão fora do

escopo deste trabalho, pois estes efeitos são específicos da tecnologia utilizada para implementar o

circuito desejado.

2.4 Decomposição Translinear não-paramétrica

  A forma da Eq. (2.6) permite utilizar circuitos translineares para processamento de sinais

modo-corrente no domínio analógico. Como as correntes de coletor I podem ser forçadas, elas

j

podem ser formadas por combinações lineares de diferentes correntes. Como exemplo, considerando

o circuito da Fig. 2.2, se I = I = I a , I = I y + I b , I = I y b , e SH = SAH = 1, tem-se um

  1

  3

  2 4 − I circuito translinear dado pela Eq. (2.10).

  (I )(I + I )(I ) = 0 (2.10) a a y b y b

  

) − (I − I

Desenvolvendo a Eq. (2.10), encontra-se a expressão da média geométrica, dada pela Eq. (2.11):

  2

  2

  2 I + I ) = 0 a − (I y b

  2

  2

  2 I = I + I y b a q

  

2

  2 I y = I + I (2.11) a

b

  

Assim, pode-se implementar, com um circuito simples, o cálculo da média geométrica entre dois

sinais sem utilizar conversão A/D e sem ter que utilizar um microprocessador. Esta é a grande

vantagem de se utilizar circuitos translineares para processamento de sinais: Realizar um pro-

cessamento de sinal avançado no domínio analógico, com baixas tensões e baixas correntes, e

consequentemente, com baixo consumo de energia.

  No entanto, encontrar uma realização translinear para um dado polinômio de entrada não é

uma tarefa trivial. Ainda que encontrar a Eq. (2.10) a partir da Eq. (2.11) possa não parecer

tão difícil, encontrar uma realização de um polinômio mais complexo, com mutilas variáveis e de

  4

grau elevado exigiria um certo nível de “criatividade algébrica”. Nas palavras de Frey e Drakkis :

“O princípio translinear estático sugere uma implementação de circuito se um único produto de

correntes do lado esquerdo [da equação] for igual a outro único produto de correntes no lado direito

[da equação]. Isto pode ser realizado com um algumas operações de rearranjo e fatoração baseados

na etapa de síntese chamada de ‘decomposição translinear’. Encontrar o rearranjo apropriado é

limitado pelo nível de criatividade e experiência que dão o devido valor a este método. Entretanto,

alguns podem considerar este processo como um desafio..” [22]. Assim, define-se o processo de

  4 tradução do autor

  

decomposição translinear não-paramétrica como a reescrita de um dado polinômio modo-corrente

em uma diferença de produtos, na forma da Eq. (2.6). É chamada não-paramétrica pois pro-

cura rescrever um polinômio de entrada em uma única malha translinear, sem introduzir novos

parâmetros. O processo de decomposição paramétrica é descrito na seção 2.5.

  O processo de decomposição translinear não-paramétrica é puramente algébrico. O objetivo

é tentar combinar, de alguma forma, polinômios-base de forma a obter uma representação do

polinômio de entrada na forma da Eq. (2.6). A essa representação dá-se o nome de “polinômio

translinear”. Como é simples, por meio de espelhos de correntes, somar e subtrair as correntes

que serão forçadas no coletor de um transistor qualquer da malha translinear, esta corrente de

coletor é representada no domínio algébrico por um polinômio-base, que é uma combinação linear

das variáveis que compõe o polinômio de entrada E r , r sendo o grau do polinômio. Chamando

os polinômio-base de P x , uma polinômio translinear pode ser escrito na forma da Eq. (2.12).

Pode-se notar que, devido ao número de termos de cada produto da Eq. (2.12) conter um número

de polinômios lineares igual ao grau do polinômio de entrada E r , este deverá ser homogêneo, ou

seja, todos so monômios resultantes de sua expansão deverão ser de grau r. Caso E r não seja

homogêneo, uma transformação de variáveis adequada deverá ser feita, conforme será mostrado

  5 nas seções 2.4.2 e 2.6.1 .

  P P . . . P P P . . . P (2.12)

  1

  1 3 2r 1 −

  2

  2 4 2r

2.4.1 Geração de Polinômios-Base

  Conforme visto na seção anterior, um polinômio-base é uma combinação linear das variáveis

que compõe o polinômio de entrada E r , sendo r o grau do polinômio. Para se desenvolver um

algoritmo de decomposição não-paramétrica qualquer, é necessário primeiramente gerar um vetor

de polinômios-base, a partir dos quais o algoritmo tentará encontrar os possíveis polinômios trans-

lineares. Para gerar este vetor, deve-se escolher um intervalo de coeficientes que serão combinados

com as variáveis. O número de polinômios-base é função do número de variáveis v e do intervalo

de coeficientes [−N, . . . , +N] utilizados. Como o número zero faz parte do intervalo, o número

de coeficientes é dado por (2N + 1). Considerando que cada variável deve ser multiplicada por

algum coeficiente numérico arbitrário, o numero total de polinômios-base N é uma permutação

  β

com repetição, de (2N + 1) tomados v a v, dado ela Eq (2.13). Por exemplo, considerando um

polinômio de duas variáveis (chamadas aqui de x e y), e coeficientes inteiros entre [−1, . . . , +1], ou

seja, N = 1, independentemente do grau deste polinômio, os seus polinômios-base são mostrados

na Tabela 2.1. v

  N = (2N + 1) (2.13) β

  5

  1

  1

  3

  2 Para tornar o desenvolvimento nas seções seguintes mais claro, o produto λ P P . . . P , por ter os índices r−1

  1

  3

  2

ímpares, será denominado “lado ímpar”, e os polinômios-base P , P , . . . , P serão denominados “polinômios

r−1

  2

  2

  4

  2

  2

  4 P P . . . P r

ímpares”. De forma análoga, o produto λ , será denominado “lado par”, e os polinômios-base P , P ,

  2 . . . r , P serão denominados “polinômios pares”, sendo que o lado ímpar e o lado par serão chamados de “lados

opostos”. O termo “polinômios opostos” se refere a um par de polinômios em que um é um polinômio ímpar e o

  1

  2 outro é um polinômio par. Por exemplo, P e P pertencentes à Eq. (2.12) são polinômios opostos.

  

Tabela 2.1: Exemplo de geração de polinômios-base

x y PB

−1 −1 (−x − y)

−1 (−x)

  1 −1 (−x + y) −1

  (−y) 1 (y) 1 −1

  (x − y)

1 (x)

1 1 (x + y)

  2 Colocando os valores de v = 2 e N = 1 na fórmula da Eq. (2.13), N = 9, β = (2 ∗ 1 + 1)

exatamente o número de polinômios-base da Tabela 2.1. A este conjunto completo de polinômios-

base dá-se o nome de , e será referenciado nos algoritmos de decomposição translinear não-

paramétrica descritos neste trabalho.

  Os coeficientes das variáveis no domínio algébrico representam espelhos de corrente na imple-

mentação do circuito, então apenas coeficientes inteiros ou fracionários podem ser utilizados, para

que se possa obter cópias precisas das correntes. É importante ressaltar que, sempre existirá um

polinômio translinear de E r , bastando que, para isso, possa-se utilizar todos os números fracioná-

rios, ou seja, todos os números do conjunto-universo Q como possíveis coeficientes das variáveis

nos polinômios-base. No entanto, se este intervalo fosse utilizado, o número de combinações pos-

síveis, até mesmo para um algoritmo eficiente, seria infinito, logo a escolha destes coeficientes não

seria prática. Assim, escolhe-se apenas coeficientes inteiros, e geralmente com N < 10. Sendo

os coeficientes limitados, as soluções são finitas, logo é possível implementar um algoritmo para

encontrá-las.

2.4.2 Transformação de Variáveis Estáticas

  Para que um polinômio de grau r seja realizável em uma malha translinear conforme mostrado

na seção 2.4, ele deve ser modo-corrente, ou seja, todas as suas variáveis devem descrever correntes

elétricas em um circuito. Se deseja-se obter um polinômio translinear a partir de um polinômio

adimensional, primeiro é necessário transformar suas variáveis adimensionais, que são função de

uma variável implícita adimensional ⌧ em variáveis de correntes no tempo. Entretanto, isso deve

ser feito sem alterar o “comportamento” do polinômio, ou seja, as transformações devem man-

ter a admiensionalidade da variável a ser transformada. Para isso, ao transformar uma variável

adimensional em uma variável de corrente, introduzem-se novas correntes de referência do tipo

I (t):

  0x I x (t) x(⌧ ) =

  (2.14) I (t) 0x

  

Assim, na transformação da variável x(⌧ ) em I (t), os dois lados da Eq. (2.14) são mantidos

x

adimensionais, mas agora é a corrente I x (t) que carrega a informação da variável x(⌧ ), e a variável

introduzida I (t) vai definir, de alguma forma os limites da excursão de sinal de I x (t). Como

  0x

exemplo, faz-se a transformação de variáveis do polinômio que representa a aproximação da função

sen(⇡x) [29], omitindo (⌧ ) e (t) para melhor legibilidade:

  3 sen(⇡x) x − x

  (2.15)

  2 ⇡ 1 + x

  Igualando a variável y ao lado direito da aproximação dada pelos Eq. (2.15), obtém-se:

  3 x − x y =

  (2.16)

  2 1 + x

Desenvolvendo-se a Eq. (2.16) obtêm-se o polinômio adimensional dado pelo lado esquerdo da

igualdade da Eq. (2.17)

  3

  2 x + x

  (2.17) y − x + y = 0

Fazendo as transformações das variáveis y e x para correntes I out e I in respectivamente, e substi-

tuindo no polinômio da Eq. (2.17) obtém-se:

  

I

out y =

  (2.18)

  I I in x = (2.19)

  I

  3

  2 I in I in I out I in I out = 0 (2.20) + +

  3

3 I

  I I

  I Removendo os denominadores obtém-se:

  3

  2

  2

  2 I in + I in I out I in + I I out = 0 (2.21) − I

O lado esquerdo da igualdade na Eq. (2.21) é um polinômio modo-corrente de grau 3 equivalente ao

polinômio adimensional do lado esquerdo da igualdade na Eq. (2.17). Nota-se que o polinômio da

Eq. (2.21) é homogêneo, ou seja, todos os seus monômios possuem o mesmo grau. Outro aspecto

importante é que cada variável pode ser transformada por uma corrente de referência diferente,

ou seja, não é necessário que todas as variáveis sejam transformadas por meio da mesma corrente

como foi feito no exemplo acima. Por exemplo, ao escolher as transformações: I out y =

  (2.22)

  I

  2 I in x =

  (2.23)

  I

  1 O polinômio modo-corrente resultante possui um grau a mais:

  3

  2

  2

  3 I I in + I I in I out

  I I in + I I out = 0 (2.24)

  2 1 − I

  1

  2

  1 Assim, existem várias formas de se transformar um polinômio adimensional em um polinômio

modo-corrente homogêneo. Por ser um método direto e discricionário, não é necessário um algo-

ritmo para esta etapa.

2.5 Decomposição Translinear Paramétrica

  Nem sempre é possível encontrar um polinômio translinear dentro do intervalo de coeficientes

inteiros especificado. Entretanto, é possível dividir o polinômio de entrada E r em sub-polinômios

menores utilizando variáveis intermediárias, ou seja, parâmetros. Em [27], o método de decom-

posição paramétrica descrito nesta seção é proposto. Dado o polinômio de entrada na forma

  , e I uma variável intermediária, P (I 1 , I 2 , . . . , I n ), sendo n o número de variáveis chamadas I n p pode-se efetuar a transformação das Eqs. (2.25) P (I , I , . . . , I n ) = P (I , I , . . . , I n , I p ) (2.25a)

  1

  2

  1

  2 (2.25b) P (I

  1 , I 2 , . . . , I n , I p ) = 0

Cada uma das das Eqs. (2.25) formará uma malha translinear distinta. Deste modo, a variável

intermediária I p não poderá ser uma combinação linear das variáveis I n , ou a Eq. (2.25b) não

formará um polinômio homogêneo. Para ilustrar melhor o método e esta afirmação, suponha que

deseja-se realizar decomposição paramétrica no polinômio homogêneo E dado pela Eq. (??):

  3

  2

  2

  2

  3 E = a b + ab + ya + yab + y (2.26)

  3

  2

  2

  

2

  3 a b + ab + ya + yab + y = 0 (2.27)

Seguindo a forma das Eqs. (2.25), divide-se este polinômio em dois usando a variável I p , conforme

ilustrado na Eq. (2.28):

  2

  2

  2

  

3

  2

  2

  2 (2.28a)

a b + ab + ya + yab + y = a b + ab + ya + I p ab

  2

  2

  2 a b + ab + ya + I p ab = 0 (2.28b)

Simplificando a Eq.(2.28a) e a Eq. (2.29a), obtém-se um novo conjunto de polinômios dados pela

  Eq. (2.29):

  3 yab + y p ab = 0 (2.29a)

− I

  2 ab + b + ya + I p b = 0 (2.29b)

Estes polinômios são mais simples que o da Eq. (2.26), e se for conveniente, pode-se reduzir

qualquer um deles ainda mais repetindo o processo, introduzindo outras variáveis intermediárias.

  Isolando I p na Eq. (2.29b), obtém-se: ya (2.30) I p = a + b + b

A Eq. (2.30) mostra que não há como a variável I p ser uma combinação linear das variáveis [a, b, y]

do polinômio E , caso contrário o polinômio dado pela Eq. (2.28b) não seria homogêneo. A

  3

variável intermediária deve sempre formar um monômio do mesmo grau do polinômio de entrada.

  Em [23], o autor afirma que o algoritmo de decomposição não-paramétrica formulado por ele

(a ser visto na seção 3.3.1.1) não pode ser utilizado para encontrar os polinômios translineares dos

polinômios modo-corrente gerados por este processo de decomposição paramétrica. Já o algoritmo

de decomposição não-paramétrica desenvolvido neste trabalho pode ser utilizado no auxílio deste

  

processo de decomposição paramétrica (a ser visto na seção 3.4.1.2). Aplicando este algoritmo ao

conjunto da Eq. (2.29) obtém-se o conjunto de decomposições não-paramétricas dado pela Eq.

(2.31)

  3 y p (2.31a) − ab(I − y) = 0

  (a + b)(I p p (2.31b) − y) = 0

  • + b) − a(I

    De acordo com a pesquisa realizada, não foi encontrado algoritmo de decomposição paramé-

    trica automatizado algum. Provavelmente porque há infinitas formas de se adicionar variáveis

    intermediárias [25].

2.6 Princípio Translinear Dinâmico [38]

  O princípio STL permite transformar equações algébricas estáticas em circuitos translineares,

e o princípio DTL (Dynamic Trasnlinear) permite transformar equações diferenciais, lineares ou

não, também em circuitos translineares. Para realizar esta transformação, basta associar um

capacitor a um dispositivo de comportamento exponencial, dado pela Eq. (2.2), como visto na

seção 2.3. A Fig. 2.4 mostra como é feita a associação: Sendo I a corrente que flui dentro do

cap Principle of dynamic translinear circuits.

  

Figura 2.4: Princípio Translinear Dinâmico [38]

capacitor C, I a corrente de coletor do transistor, e V a tensão base-emissor do transistor.

  C BE

V const representa qualquer dispositivo que tenha uma tensão constante entre seus terminais que

ficam entre o capacitor e a base do transistor. Como o emissor do transistor e a placa inferior do

capacitor estão conectadas ao mesmo nível de referência, o capacitor e o transistor formam uma

malha translinear dinâmica. Aplicando a LTK nesta malha, obtêm-se a Eq. (2.32):

  (2.32) cap + V const + V BE = 0

  −V Substituido a expressão de V , dada pela Eq. (2.3), na Eq. (2.32), obtém-se: BE

  ◆ ✓ I C cap + V const + V T ln = 0 (2.33)

  −V

  I S Diferenciando a Eq. (2.33) obtém-se: ✓ ◆◆ ✓ I dV cap d C

  V T ln + = 0 (2.34) − dt dt

  I S ◆ ✓ I ◆ d ✓ I dV cap S C

  • V T = 0 (2.35) − dt

  I C dt

  I S

✓ 1 ◆ dI

dV cap C = V T

  (2.36) dt

  I C dt Entretanto, dV cap I cap = C (2.37) dt

Substituindo a expressão de I cap na Eq. (2.36), e multiplicando-a pela capacitância C, tem-se a

  Eq. (2.38): ✓ 1 ◆ dI C

  I cap = CV T (2.38)

  I C dt

Mudando a notação de derivada para um ponto sobrescrito, a Eq. (2.38) pode ser rescrita na forma

da Eq. (2.39) : ˙

  I C

I cap = CV T

  I C ˙ (2.39) CV T

  

I C = I cap

  I C O princípio DTL é uma conseqüência direta da Eq. (2.39): “A derivada no tempo de uma

corrente pode ser mapeada em um produto de correntes” [38]. O lado direito da Eq. (2.39) pode

ser realizado facilmente utilizando o princípio STL, ou seja, a implementação de partes de uma

equação diferencial é equivalente à implementação de um produto de correntes.

  Pode ser que haja mais transistores na malha translinear dinâmica nos quais as tensões V BE

de suas junções não são constantes. A Fig. 2.5 mostra dois exemplos onde esta situação ocorre.

Aplicando os mesmos cálculos das Eqs. (2.32) a Eq. (2.39) aos arranjos da Fig. 2.5 (a) e (b),

  

Figura 2.5: Arranjos distintos de correntes de capacitor. [38]

obtém-se, respectivamente, as Eqs. (2.40a) e (2.40b) ! ˙ ˙

  I X I out

  I C 2 = CV T (2.40a) −

  I I X out

  ! ˙ ˙

  I X I out (2.40b)

  I C 1 = CV + T

  I X I out

  

Assim, utilizando os índices SH e SAH para denominar os transistores com suas junções base-

emissor no sentido horário e no sentido anti-horário de uma malha translinear dinâmica, I a

j

corrente de coletor que flui pelo transistor j, e I C a corrente do capacitor, o princípio DTL pode

ser generalizado na forma da Eq. (2.41):

  1 ˙ ˙

  X X

  I I j j

  @ A

  I C = CV T (2.41) −

  I j I j j

2 SH j

  2 SAH

2.6.1 Transformação de Variáveis Dinâmicas

  Para implementar uma equação diferencial adimensional em um circuito translinear, além da

transformação das variáveis estáticas vista na seção 2.4.2, deve-se transformar as derivadas adimen-

sionais para derivadas no tempo, para que o princípio DTL possa ser aplicado. Assim, considera-se

que as derivadas adimensionais são realizadas em relação à variável implícita ⌧ . Como exemplo,

a equação diferencial de primeira ordem dada pela Eq. (2.42) pode ser escrita na forma da Eq.

(2.43): ˙y + y = x (2.42) d y(⌧ ) + y(⌧ ) = x(⌧ ) (2.43) d⌧

Deve-se aplicar ao termo d/d⌧ uma transformação que gere d/dt na forma da Eq. (2.44), para

manter os dois lados adimensionais:

d d

  (2.44)

= [tempo] ×

d⌧ dt

Entretanto, deve-se gerar “tempo” combinando unidades de variáveis de circuito (tensões, correntes,

capacitâncias, resistências, etc.). Como isso pode ser feito de várias formas, deve-se procurar fazê-lo

de uma forma que seja vantajosa para a realização do circuito. Como deseja-se utilizar o princípio

DTL para implementar a derivação em um circuito, a constante CV da Eq. (2.39) é um bom

  T ponto de partida. A unidade desta constante é dada pela Eq. (2.45): [carga]

  (2.45) T ] =

  × [tensão] = [carga] [C] × [V [tensão] Assim, basta agora encontrar uma unidade k que relacione carga e tempo:

  (2.46)

[tempo] = k × [carga]

[tempo] k =

  (2.47) [carga] 1 (2.48) k = [corrente]

  

Assim, a constante CV equivale a “tempo”, sendo I uma corrente constante, e a Eq. (2.49)

T /I mostra a transformação dada pela Eq. (2.44) modificada:

d CV T d

  = (2.49) d⌧

  I dt Uma conclusão direta da Eq. (2.49) é que o funcionamento do circuito agora depende da

constante V , logo é sensível à variação de temperatura. Uma forma de contornar este problema

T

  6 é fazer a corrente I PTAT .

  Retomando o desenvolvimento da Eq. (2.43), aplicando a transformação dada pela Eq. (2.49), obtém-se: CV d

  T (2.50) y(⌧ ) + y(⌧ ) = x(⌧ )

  I dt

Agora deve-se transformar as variáveis adimensionais, em ⌧ , em variáveis de correntes no tempo,

conforme mostrado na seção 2.4.2. Utilizando uma única corrente I 1 para realizar esta transfor- mação, a Eq. (2.50) fica:

  CV d I y I y I x T

  (2.51) = + I dt

  I

1 I

  1 I

  1 Eliminando-se I 1 da Eq. (2.51), bem como mudando a notação de derivação para um ponto sobrescrito, a transformação de variáveis da Eq. (2.42) fica: ˙

  CV T I y + I I y = I I x (2.52) A Eq. (2.52) é uma descrição modo-corrente de um filtro passa-baixa de primeira ordem [34].

Combinando a Eq. (2.52) com a Eq. (2.39), obtém-se o polinômio modo-corrente equivalente deste

filtro:

  (2.53) I cap I y + I

I y

I x = 0 − I

  A Eq. (2.53) pode ser realizada em um circuito translinear utilizando o princípio STL. Desta

forma, a realização do circuito implica em uma malha STL superposta a uma malha DTL. Ao

encontrar possíveis polinômios translineares equivalentes à Eq. (2.53), deve-se verificar se as malhas

encontradas são compatíveis. Tomando como exemplo o desenvolvimento do filtro de primeira

ordem dado pela Eq. (2.52), foi utilizada a malha DTL da Fig. 2.4 para gerar a Eq. (2.39), que

˙ por sua vez foi utilizada para substituir o termo CV T I y na Eq. (2.52). Se um polinômio translinear

equivalente à Eq. (2.53) implicar em introduzir junções na malha DTL entre o capacitor e a base

do transistor por onde flui I onde as tensões V não são constantes, esta malha DTL não será

y BE compatível com a malha dada pela Fig. 2.4, logo este polinômio translinear não será válido.

  Quando não é possível encontrar um polinômio translinear onde a malha STL seja compatível

com a malha DTL, uma nova malha DTL deve ser especificada, e o projeto é reiniciado até que

seja encontrado um polinômio translinear que tenha suas malhas STL e DTL compatíveis.

  Assim, evidencia-se uma vantagem em se utilizar circuitos translineares: Funções de transfe-

rências, como filtros passivos por exemplo, podem ser implementadas em circuitos translineares

utilizando apenas transistores e capacitores. Combinado à alta densidade de componentes pro-

porcionado pelas tecnologias CMOS, pode-se criar circuitos de elevada complexidade funcional

utilizando transistores MOS. Como os circuitos translineares dispensam o uso de resistores, que

tendem a ter dimensões muito grandes quando se utiliza correntes muito pequenas, e quanto maior

o resistor, maior tende a ser a sensibilidade do circuito em relação à temperatura, esta é uma

vantagem muito importante para circuitos de baixíssimo consumo de energia.

6 Proportional To Absolute Temperature

  —Proporcional à Temperatura Absoluta

2.7 Exemplo de Síntese: Circuito RMS-DC [26]

  7 Uma forma de se implementar um circuito que fornece um valor DC proporcional ao valor

8 RMS é dada pela Fig. 2.6, onde LPF (low-pass filter) se refere a um filtro passa-baixas. A equação Fig. 4. Block schematic of a conventional rms-dc converter.

  

Figura 2.6: Diagrama de blocos de um conversor RMS-DC [26]

diferencial translinear do filtro utilizado é a dada pela Eq. (2.52), desenvolvida na seção anterior.

2 A transformação de variáveis do bloco z = x /y é dada por:

  2 I in I z =

  (2.54)

  I y

  

Substituindo I e I na Eq. (2.52), obtém-se a equação diferencial translinear, já com

y = I out x = I z as variáveis estáticas transformadas:

  2

  2 ˙ CV T

  I out I out + I

  

I

I = 0 (2.55) out − I in

  

Para encontrar a corrente de capacitor e transformar a Eq. (2.55) em um polinômio modo-corrente,

define-se o circuito da malha translinear dinâmica na Fig. 2.7. Esta malha é definida com dois

  2

transistores, pois na Eq. (2.55) aparece I , e este ramo poderá implementar esta parte do circuito

out estático.

  Subcircuit of the dynamic translinear rms-dc converter

Figura 2.7: Malha translinear dinâmica RMS-DC [26]

Deste modo, aplicando a fórmula geral do princípio DTL dada pela Eq. (2.41), a relação entre

  7 Direct Current —Corrente contínua

  8 Root Mean Square —Raiz da Média Quadrática o termo derivativo e a corrente de capacitor é obtida: ! ˙ ˙

  1 I out I out I + cap = CV T

  2 I out I out ! ◆ ˙

  ✓ 1 I out I cap = 2 C

  V T

  2 I out

˙

I cap I out = CV I out (2.56)

  T

Substituindo o resultado da Eq. (2.56) na Eq. (2.55), o polinômio modo-corrente é dado pela Eq.

  (2.57)

  2

  

2

  2 I cap I + I

  

I

I = 0 (2.57)

out out − I in

  

Aplicando-se decomposição não-paramétrica no polinômio modo-corrente da Eq. (2.57), obtém-se

o polinômio translinear:

  2

  2 I (I cap + I I = 0 (2.58) out ) − I in O circuito relativo ao polinômio translinear da Eq. (2.58) é mostrado na Fig. 2.8. A malha

estática é formada pelos transistores Q a Q , sendo que os transistores conectados no sentido

  1

  6

horário são Q e Q , que implementam I , e Q , que implementa I . Já os transistores conectados

  1 2 in

  4

no sentido anti-horário são Q e Q , que implementam I out , e Q que implementa (I cap + I ). A

  5

  6

  3 malha translinear dinâmica é dada pelo capacitor e os transistores Q e Q .

  5

  6 Como o transistor Q , é polarizado pela corrente constante I , ele é visto pela malha dinâmica

  3

como uma fonte de tensão constante, portanto não tem influencia alguma na malha dinâmica. Os

transistores Q e Q servem para compensar as correntes de base, e colocar Q e Q no modo

  7

  8

  2

  4

“diode-connected”. Assim, as correntes em Q , Q e Q são fixadas, fazendo com que as correntes

  1

  

2

  4

em Q , Q e Q variem de forma a manter a igualdade do polinômio-translinear implementado

  3

  5

  6 pelo circuito, dado pela Eq. (2.58).

  

Figura 2.8: Circuito RMS-DC [26]. A malha estática é formada por Q aQ ; a malha dinâmica é

  1

  6 formada por 1/2C, e Q a Q

  5

6 Como a malha translinear dinâmica é compatível com a malha translinear estática, o projeto

  

está pronto. Um ponto interessante é que a frequência de corte do filtro passa-baixas é dada

  

pela Eq. (2.59), mostrando que os circuitos translineares podem ter vários de seus parâmetros

controláveis por meio das correntes utilizadas nas transformações de variáveis.

  I ! = (2.59) c

  CV T

2.7.1 Circuito da função Módulo [27]

  O circuito RMS-DC assume que a corrente I está retificada antes de alimentá-lo. Assim, in

pode-se também realizar um circuito translinear estático que implemente a função módulo com

esta finalidade. O polinômio adimensional que representa a função escolhida é dado pela Eq. (2.60)

  2

  2 y = x (2.60) √

  2 y = x (2.61) (2.62)

y = |x|

Assim, y = −x se x < 0 e y = x se x > 0. O polinômio modo-corrente relativo à Eq. (2.60) é dado

pelo lado esquerdo da Eq. (2.63):

  2

  

2

I = 0 (2.63) y − I x

Entretanto, este polinômio não implementaria o circuito de forma satisfatória, pois se I x < 0,

então o transistor entraria em corte. Para solucionar o problema, pode-se adicionar e subtrair o

  2

monômio I à Eq. (2.63) sem alterar o seu comportamento e mantendo o polinômio homogêneo:

  2

  2

  

2

  2

  • I + I = 0 −I y − I x

  2

  2

  2

  2 (I ) = 0 (2.64)

− I x ) − (I − I y

  2

2 Aplicando o produto notável a

  − b = (a + b)(a −b) à Eq. (2.64), obtém-se o polinômio translinear dado pela Eq. (2.65) (I + I x )(I x + I y )(I y ) = 0 (2.65) − I − I

  ) − (I O circuito que implementa a Eq. (2.65) pode ser visto na Fig. 2.9 Para verificar que este circuito de fato implementa a Eq. (2.65), calculam-se as correntes dos

transistores que formam a malha estática Q . As correntes I e I , que fluem pelos respectivos

  2 −Q

  

5

  2

  3 transistores Q e Q são analisadas conforme as Eqs. (2.66):

  2

3 I = I + I (2.66a)

  3

  1 (2.66b)

  I 1 = I

2 I = I + I (2.66c)

  3

  2 I = I in (2.66d)

  2 3 − I substituindo Eq. (2.66d) na Eq. (2.66c): I = I + I in (2.66e)

  3 3 − I

1 I = (I in ) (2.66f)

  3 − I

  2

  2 (I − I out ) (2.67f)

  6 = I

  2 e Q

  3 estarão sempre com correntes de coletor positivas.

  As correntes I

  4 e I

  5 , que fluem pelos respectivos transistores Q

  4 e Q

  5 são analisadas conforme as Eqs. (2.67):

  I = I 4 + I

  

6

(2.67a)

  I

  5 (2.67b) I = I

  2 (I + |I in |) se I in < 0 Desta forma, desde que |I in

  4

  

5

(2.67c)

  I

  4 = I

  5

− I

out (2.67d) substituindo Eq. (2.67d) na Eq. (2.67c): I = I

  5

  5 − I out (2.67e)

  I

  5 =

  1

  | < I , os transistores Q

  1

  

Figura 2.9: Circuito retificador de onda completa, com a malha translinear composta pelos tran-

sistores Q

  1

  2 a Q

  5 [27] substituindo Eq. (2.66f) na Eq. (2.66c):

  I =

  1

  2 (I − I in

  ) + I

  2 (2.66g)

  2I

  2 = I + I in (2.66h)

  I 2 =

  2 (I + I in ) (2.66i) Assim:

  2 (I − |I in |) se I in > 0

  I

  2 =

  8 < :

  1

  2 (I + |I in |) se I in > 0

  1

  2 (I − |I in |) se I in < 0 e

  I

  3 =

  8 < :

  1

  • + I

  • + I

substituindo Eq. (2.67f) na Eq. (2.67c):

  1 I = (I out ) + I (2.67g) − I

  4

  2

  2I = I + I out (2.67h)

  4

  1 I = (I + I out ) (2.67i)

  4

  2 Olhando novamente para o circuito da Fig. 2.9, os transistores Q e Q estão conectados no

  2

  3

sentido horário, enquanto que Q e Q estão conectados em sentido anti-horário. Assim, este

  4

  5 circuito implementa o polinômio modo corrente:

  (2.68)

  I

  3

2 I

  

4

I 5 = 0 − I

Substituindo os valores das correntes dados pelas Eqs. (2.66f), (2.66i), (2.67f), e (2.67i) na Eq.

  

(2.68), obtém-se o polinômio translinear dado pela Eq. (2.69) que é equivalente ao polinômio

translinear dado pela Eq. (2.65). Assim, o circuito implementa corretamente a função módulo.

  1

  1

  

1

  1 (2.69)

(I + I x ) (I x (I + I y ) (I y ) = 0

− I − I

  ) −

  2

  2

  

2

  2 O transistor Q tem sua tensão base-emissor flutuante, logo fornece I para o nó entre o emissor

  7 out de Q e o coletor de Q , pois as correntes I e I são forçadas pela malha dada pela Eq. (2.65)

  4

  5

  4

  

5

2.8 Outras Metodologias de Síntese Translinear

  Em [22], um estudo sobre a convergência dos métodos de síntese de filtros translineares é

realizado. As metodologias listadas nesse estudo são: mapeamento de espaço de estados exponen-

ciais [39], a adaptação da técnica de filtros LC em escada [40], e os mesmos fundamentos utilizados

na metodologia do trabalho desta dissertação em [28], estendidos com o uso da célula de Ber-

noulli [41]. O autor afirma que todas essas metodologias produzem uma combinação entre malhas

estáticas e dinâmicas, e que, ainda que os autores considerem seus métodos únicos, eles são na

verdade semelhantes. Um ponto em comum nos métodos apresentados em [22] é que são baseados

em construir um bloco básico de um integrador translinear, e combiná-los de alguma forma para

obter a funcionalidade desejada [22]. Além das metodologias descritas em [22], em [15] é realizada

uma descrição completa de síntese de filtros translineares em espaço de estados, com detalhes de

implementação em hardware.

  9 Entretanto, as metodologias descritas acima limitam-se apenas a síntese de filtros translineares .

  Assim, a metodologia utilizada nesta dissertação permite encontrar uma realização em circuito

de qualquer função matemática, não limitando-se a síntese de filtros. Em relação à síntese de filtros,

tem a vantagem de poder produzir circuitos mais compactos, pois busca realizá-los em poucas

malhas translineares, preferencialmente em uma única, enquanto que nas outras metodologias

citadas acima, o uso de blocos básicos pode resultar em circuitos de maiores dimensões, o que por

sua vez pode levar a um desempenho inferior.

9 Os filtros translineares são também chamados filtros log-domain

2.8.1 Algoritmo de Grafos de David Ilsen [25]

  Nesse trabalho, um método semelhante ao da Fig. 2.1 é desenvolvido, porém a metodologia da

etapa de decomposição polinomial é substituída por um algoritmo de classificação de padrões de

polinômios baseado em teoria dos grafos. Este algoritmo cria um catálogo de todas as topologias

de circuitos translineares para um dado número de transistores, bem como os polinômios transli-

neares expandidos e simplificados associados a cada uma delas. A partir daí, procura-se ajustar o

polinômio de entrada a uma ou mais topologias do catálogo que tenham maior probabilidade de

representá-lo, por meio de classificação de padrões. A Fig. 2.10 mostra o catálogo de topologias

com até seis transistores, onde cada ramo em um grafo representa um transistor, e a Tabela 2.2

mostra o número de topologias geradas pelo algoritmo para até nove transistores.

  A vantagem deste algoritmo é que ele encontra o equivalente a decomposições paramétricas e

não paramétricas do polinômio modo-corrente, pois como pode se perceber na Fig. 2.10, topologias

com malhas múltiplas são consideradas. No entanto, a principal desvantagem, é que a a sua

c

implementação disponibilizada depende do pacote de software proprietário MATHEMATICA ,

não sendo assim, uma implementação amplamente acessível e de baixo custo.

  

Tabela 2.2: Número de topologias de circuitos translineares para um dado número de transistores

[25] numero de transistores

  

4

  5

  6

  7

  8

  9 numero de topologias

  

2

  3

  19 39 174 559

Figura 2.10: Topologias de circuitos translineares contendo até seis transistores [25] Capítulo 3 Algoritmos de Decomposição Translinear não-paramétrica

  3.1 Introdução Neste capítulo são apresentados três algoritmos de decomposição não-paramétrica: Um algo-

  1

  2

ritmo trivial, o algoritmo de Mulder et. al. [23] , e o algoritmo desenvolvido neste trabalho . Estes

algoritmos são apresentados já da forma que foram implementados nos fluxografos desta seção.

  3.2 Análise Combinatória de um Algoritmo Trivial Para mostrar a necessidade de se criar um algoritmo complexo de decomposição não-paramétrica,

primeiro desenvolveu-se um algoritmo simples de pura força-bruta, no qual todas as combinações de

polinômios-base na forma da Eq. (2.12) são testadas e comparadas com o polinômio modo-corrente

relativo ao polinômio de entrada E r . Para realizar a análise de viabilidade deste algoritmo, basta

calcular quantas combinações serão testadas.

  A partir de um vetor de polinômios-base contendo N elementos, N dado pela Eq. (2.13), β β

deve-se calcular quantas combinações destes polinômios-base encaixam-se no modelo da Eq. (2.12).

  

Como a multiplicação possui propriedade comutativa, cada lado da equação pode ter uma com-

binação entre N polinômios tomados r a r com repetição, pois um polinômio-base pode estar

β multiplicado mais de uma vez. Define-se então o número A(N

  β , r) na Eq. (3.2). Finalmente,

como cada produto da Eq. (2.12) pode assumir A(N β , r) combinações, define-se o número N trivial

na Eq. (3.3) como a combinação do número A(N β , r) tomado 2 a 2. n + p − 1! CR =

  (3.1a) (n,p) p!(n − 1)! n!

  C = (3.1b)

  (n,p) p!(n − p)!

  1 Deste ponto em diante este algoritmo será chamado de “algoritmo original”

  2 Deste ponto em diante este algoritmo será chamado de “novo algoritmo”

  

N β

  • r − 1! (3.2) A(N β , r) =

    r!(N β

    − 1)! ⇣ ⌘

  (N +r 1)! β0

  ! r !(N 1)!

  β0 N (N , r) =

  (3.3)

trivial β h⇣ ⌘ i

(N +r 1)!

  β0 2! ! − 2 r !(N 1)!

  β0

Para exemplificar, utilizando a Eq. (3.3), calcula-se o número de combinações possíveis para

se encontrar todos os polinômios modo-corrente válidos de um polinômio de terceiro grau, três

variáveis e com coeficientes de -5 a 5 (n = 3, r = 3, N = 5).

3 N β = 1331

  = (2 ∗ 5 + 1) 1331 + 3 − 1! A(1331, 3) = = 393.877.506 3!(1331 − 1)!

  393.877.506!

  16 (3.4) N trivial (1331, 3) =

  = 7, 75697447 × 10 2!(393.877.506 − 2)! Se fosse tentado encontrar polinômios translineares por meio de um processador hipotético de

  

8 GHz (recorde de velocidade nesta data), e que toda a operação de multiplicar, expandir, simpli-

ficar a combinação de polinômios-base e compará-lo com o polinômio modo-corrente E r coubesse

em apenas um ciclo de processamento, o tempo necessário para encontrar todas os polinômios

translineares possíveis seria:

  16 7, 75697447 × 10 t =

  (3.5) ≈ 9.696.218 segundos ≈ 112 dias

  9 8 × 10 As Figuras 3.1a à 3.1d mostram o número de dias necessários para se testar todas as possi-

bilidades de polinômios translineares utilizando o algoritmo trivial, para diferentes valores de N,

r, e v. Pode-se perceber que o uso do algoritmo trivial leva um número elevado de dias para ser

executado para os valores N ≥ 4, v ≥ 3 e r ≥ 3. Conclui-se que um algoritmo mais eficiente é

necessário.

3.3 Algoritmo de decomposição não-paramétrica original [23]

  De acordo com a pesquisa realizada, o algoritmo de decomposição não-paramétrica desenvol-

vido em [23] aparentemente é o único publicado até hoje. Ele explora a forma da decomposição

translinear dada pela Eq. (2.12) para usar a operação de divisão por pares de polinômios e ex-

pansão em frações parciais. Isso permite encontrar polinômios translineares de uma forma mais

inteligente que o algoritmo trivial visto na seção 3.2. O algoritmo é dividido em três etapas: A

Geração do Vetor de Polinômios-Base, a Divisão recursiva por pares de polinômios-base e a Veri-

ficação final. A Fig. 3.2 mostra um diagrama com estas etapas, e as seções seguintes descrevem

cada uma delas. Como o autor do algoritmo original não apresentou a estrutura da implementação

de seu algoritmo, duas versões da etapa de “Divisão recursiva por pares de polinômios-base” foram

implementadas neste trabalho: uma versão otimizada para minimizar o tempo de execução, e uma

versão otimizada para minimizar a memória utilizada.

  

(a) Grau 2

(b) Grau 3

  

(c) Grau 4

(d) Grau 5

Figura 3.1: Dias necessários para execução do algoritmo trivial para diversos valores de N e v.

  Cada gráfico corresponde a diferentes graus r do polinômio de entrada E r

  

Figura 3.2: Estrutura de topo da implementação do algoritmo original de decomposição não-

paramétrica [23]

3.3.1 Geração do vetor de Polinômios-Base

  Como visto na seção 3.2, o número de polinômios-base N β do vetor tem um grande impacto

no número de computações, não só do algoritmo trivial, mas também de qualquer algoritmo que se

possa conceber. Esse algoritmo utiliza duas estratégias para reduzir o número de polinômios-base:

A obtenção de polinômios-base estritamente positivos, que gera o vetor a partir do vetor , e

  1

a Divisão por um polinômio base e fatoração do resto, que gera o vetor a partir do vetor .

  2

  1

  3.3.1.1 Obtenção de Polinômios-Base Estritamente Positivos Como os polinômios-base representam correntes de coletor, a primeira coisa a se fazer é excluir

todos os polinômios-base que não são estritamente positivos. Parte-se do princípio que, ao realizar

a síntese de um circuito translinear, todos os limites superiores e inferiores das correntes sejam co-

nhecidos. Isso é trivial para variáveis estáticas, mas para variáveis dinâmicas é necessário conhecer

as formas de onda e as freqüências das correntes de entrada, e resolver a equação diferencial para

obter os limites das correntes de saída. Para determinar se o polinômio-base é estritamente posi-

tivo, basta substituir os respectivos limites inferiores nas variáveis com coeficientes positivos, e os

respectivos limites superiores nas variáveis com coeficientes negativos, e caso a soma der positiva,

o polinômio é estritamente positivo, e é copiado do vetor para o vetor . A ilustração deste

  1 procedimento pode ser vista na Fig. 3.3

  3.3.1.2 Divisão por um Polinômio-Base e fatoração do resto A forma geral de um polinômio translinear dada pela Eq. (2.12) pode ser explorada para

verificar se um polinômio-base pode fazer parte de um polinômio translinear. Suponha que um

polinômio homogêneo de terceiro grau E , seja equivalente ao polinômio translinear dado pela Eq.

  3

(3.6). Se dividirmos ambos os lados desta equação por um de seus polinômios-base, P por exemplo,

  1

o resultado é dado pela Eq. (3.7). Assim, se o resto da divisão, representado neste exemplo

por P P P , não for favorável em r polinômios lineares, então não existe polinômio translinear

  2

  4

  6

equivalente a E na qual P possa fazer parte, logo não deve ser copiado no vetor . Todos os

r

  1

  2

polinômios-base do vetor são submetidos a este teste, e os polinômios-base não-eliminados são

  1

  

Figura 3.3: Obtenção de Polinômios-Base (PB’s) estritamente positivos. O vetor é obtido a

  1 partir do vetor . O índice ‘i’ é utilizado para percorrer o vetor copiados no vetor . A Figura 3.4 ilustra este sub-algoritmo.

2 E = P P P P P P (3.6)

  3

  1

  1

  3 5 −

  2

  2

  4

  6 E P P P

  3

  2

  4

  6 = P P

  (3.7)

  1

  3

5 −

  2 P P

  1

  1 Como exemplo, fazendo E igual ao polinômio da Eq. (2.21), ele é dividido por P + = (6I in

  3

  1

  

5I out + 6I ), e o resultado com o resto R obtido fatorado é mostrado na Eq. (3.8). O Quociente Q

não é calculado, pois não é relevante neste teste.

  3

  2

  2

2 E = I + I

  I I + I I ; P = (6I + 5I + 6I ) 3 in in out in out 1 in out

  − I

  3

  2

  2

  2 I in + I in I out I in + I I out

  1 I out (5I out )(5I out ) − I − 12I − 6I = Q + (3.8)

(6I in + 5I out + 6I ) 216 (6I in + 5I out + 6I )

  1 (3.9) R =

  I out (5I out )(5I out ) − 12I − 6I 216

O resto dado pela Eq. (3.9) é favorável em 3 polinômios lineares, logo (6I + 5I + 6I ) pode

in out

fazer parte de um polinômio translinear equivalente ao polinômio dado pela Eq. (2.21), e deve ser

copiado no vetor .

2 Um outro exemplo é realizado utilizando o mesmo E do exemplo anterior, mas fazendo P =

  3

  1

  • I + I ). Repete-se o procedimento de divisão por P e fatoração do resto, e o resultado,

  in out

  1 (−I já com o resto R fatorado, é mostrado na Eq. (3.10).

  3

  2

  2

  

2

E = I in + I in I out I in + I I out ; P in + I out + I ) 3 − I

  1 = (−I

  3

  2

  2

  2

  2

  2 I in + I in I out I in + I I out I out (2I + 5I out I + 4I ) − I out = Q + (3.10) in + I out + I ) in + I out + I )

  (−I (−I

  2

  2 (3.11) R = I out (2I + 5I out

  I + 4I ) out

  

O resto dado pela Eq. (3.11) é fatorável em um polinômio linear e um polinômio quadrático

in + I out + I ) não deve ser copiado para o vetor

  2 irredutível, logo o polinômio (−I

Figura 3.4: Divisão por um Polinômio-Base (PB) e fatoração do Resto. O índice ‘i’ é utilizado

para percorrer o vetor

  1

  

3.3.2 Divisão recursiva por pares de polinômios-base, versão otimizada para

minimizar tempo de execução Nesta etapa os polinômios-base do vetor são combinados por meio de divisões polinomiais e

  2

expansão em frações parciais dos restos. Este método armazena listas de polinômios-base que são

reutilizados em memória, a fim de evitar repetições de rotinas desnecessárias. Entretanto, não há

como controlar o tamanho destas listas em memória, tornado esta versão insegura nesse sentido.

  As seções a seguir detalham as etapas deste sub-algoritmo.

  

3.3.2.1 Divisão por pares de Polinômios-Base e Expansão do Resto em frações par-

ciais Uma forma efetiva de verificar quais polinômios-base podem fazer parte de um polinômio

translinear juntos, é dividir o polinômio de entrada E r por um par de polinômios base e expandir

o resto em frações parciais. Para ilustrar este exemplo, pode-se assumir um polinômio E que que

  3

seja equivalente a um polinômio translinear conforme a Eq.(3.6). A Eq. (3.12) mostra a divisão

de E por 2 polinômios-base, P e P , que fazem parte do polinômio translinear, mas pertencem

r

  1

  2

a produtos opostos. Nota-se que o grau dos restos nos numeradores sobre P e P possuem grau

  1

  2 menor que E

  3 , e podem ser fatorados em r − 1 polinômios lineares. O Quociente da divisão Q é irrelevante neste teste, logo não é calculado.

  

E P P P P

  3

  3

  5

  4

  6 = Q +

  (3.12)

  1

  2 − P P P P

  1

  2

  2

  1 Deste modo, pode-se generalizar esta etapa baseando-se nas Eqs. (3.13) e (3.14) da seguinte forma:

Divide-se o polinômio homogêneo E r por um par de polinômios-base, P x e P y , pertencentes a um

vetor de polinômios-base. Expande-se o resto desta divisão em frações parciais em relação a uma

  3 variável comum entre P x e P y . Se os numeradores desta expansão, R x e R y , fore de grau r − 1 e P podem, juntos, fazer parte de um x y e ambos fatoráveis em r − 1 polinômios lineares, então P polinômio translinear equivalente a E r como polinômios opostos.

  

E R R y

r x

  

= Q + (3.13) +

P x P y P x P y

(3.14) E r =

  1 P x P 1 . . . P 2r 1

  2 P y P 2 . . . P 2r −

Esta etapa do algoritmo divide o polinômio de entrada E r por todas as combinações entre polinômios-

base do vetor , e a cada vez que um resultado satisfatório é encontrado, a próxima etapa, “Divisão

  2

recursiva por pares de polinômios-base”, é iniciada, e ao final desta, a etapa de “Verificação final”

também é executada. Assim, este sub-algoritmo é o núcleo da etapa geral de “Divisão Recursiva

por Pares de Polinômios-Base”, e seu fluxografo é descrito na Fig. 3.5 Como exemplo, a Eq. (2.21) é dividida e por (6I in + 5I out + 6I ) junto com (5I in + 5I out + 4I )

e (I in + I out + I in + I out ), e os resultados, já com o restos expandidos em frações

) junto com (−I

  3 x y

  Se não houver uma variável em comum, pode-se usar uma variável qualquer de P e outra de P

  

parciais e fatorados, são mostrados nas Eqs. (3.15) e (3.16), respectivamente. Os Quocientes Q

não são calculados, pois não influenciam neste teste.

  3

  2

  2

  2 I in + I in I out I in + I

I out

− I =

  (6I in + 5I out + 6I )(5I in + 5I out + 4I ) ◆ ◆ 1 ✓ I out (5I out ) 2 ✓ I (10I out + 3I )

− 12I

  (3.15) Q + +

  36

  6I in + 5I out + 6I

  25

  5I in + 5I out + 4I

  3

  2

  2

  2 I in + I in I out I in + I I out − I =

  (+I in + I out + I in + I out ) )(−I ✓ ◆

  2

  3

1 I

  2I −I out (3.16)

  • Q + (2I out + I )

  I in + I out + I in + I out −I Na Eq. (3.15), os restos numeradores das frações parciais são de grau 2, um a menos que

o Polinômio de entrada, e são fatoráveis em 2 polinômios lineares, logo (6I + 5I + 6I ) e

in out

  

(5I in + 5I out + 4I ) podem formar juntos um polinômio translinear como polinômios opostos. Já

na Eq. (3.16), o grau dos numeradores das frações parciais é igual ao grau do polinômio de entrada,

então (I in + I out + I in + I out ) não podem formar juntos um polinômio translinear como

) e (−I polinômios opostos.

  3.3.2.2 Geração Recursiva de decomposições parciais Já que a divisão de E r por um par de polinômios-base P e P e a expansão em frações parciais

  1

  2

dos restos pode ser usada para verificar se este par pode fazer parte de um polinômio translinear

como polinômios opostos, então os numeradores do resultado da expansão em frações parciais

dos restos podem ser usados para iniciar um processo recursivo de divisão por 2 polinômios e

expansão em frações parciais do novo resto, e assim sucessivamente, até que o resto seja somente

uma constante.

  Denominando P x,n , Q x,n , e R x,n Polinômios-base, Quocientes, e Restos de índice x e grau n, Divide-se inicialmente, o polinômio E r por um par de polinômios-base, P e P , e obtém-se:

  1

  2 E r R 1,r 1 R 2,r 1 = Q

  (3.17) + + r,r

2 P P P P

  1

  2

  1

  2

e os Restos R e R são usados para iniciar outra divisão com expansão em frações parciais

  1,r 1 2,r 1 independentes: R R R

  

1,r 1 1,r 2 4,r 2

(3.18) + + = Q

  1,r 2 P P P P

  1

  4

  1

  4 R R R

2,r 1 2,r 2 3,r 2

  • = Q

  (3.19) + 2,r 2

  P P P P

  2

  3

  2

  3

e cada polinômio que gerar uma expansão em frações parciais bem-sucedida junto com o seu

polinômio-base de origem (P com P e P com P ) é armazenado em um conjunto temporário de

  4

  1

  3

  2

polinômios , e o processo recursivo continua dividindo o último numerador sobre o polinômio de

  

Figura 3.5: Divisão por pares de Polinômios-base e execução de decomposições parciais e Verificação

final, versão otimizada para tempo de execução. Os índices ‘i’ e ‘j’ são utilizados para percorrer o

vetor e gerar pares de polinômios-base. Os índices ‘k’ e ‘h’ ão utilizados para percorrer as listas

  2

de decomposições parciais ↵ x,k e ↵ y,h . O procedimento de Verificação final está destacado dentro

da caixa pontilhada

origem (R , R ) pelo polinômio de origem multiplicado a um outro polinômio-base de , até

  1,x 2,x

  2 que os restos sejam constantes, ou seja, tenham grau 0 (R 1,0 , R 2,0 ).

  Neste ponto, é copiado para uma lista de decomposições parciais encontradas para o seu

  

respectivo polinômio-base ↵ ,onde x refere-se ao índice do polinômio-base de referência, e n é

x,n

o índice do conjunto copiado para a lista ↵ . Isso significa que P terá uma lista ↵ de

x,n

1 1,n

conjuntos de polinômios-base que, quando multiplicados, podem fazer parte de um polinômio

translinear tendo P como polinômio oposto, e P também terá sua respectiva lista ↵ .

  1 2 2,n Como o processo recursivo relativo a P não depende dos resultados do processo relativo a P ,

  1

  2

o problema se divide em dois problemas separados. Os quocientes Q e os restos que não são

x,n

relativos aos polinômios-base de origem são descartados durante este processo. Este sub-algoritmo

pode ser melhor visualizado na Fig. 3.6.

  Como exemplo, utiliza-se o resultado da expansão em frações parciais da Eq. (3.15) para realizar

o procedimento de decomposições parciais, tem-se o primeiro passo tendo P como polinômio de

  1 referência: P = (6I in + 5I out + 6I ), = [R ]

  1 1,2

  1 R 1,2 = I out (5I out ) − 12I

  36 Escolhe-se P = (5I in + 5I out + 3I ):

  4

  1 I out (5I out ) − 12I = 36 (6I in + 5I out + 6I )(5I in + 5I out + 3I )

  ✓ ◆ ✓ ◆ 1 in

  1

  5I in + 3I −I − I

  • Q

  (3.20) 1,0

  5

  6I in + 5I out + 6I

  36

  5I in + 5I out + 3I Como a expansão em frações parciais foi bem-sucedida, adiciona-se P e substitui-se R por R 4 1,2 1,1 em . Segundo passo:

P = (6I in + 5I out + 6I ), = [R , (5I in + 5I out + 3I )]

  1 1,1

  1 R = in ) 1,1 − I

  (−I

  5 Escolhe-se P = I out :

  6 1 in ) − I

  (−I = 5 (6I in + 5I out + 6I )(I out ) ✓ ◆ ✓ ◆

  1

  1

  1 −1 (3.21)

  • 6

  6I in + 5I out + 6I

  30

  5I in + 5I out + 3I Como a expansão em fações parciais foi bem-sucedida, adiciona-se P e substitui-se R por R 6 1,1 1,0 em .

  1 P = (6I in + 5I out + 6I ), = [ , (5I in + 5I out + 3I ), I out ] (3.22)

  1

  6

  1 R = = 1,0

  

1

  6

  

Figura 3.6: Sub-rotina de geração da lista de decomposições parciais ↵ x,n . O índice ‘i’ é utilizado

para percorrer o vetor , e o índice ‘n’ guarda o número de conjuntos gravados na lista ↵ x,n

2 Como R é constante, é copiada para a lista ↵ de decomposições parciais relativas a P .

  1,0 1,0

  1 Agora executando a decomposição parcial para P :

  

2

P = (5I in + 5I out + 4I ), = [R ] 2 1,2

  2 R = I (10I out + 3I ) 2,2

  25 Escolhe-se P in + 5I out + I ):

  3 = (−I

  2 I (10I out + 3I ) = 25 (5I in + 5I out + 4I in + 5I out + I ) )(−I

  ✓ ◆ ✓ ◆

2 I

  2 I (3.23)

  • Q

  2,0

  15

  5I in + 5I out + 4I 75 in + 5I out + I −I Como a expansão em fações parciais foi bem-sucedida, adiciona-se P e substitui-se R por R

  3 2,2 2,1 em . Segundo Passo:

P = (5I in + 5I out + 4I ), = [R in + 5I out + I )]

  2 2,1 , (−I

  2 R = (I )

2,1

  15 Escolhe-se P = (I + I ): 5 in out

  2 I = 15 (5I + 5I + 4I )(I + I ) in out in out

  ✓ ◆ ✓ ◆

  1

  1

  1 −1 (3.24) +

  6

  5I in + 5I out + 4I

  30 I in + I out Como a expansão em fações parciais foi bem-sucedida, adiciona-se P e substitui-se R por R 5 2,1 2,0 em .

  1 (3.25) P

2 = (5I in + 5I out + 4I ), in + 5I out + I ), (I in + I out )]

= [− , (−I

  6

  1 R = 2,0

  2 = −

  6 Como R é constante, é copiada para a lista ↵ de decomposições parciais relativas a P .

  2,0 2,0

  2

3.3.3 Verificação Final

  Para entender melhor porque o processo de divisões recursivas e expansões dos restos em frações

parciais é eficaz, repete-se abaixo todas as operações de expansão de um polinômio de terceiro grau E :

  3 E

  3 R 1,2 R 2,2 (3.26a) + + = Q

  3,1 P P P P

  1

  2

  

1

  2 R R R 1,2 1,1 4,1

= Q (3.26b) + +

  1,0 P P P P

  1

  4

  1

  4 R R R 1,1 1,0 6,0 = (3.26c) + P P P P

  

1

  6

  1

  6 R R R 2,2 2,1 3,1 = Q (3.26d) + +

  2,0 P P P P

  2

  3

  2

  3 R R R 2,1 2,0 5,0

  • = (3.26e) P P P P

  

2

  5

  2

  5 Agora, eliminam-se os denominadores, de modo a isolar os termos R e R , obtendo-se o novo 1,x 2,x conjunto:

  (3.27a) E 3 = P

  1 P

  2 Q 3,1 + P

  2 R 1,2 + P

  1 R 2,2 R = P P Q + P R + P R (3.27b)

  1,2

  1

4 1,0

4 1,1 1 4,1 R = P R + P R (3.27c)

  1,1 6 1,0 1 6,0 R = P P Q + P R + P R (3.27d)

  2,2

  2

3 2,0

3 2,1 2 3,1 R = P R + P R (3.27e)

  2,1 5 2,0 2 5,0

Substituindo o resto R da Eq. (3.27e) na Eq. (3.27d), o resto R da Eq. (3.27c) na Eq. (3.27b),

  2,1 1,1

o resto R da Eq. (3.27d) e o resto R da Eq. (3.27b) na Eq. (3.27a), pode-se rescrever E na

  2,2 1,2

  3 forma: E = P P Q + P P P Q + P P P R + P P P R

  3

  1 2 3,1

  1

  2 4 1,0

  

2

  4 6 1,0

  1

  2 4 6,0

  • P P R + P P P Q + P P P R + P P P R + P P R (3.28)

  1 2 4,1

  1

  2 3 2,0

  1

  3 5 2,0

  1

  2 3 5,0

  1 2 3,1 Que por sua vez, pode ser reorganizada na forma:

  Polinômio translinear encontrado z }| { E = (R P P P + R P P P )

  3 2,0

  1

  3 5 1,0

  2

  4

  6

  • (P P [Q + P (Q + R ) + P (Q + R ) + R + R ]) (3.29)

  1 2 3,1 4 1,0 6,0 3 2,0 5,0 3,1 4,1 | {z }

  Parte descartada

Assim, se a parte da Eq. (3.29) referente à “Parte Descartada” for zero, significa que a parte do

“Polinômio translinear encontrado” é um polinômio transinear válido. Entretanto, não é necessário

guardar nenhum outro resto ou quociente para calcular a “Parte descartada”. Basta apenas expan-

dir a parte “Polinômio translinear encontrado” e subtrair de E . Se o resultado for zero, implica

  3 que a “Parte descartada” também é zero, logo o polinômio translinear é válido. Assim, o procedimento de Verificação final apenas multiplica P por cada elemento da lista de x

polinômios ↵ , e soma a cada resultado de todos os elementos da lista ↵ multiplicados por P

y,n x,n y

e subtrai cada resultado de E r . Cada vez que esta subtração dá zero, o polinômio translinear é

guardado no vetor . Como exemplo, executa-se a verificação final nos resultados obtidos nas Eqs.

  (3.22) e (3.25). Esta rotina de verificação final faz parte do fluxografo da Fig. 3.5.

  1 ↵ 1,0 =[ , (5I in + 5I out + 3I ), (I out )]

  6

  1

↵ + 5I + I ), (I + I )]

2,0 in out in out

  =[− , (−I

6 Z = (P ↵ + P ↵ )

  1 2,0 2 1,0

  1 (6I in + 5I out + 6I in + 5I out + I )(I in + I out ) Z = − )(−I

  6

  1

  • (5I + 5I + 4I )(5I + 5I + 3I )(y)

  in out in out

  6

  3

  2

  2

  2 Z = I in + I in I out I in + I I out − I K = E

  3 − Z

  3

  2

  2

  2

  3

  2

  2

  2 K = (I in + I in I out I in + I I out in + I in I out I in + I I out ) − I − I ) − (I

  K = 0 Assim, (P ↵ + P ↵ ) é um polinômio translinear válido da Eq. (2.21), e deve ser gravado 1 2,0 2 1,0

  

3.3.4 Divisão recursiva por pares de polinômios-base, versão otimizada para

minimizar a memória utilizada Pra que o algoritmo apresentado na seção 3.3.2 acima fique seguro em relação ao tamanho de

memória utilizado, e que o fundamento de que encontrar os polinômios-base relativos a P e P são

  1

  2

problemas separados seja mantido, a cada decomposição parcial que seria inserida na lista ↵ x,n ,

todos as decomposições parciais que seriam colocadas na ↵ y,n são geradas novamente, o que torna

o número de expansões em frações parciais executadas muito maior. Assim o algoritmo da seção

anterior é re-implementado na forma do fluxografo da Fig. 3.7. Esta versão do algoritmo executa

o sub-algoritmo de “decomposição parcial primária”, dado pela Fig. 3.8, que por sua vez executa

o sub-algoritmo “decomposição parcial secundária”, dado pela Fig. 3.9.

  Desta forma, para cada decomposição parcial , relativa a P encontrada, todas as decompo- x x

sições parciais y relativas a P y são calculadas, e o procedimento de verificação final é realizado

a cada y encontrado, na forma da Eq. (3.30). Como não há criação de listas, não há risco de

utilização descontrolada da memória do computador.

  E + P ) = 0 (3.30) r x y y x

  − (P

  

Figura 3.7: Divisão por pares de Polinômios-base e execução de decomposições primárias, versão

otimizada para minimizar a memória utilizada. Os índices ‘i’ e ‘j’ são utilizados para percorrer o

vetor e gerar pares de polinômios-base.

  2

3.4 Novo Algoritmo de decomposição não-paramétrica

  O algoritmo apresentado nesta seção é uma modificação do apresentado na seção 3.3, e é o foco

desta dissertação. Assim como no algoritmo de Mulder et. al. [23], este trabalho tem por objetivo

encontrar um ou mais polinômios translineares na forma da Eq.(2.6) para um dado polinômio

  4

modo-corrente utilizando o processo de decomposição não-paramétrica. A principal mudança

introduzida por este trabalho é a tentativa de obter mais soluções que o algoritmo de Mulder et.

al., e secundariamente, tentar evitar o aumento de computações, ou seja, uma perda de eficiência

4 Transformado a partir de um polinômio adimensional, através dos métodos apresentados nas seções, 2.4.2 e

  2.6.1

  

Figura 3.8: Sub-rotina de geração de decomposições primarias . O índice ‘i’ é utilizado para

x percorrer o vetor .

  2

em relação ao algoritmo original. Este algoritmo tem as mesmas etapas estruturais do outro,

como pode ser visto na Fig. 3.2, entretanto, adicionou-se a etapa de Eliminação de polinômios

translineares repetidos. A Fig. 3.10 mostra a estrutura deste Algoritmo, e cada etapa é descrita

nas seções deste capítulo.

  

Figura 3.9: Sub-rotina de geração de decomposições secundarias y . O índice ‘i’ é utilizado para

percorrer o vetor .

2 Deste ponto em diante, o termo “algoritmo” refere-se ao algoritmo desenvolvido neste trabalho, e o termo “algoritmo original” refere-se ao algoritmo de Mulder et. al..

  

Figura 3.10: Estrutura do novo algoritmo de decomposição não-paramétrica

3.4.1 Geração do Vetor de Polinômios-Base

  O algoritmo utiliza o vetor de polinômios-base , definido pela Eq. (2.13), mas este recebe o

nome ⌧ nesta seção (⌧ = ). As etapas de redução do vetor ⌧ executadas pelo algoritmo podem

ser vistas na Fig. 3.11. A etapa de “Eliminação de polinômios-base estritamente negativos” gera o

vetor ⌧ a partir do vetor ⌧ ; a etapa de “Eliminação de polinômios-base redundantes” gera o vetor

  1

⌧ a partir do vetor ⌧ ; a etapa de “Divisão portares de polinômios base e expansão em frações

  2

  1

parciais” gera o vetor ⌧ a partir do vetor ⌧ ; e a etapa de “Re-contagem de polinômios-base” gera

  3

  2 o vetor ⌧ a partir do vetor ⌧ .Cada etapa é descrita nas subseções a seguir.

  4

3 Figura 3.11: Geração do Vetor de Polinômios-Base

  

3.4.1.1 Eliminação da etapa de divisão por um Polinômio-Base e Fatoração do resto

Apesar da etapa de “Divisão por um polinômo-base e fatoração do resto”, apresentada na seção

3.3.1.2, ser efetiva na redução do vetor de polinômios-base, o autor do algoritmo original não

especificou qual algoritmo de fatoração polinomial multivariável foi utilizado, e o desenvolvimento

destes algoritmos é uma área muito ampla, com muitos trabalhos acadêmicos, praticamente um

ramo da matemática simbólica em si. Não há um algoritmo definitivo e absoluto que resolva este

problema [42–47].

  Assim, como a fatoração polinomial é um passo desejável, mas não necessário para se obter

todas os polinômios translineares de um polinômio modo-corrente de entrada, e como o objetivo

deste trabalho é encontrar o máximo número de polinômios translineares possível, decidiu-se evitar

o risco de ter um polinômio-base adequado excluído por uma fatoração plinomial inadequada, e

preferiu-se deixar a escolha de um algoritmo de fatoração adequado, bem como sua implementação

ou integração, como propostas para trabalhos futuros.

  3.4.1.2 Eliminação de Polinômios-Base Estritamente Negativos

O argumento de que a faixa de variação de todas as variáveis de corrente devem ser conhecidas

previamente, como visto na seção 3.3.1.1, nem sempre se aplica. Pode ser que uma restrição de tamanho de circuito, por exemplo, seja mais importante que a faixa de operação das respectivas correntes; ou pode ser que seja mais importante que haja pelo menos um polinômio translinear equivalente, e que os limites das correntes possam ser definidos em função do polinômio translinear encontrado, e não o contrário. Esta abordagem oferece ao projetista mais flexibilidade e maior probabilidade de encontrar um polinômio translinear realizável para seu projeto.

  

Esta modificação também proporciona que este algoritmo possa ser utilizado para encontrar os

polinômios translineares do conjunto de polinômios modo-corrente gerados por uma decomposição paramétrica, tornando-o mais poderoso em relação ao algoritmo original.

  Figura 3.12: Algoritmo de eliminação de polinômios-base estritamente negativos. O índice “i” é utilizado para percorrer o vetor ⌧ Portanto, diferentemente do método apresentado na seção 3.3.1, escolheu-se eliminar os polinômios- base estritamente negativos ao invés de manter apenas os estritamente positivos, constituindo as- sim, o vetor reduzido ⌧ . O algoritmo que realiza esta operação pode ser visto na Figura 3.12. O

  1 número de polinômios-base excluídos por este procedimento é determinístico, dado pelo número de v coeficientes negativos mais um, devido ao zero, elevado ao número de variáveis, ou seja, (N + 1) . Subtraindo este número de N , o número de elementos de ⌧ , N 1 é dado pela Eq. (3.31).

  τ 1 τ v N τ 1 = N τ

  (3.31) − (N + 1) Como exemplo, aplicando esta redução ao conjunto ⌧ dado pela Tabela 2.1, obtém-se o con-

  2

  2 junto ⌧ mostrado na Tabela 3.1, cujo número de elementos é N 1 = (3) = 5, exatamente

  1 τ

  − (2) o número de elementos, todos estritamente não-negativos, na tabela.

Tabela 3.1: Exemplo de eliminação de Polinômis-Base estritamente negativos

x y PB

  1 −1 (−x + y) 1 (y)

  1 −1 (x − y)

1 (x)

  1 1 (x + y) Para que haja ainda uma maior flexibilidade nos polinômios translineares que deseja-se en-

contrar, permite-se definir diferentes limites superiores e inferiores para os coeficientes, na forma

inf , . . . , +N sup

[−N ] ao invés de usar coeficientes entre [−N, . . . , +N], como visto na seção 2.5.

  Assim, os cálculos de N τ e N τ 1 podem ser re-escritos, respectivamente, nas Eqs. (3.32) e (3.33) v

  N τ = (N inf + N sup + 1) (3.32) v

  N 1 = N + 1) (3.33) τ τ inf

  − (N

3.4.1.3 Eliminação de Polinômios-Base Redundantes Suponha que para um polinômio qualquer, haja dois polinômios translineares dados pelas Eqs.

  (3.34) e (3.35).

  (3.34)

  1 P

  1 P

  3 P

  5

  2 P

  2 P

  4 P 6 = 0 − P P P P P P = 0 (3.35)

  1

  1

  3 7 −

  2

  2

  4

  8 Se P = k P , e P = k P , k e k constantes, então o polinômio translinear dado pela Eq. (3.35)

  7

  1

  5

  8

  2

  6

  1

  2

pode ser rescrito na Eq. (3.36), que é composta pelos mesmos polinômios-base que a Eq. (3.34),

portanto os polinômios translineares são equivalentes do ponto de vista do algoritmo. k P P P P P P = 0 (3.36)

  1 1

  1

  3

5 − k 2 2

  2

  4

  6 Assim, se houver um ou mais polinômios-base que sejam combinação linear de outro qualquer,

basta que apenas um deles faça parte do vetor de polinômios-base para que todos os polinômios

  

Figura 3.13: Algoritmo de eliminação de polinômios-base (PB) redundantes. O índice “i” refere-se

a um polinômio-base de ⌧ que será dividido por outro de índice “j” do mesmo vetor.

  1

translineares sejam encontrados. Para remover estes polinômios-base, faz-se uma divisão simples

entre todos os polinômios-base do vetor ⌧ , removendo um deles quando o quociente da divisão é

  1

uma constante e o resto é zero. A decisão entre remover o polinômio dividendo ou o polinômio

divisor depende da constante encontrada no quociente. Se o seu módulo é menor que 1, significa

que os coeficientes do divisor são maiores que os do dividendo, portanto elimina-se o polinômio-

base divisor. Caso contrário, elimina-se o polinômio-base do dividendo. Isso é feito para que os

polinômios-base utilizados tenham coeficientes menores, para melhorar a legibilidade dos resulta-

dos. Ao final do processo, o vetor de polinômios-base reduzido ⌧ é gerado. Este procedimento é

  2 ilustrado na Figura (3.13)

  3.4.1.4 Divisão por Pares de Polinômios-Base e Expansão em Frações Parciais Como visto na seção 3.3.2.1, a divisão do polinômio de entrada E r por um par de polinômios-

base, P x e P y , permite verificar se este par pode fazer parte de um polinômio translinear equivalente.

Entretanto, o autor impõe a condição de que os numeradores resultantes da expansão em frações

parciais, R e R x y devem ter grau r − 1 e serem fatoráveis em r − 1 fatores lineares. Como visto na

seção 3.4.1.1, utilizar este procedimento com um algoritmo de fatoração polinomial multivariável

inadequado pode causar a perda de polinômios-base que poderiam fazer parte de um polinômio

translinear válido. Todavia, decidiu-se excluir apenas este requisito de fatorabilidade dos restos,

dado pela Eq. (3.7), e o procedimento continua sendo válido para encontrar possíveis pares de

polinonômios-base que possam fazer parte de um polinômio translinear válido.

  Uma mudança fundamental deste algoritmo é utilizar esta etapa para construir um vetor de

pares de polinômios base, chamado ⌧ , onde cada elemento é um par de polinômios-base com seus

  3

respectivos restos gerados pela expansão em frações parciais bem sucedida. Este procedimento é

mostrado na Eq. (3.37), e o elemento do vetor ⌧ gerado é ((P x , R x ), (P y , R y )). Como os elementos

  3

deste vetor são os pontos de partida para encontrar as decomposições, chama-se o vetor ⌧ de

  3 “vetor sementes”.

  

E r R x R y

(3.37)

  • = Q +

    P x P y P x P y

    O fundamento deste procedimento é que, se um polinômio-base faz parte de um polinômio trans-

    linear, então ele necessariamente está associado a pelo menos um polinômio-base que faz parte de

    um mesmo polinômio translinear, opostamente conectado, dado pela Eq. (2.12). Assim, como os

    polinômios-base devem estar sempre associados a pelo menos um outro, é mais eficiente tratá-los

    aos pares dentro do algoritmo. Com isso, a afirmação feita pelo autor original na seção 3.3.2.2

    de que encontrar os polinômios opostamente conectados a P e P são problemas separados leva

  x y

apenas a uma possível perda de eficiência, calculando de forma desnecessária decomposições par-

ciais que com certeza não formarão um polinômio translinear válido, pois fundamentalmente, os

problemas não são independentes.

  Relembrando que P , Q , e R são respectivamente: Polinômios-base, Quocientes, e Restos x,n x,n x,n

de índice x e grau n, o processo de divisão recursiva mostrado na seção 3.3.2.2 pode ganhar eficiência

se, a cada etapa recursiva, um dado resto R x,n for dividido por P x P , e R y,n for dividido por P y P ,

  1

  2

como mostrado nas Eqs. (3.38) a (3.39), apenas se houver um elemento ((P , R ), (P , R ))

  1 1,n 2 2,n pertencente a ⌧ .

3 R x,r R x,r R

  1 2 1,r 2 (3.38) = Q + + x,r

2 P x P P x P

  1

  1 R y,r R y,r R

  1 2 2,r 2 (3.39)

  2 + = Q + y,r

P y P P y P

  2

  2 Este processo divide E por todos os possíveis pares de polinômios-base do vetor ⌧ para gerar r

  2 o vetor de pares ⌧ , e este procedimento é ilustrado na Fig. 3.14

3 Como exemplo, é utilizado um vetor de polinômios-base ⌧ , gerado a partir dos procedimentos

  2

anteriores para o polinômio de entrada E dado pelo lado esquerdo da Eq. (2.21). Este vetor r Figura 3.14: Algoritmo de geração do vetor ⌧

  3 de pares de polinômios-base (PB). O índice “i” refere-se a um polinômio-base de ⌧

  6 I + I in + I out ⌧

  1,2 , R

  2 ), (R

  1 , P

  3 : ((P

  2 é mostrado na Tabela 3.3. São mostra- dos exemplos da obtenção dos dois primeiros elementos deste vetor ⌧

  3 gerado a partir deste vetor ⌧

  2 é mostrado na Tabela 3.2, e alguns polinômios-base gerados foram excluídos para melhorar a legibilidade. O vetor ⌧

  5 I out P

  2 que, junto outro de índice “j” do mesmo vetor, dividirão o polinômio modo-corrente E r .

  4 I in P

  3 I out P

  P

  2 I − I in

  1 I + I in P

  2

elemento polinômio

P

  

Tabela 3.2: Exemplo de vetor ⌧

  2,2 )), e

  ((P , P ), (R , R ))nas Eqs. (3.40) e (3.41).

  1 4 1,2 4,2

  3

  2

  2

  2 E r = I in + I in

I out

I in + I I out − I Fazendo para ((P , P ), (R , R )):

  1 2 1,2 2,2 E r R 1,2 R 2,2

  • = Q

  3,1 P P P P

  1

  

2

  1

  2

  3

  2

  2

2 I + I

  I I + I

  I I

  I I

  I

in in out in out out out

  − I = Q (3.40) + + 3,1

  (I + I in )(I in ) (I + I in ) (I in ) − I − I obtém-se o primeiro elemento da Tabela 3.3: (((I + I in ), (I in )), (I I out , I I out )).

  − I Fazendo agora para ((P , P ), (R , R )): 1 4 1,2 4,2

  E r R R 1,2 4,2

  • = Q

  3,1 P P P P

  

1

  4

  1

  4

  3

  2

  2

  2

  2 I in + I in I out I in + I I out

  I I out

  I − I = Q (3.41) + +

  3,1 (I + I in )I in (I + I in ) I in

  2 obtém-se o segundo elemento da Tabela 3.3: (((I

  • I in ), (I in )), (I I out , I )).

  Apesar de aparecer Q e R em ambos exemplos, não há problema, pois os índices são 3,1 1,2 particulares de cada elemento de ⌧ gerado.

  3

  3.4.1.5 Recontagem de polinômios-Base O processo de construção do vetor ⌧ compensa, de certa forma, a ausência do processo de

  3

fatoração do resto da divisão por um polinômio-base. Após constituído, o vetor ⌧ é percorrido, e

  3

cada polinômio-base que faz parte de algum elemento é copiado no vetor ⌧ . Assim, os polinômios

  4

base de ⌧ que com certeza não fazem parte de polinômio translinear algum são eliminados pelo

  2

processo de construção do vetor ⌧ . Este vetor de polinômios-base reduzido é utilizado para

  3 comparação entre algoritmos, e o seu procedimento de construção é mostrado na Fig. 3.15

3.4.2 Divisão Recursiva por Pares de Polinômios-Base e verificação final

  Baseado na premissa de que polinômios-base devem ser tratados aos pares, modificou-se o pro-

cedimento da seção 3.3.2.2. Ao invés de criar listas ↵ x,n independentes para depois testar se a

combinação entre seus conjuntos formam um polinômio translinear válido, constrói-se simulta-

neamente as os conjuntos de P x e P y a partir de um elemento ((P x , R x ), (P y , R y )) de ⌧ . Assim,

  3 estes conjuntos são chamados aqui de e . x y

  Estes conjuntos x e y são construídos fazendo-se a divisão recursiva dos polinômios do ele-

mento ((P x , R x ), (P y , R y )) com os polinômios-base de outros elementos de ⌧ . Caso uma das

  3

divisões (e fatoração do resto) simultâneas venha a falhar, a divisão é refeita invertendo os

polinômios-base do elemento testado. Por exemplo, considere os elementos de ⌧

  3 ((P 1 , R 1 ), (P 2 , R 2 ))

e ((P , R ), (P , R )). Realizando o procedimento de divisão e fatoração do resto simultâneos,

  3

  3

  4

  4

  • I
  • 2I

  6 I + I in + I out −I in

  4 (3.42) R

  4b,2 P

  1

  1a,2 P

  4 = Q +

R

  1 P

  1,2 P

  2 obtém-se: R

  2

  2 P

  2 P

  5 I I in

  2 P

  5 I I in

  2 P

  I

  4 I in

  2 P

  2

  6 I + I in + I out −I in

  2 P

  2,2 P

  3 = Q +

R

  3 I out I in

  1 P

  2

  P

  4 = Q + R 2,1

  2 P

  P

  3 (3.44) R 2,2

  1

  P

  3 = Q + R 1,1

  P

  2,1 P

  4 , conforme as equações abaixo: R 1,2

  2

com P

  3 e P

  1 com P

  1,2 , a divisão simultânea falhou, então deve-se testar a divisão combinando P

  4b,2 possuem o mesmo grau de R

  1a,2 e R

  3 (3.43) Como R

  3,1 P

  2

  2 − I

  2 P

  4 (3.45)

Neste caso, as Eqs. (3.44) e (3.45) mostram um procedimento de divisão e expansão em frações

parciais bem-sucedido. Ao final do processo recursivo, aplica-se o procedimento de “Verificação

  1 I + I in

  2

  

out

−I in

  6 I + I in

  I I out P

  1 I + I in

  2 P

  I

  4 I in

  I I out P

  I I out P

  2 P

  2 I − I in

  P

  I I out

  1 I + I in

  2 P

  2 de ⌧ 3 P y R y,

  R x,

  2 reduzido elemento P x

  3 gerado a partir de vetor ⌧

  Tabela 3.3: Vetor ⌧

  out I + I

  2 I − I in

  2

  2 P

  6 I + I in + I out −I in

  2 P

  5 I I in

  2 P

  I

  4 I in

  2 P

  2 − I

  3 I out I in

  5 I I in

  I I out P

  I I out P

  2 I − I in

  I I out P

  4 I x

  2I I out P

  2 I − I in

  2 P

  2 − I

  I in

  3 I out

  • 2I out I + I
  • 2I out I + I
  • 2I out I + I
  • R
  • R
  • R 3,1 P
  • R 4,1 P

  

Figura 3.15: Algoritmo de geração do vetor ⌧ de polinômios-base (PB). O índice “i” refere-se a

  4 um elemento do vetor ⌧

3 Final” descrito na seção 3.3.3 aos conjuntos x e y gerados, reduzindo este procedimento a um

  

único teste dado pelo conjunto da Eq. (3.46), considerando que E r foi o polinômio modo-corrente

utilizado para gerar o vetor ⌧ :

  3 (3.46a) Z = (P x y + P y x )

  K = E r (3.46b) − Z

  Se K = 0; então P x y + P y x é um polinômio translinear válido de E r (3.46c)

Como exemplo, este algoritmo é executado nas Eqs.(3.47)-(3.50), com o polinômio de entrada

E r sendo o lado esquerdo da Eq. (2.21), e seu respectivo o vetor reduzido ⌧ é mostrado na

  3 Tabela 3.4. Este vetor reduzido foi retirado da Tabela 3.3 para uma melhor legibilidade. Tomando ((P , R ), (P , R )) como par inicial, os conjuntos e contém apenas os restos iniciais R

  1 1,2 2 2,2

  1 2 1,2 e R :

  2,2 = [I I out ]

  1 = [I I out ]

  2 Combinando ((P , R ), (P , R )) com ((P , R ), (P , R )) obtém-se: 1 1,2 2 2,2 4 4,2 3 3,2

  

R R R

1,2 1,1 4,1

  = Q + +

P P P P

  1

  4

  1

  4 I I out out I out −I =

  (3.47) + (I + I in )I in (I + I in ) I in

  

Tabela 3.4: Vetor reduzido ⌧

  3 elemento P R x x,

  2 de ⌧ 3 P y R y,

  2 P I + I

  I I 1 in out

  P

  I I out − I

  2 I in

  2

  2 P I out I in

  3 − I

  2 P

  I

  4 I in

  2 P

  I I in

  5

  2

  2 P

I + I + I + 2I

I + I 6 in out in out −I

  e, simultaneamente:

R R R

2,2 2,1 3,1

  • = Q +

    P P P P

  2

  3

  2

  3 I I out I in = 1 + (3.48) + (I in )I out (I in )

  I out − I − I

Como ambas divisões e expansões em frações parciais dos restos foram bem-sucedidas, adiciona-se

P a e P a , e substitui-se R e R por R e R , respectivamente:

  4

  1

  3 2 1,2 2,2 1,1 2,1

1 out ), (I in )]

= [(−I

= [(I in ), (I out )]

  2 Combinando ((P , R ), (P , R )) com ((P , R ), (P , R )) obtém-se: 1 1,1 2 2,1 6 6,2 5 5,2

  R R R 1,1 1,0 6,1

  • = Q + P

  1 P

  6 P

  1 P

  6 out 1 −I −1

  = (3.49) +

(I + I in )(I + I in + I out ) (I + I in ) (I + I in + I out )

e, simultaneamente: R R R

  2,1 2,0 5,1

  • = Q + P P P P

  2

  5

  2

  5 I in

  1 −1 (3.50) = 1 + +

  

(I in )I (I in )

  I

− I − I

Como ambas divisões e expansões em frações parciais dos restos foram bem-sucedidas, adiciona-se

a e P a , e substitui-se R e R por R e R , respectivamente: P

  6

  1

  5 2 1,1 2,1 1,0 2,0 in ), (I + I in + I out )]

  1 = [(−1), (I = [(1), (I out ), (I )]

2 Como os restos são constantes, = 1, e o processo recursivo é interrompido. O

  1

  

2

= −1, and

  

polinômio translinear encontrado é dado pela Eq. (3.51), e o único teste de verificação final fica:

  3

  2

  

2

  2 E r = I in + I in I out I in + I I out − I Z = (P + P )

  1 2 2 1 Z = (I + I in )I out I in )I in (I + I in + I out ) (3.51)

− (I − I

  K = E r

  − Z K = 0 Se o polinômio translinear é válido, os polinômios do conjunto x e y são ordenados segundo

seus índices dentro do vetor ⌧ . O polinômio translinear encontrado é testado na forma da seção

  4 3.5, e se não for redundante, é gravado no vetor .

  O diagrama deste algoritmo pode ser visto na Fig. 3.16

3.5 Eliminação de polinômios translineares redundantes

  Como o vetor ⌧ indica qual polinômio pode ser combinado com outro, ao encontrar os polinô-

  3

mios translineares a partir do vetor ⌧ da Tabela 3.3, certamente serão gerados três polinômios

  3 translineares equivalentes ao polinômio translinear dado pela Eq. (3.51): Z = P P P + P P P = (I + I in )I out

  I in )I in (I + I in + I out )

  1

  1

  3

  5

  2

  4

  6 − (I − I Z

  2 = P

  1 P

  3 P 5 + P

  4 P

  2 P 6 = (I + I in )I out I in (I in )(I + I in + I out ) − I − I Z = P P P + P P P = (I + I in )I out

  I + I in + I out )(I in )I in

  3

  1

  3

  5

  6

  2 4 − (I − I

E não seria possível detectar estas redundâncias de forma preemptiva a não ser comparando os

polinômios translineares encontrados com os já existentes no vetor . Desta forma, cada polinômio

translinear válido encontrado é comparado com todos os outros já gravados, e é descartado caso

um equivalente já exista. Assim, o vetor conterá apenas polinômios translineares únicos. O

diagrama deste procedimento pode ser visto na Fig. 3.17

  

Figura 3.16: Divisão Recursiva por Pares de Polinômios Simultâneos. T e T referem-se a elementos

i j

do vetor ⌧ , e “i” e “j” são índices utilizados para percorrer este vetor. Os índices “a” e “b” servem

  3

para diferenciar os polinômios-base e restos de T j dos polinômios-base e restos de T i , que utilizam

os índices “x” e “y”.

  

Figura 3.17: Eliminação de polinômios translineares redundantes. O índice “i” refere-se a um po-

linômio translinear do vetor . Subentende-se que e já incluem os seus respectivos polinômios

x y de origem.

  Capítulo 4 Procedimento de validação e comparação entre algoritmos

  4.1 Introdução Neste capítulo são apresentadas as formas de se avaliar o novo algoritmo quanto a eficácia e

eficiência, quando comparado ao algoritmo original, este último em suas versões otimizadas quanto

  

à tempo de execução e uso de memória. Ambos algoritmos foram implementados em linguagem

c

  

“C”, compilados e executados em um computador com processador Intel core i7, 8GB de memória

RAM. Não convém incluir o algoritmo de [25], descrito na seção 2.8.1, nestas análises comparativas,

pois não é um algoritmo de decomposição translinear. Os resultados da aplicação da metodologia

descrita neste capítulo são apresentados no Capítulo 5.

  4.2 Eficácia do algoritmo implementado A eficácia do algoritmo é a capacidade dele de encontrar todas os polinômios translineares inf , . . . , N sup ]. Assim, cada polinômio de entrada eleito dentro do intervalo de coeficientes [−N

para este teste é submetido a ambos algoritmos, e se os mesmos polinômios translineares forem

encontrados, então o algoritmo está validado até que alguém encontre algum polinômio de entrada

no qual o número de polinômios translineares encontrados seja diferente. Como o novo algoritmo

utiliza estratégias diferentes para gerar o vetor de polinômios-base em relação ao algoritmo origi-

nal, utiliza-se a estratégia de geração de polinômios-base do algoritmo original, ou seja o vetor ⌧

  4

da seção 3.4.1.5, junto com a estratégia de decomposição translinear não-paramétrica do algoritmo

original descrita na seção 3.3.2 para fazer esta comparação. Assim, ambas estratégias de combi-

nação devem gerar os mesmos polinômios translineares para um mesmo polinômio modo-corrente

de entrada. Como não implementou-se a função de fatoração de polinômios multivariáveis, não

há como utilizar a estratégia da seção 3.3.1 para comparar os resultados da decomposição de um

polinômio qualquer.

4.3 Medida de Eficiência entre algoritmos

  Como visto na seção 3.2, um algoritmo ineficiente poderia levar meses, ainda que utilizando

um computador poderoso, para encontrar polinômios translineares a partir de polinômios modo-

corrente relativamente simples. Assim, os dois algoritmos são comparados em relação ao tempo

gasto para encontrar todas os polinômios translineares e em relação ao número de operações de

expansão em frações parciais executadas, pois é a rotina mais intensamente executada em ambos

algoritmos e de maior consumo de ciclos de clock.

  Como os algoritmos não são determinísticos, é possível determinar apenas a quantidade de

expansões em frações parciais executadas no caso de nenhuma das expansões terem sucesso, ou

seja, apenas se nenhuma função é executada de forma recursiva. Para calcular o número N de

novo

expansões em frações parciais no pior caso para o algoritmo deste trabalho, utiliza-se o número N τ

  3

de elementos do vetor ⌧ . Como cada elemento é combinado com outro de duas formas diferentes,

  3

exceto quando um elemento combina com si próprio, o cálculo de N , utilizando a fórmula

original de arranjo com repetição, é dado pela Eq. (4.1)

  2 N novo = N τ 3 (4.1) Já no caso do algoritmo original, considerando a sua versão otimizada para menor tempo de

execução, como o número de elementos no vetor ⌧ indica quantas vezes a etapa de “divisão por

  3

um par de polinômios-base e expansão do resto em frações parciais”, mostrada na seção 3.3.2.1 é

executada, multiplica-se N τ

  3 pelo número de elementos do vetor reduzido ⌧ , N τ 4 , para encontrar

  4 o número de expansões em frações parciais executadas no pior caso N orig , dado pela Eq. (4.2).

  N orig = N τ

  3 N τ 4 (4.2)

  

4.3.1 Geração de vetores de polinômios extremamente reduzidos e nova me-

dida de eficiência Tendo sido gerados todos os polinômios translineares com qualquer um dos algoritmos, percorre-

se o vetor de polinômios translineares e copia-se em um vetor ⌧ todos os polinômios-base que de

  5

fato fizeram parte de algum polinômio translinear. Este procedimento está ilustrado na Fig. 4.1.

  Assim, pode-se fazer um novo teste de eficiência dos algoritmos de forma mais significativa com

este vetor extremamente reduzido, pois este vetor com certeza é igual ou menor que um vetor que

fosse submetido ao processo de “divisão por um polinômio-base e fatoração do resto” visto na seção

3.3.1.2. Um vetor ⌧ de pares de polinômios é gerado a partir de ⌧ , conforme o procedimento da

  6 5 seção 3.4.1.4.

  O novo algoritmo é re-executado tendo o vetor ⌧ como entrada e o algoritmo original é re-

  6

executado tendo o vetor ⌧ como entrada, e os resultados são novamente comparados quanto à

  5 eficiência e eficácia.

  

Figura 4.1: Geração do vetor de polinômios-base extremamente reduzido ⌧ . O índice “i” refere-se a

  5

um polinômio translinear dentro do vetor , e o índice “j” refere-se a um polinômio-base pertencente

ao polinômio translinear i .

4.4 Polinômios utilizados para testar o algoritmo

4.4.1 Polinômios aleatórios

  Para testar tanto a eficiência quanto a eficácia do algoritmo, são construídos polinômios de

entrada aleatórios, formados a partir de uma equação na forma da 2.12. Como a ferramenta

implementada realiza um pré-processamento do polinômio de entrada, expandindo-o, simplificando

e reordenando os monômios resultantes, o algoritmo deve encontrar pelo menos a equação de

entrada na forma em que foi passada à ferramenta.

  Assim, escolheu-se os polinômios da Tabela 4.1, buscando-se variar o grau r e o número de variáveis v. O valor dos coeficientes variou apenas entre [−1, . . . , +1] para simplificar a análise.

  

Tabela 4.1: Vetor de Polinômios de Entrada para avaliação dos algoritmos

índice grau r número de Polinômio variáveis v de entrada a

  5 3 x

  2 i

  4 4 x

  3 (−y + k + z) − (x − k)(x − y)(x + y − k)

  2 j

  5 2 x

  2 (x − y)

  3 − (x + y)

  2 y

  3 k

  

2

y

  2 (−y + z)z − y

  2 (x − y − z) − (y + z)

  2 (x − z)

  2 z l

  5

  4 (x − k)(x + y − z)(x − k − y + z)

  2 − y

  3 (x + k − z)

  2

  Além desta avaliação de funcionalidade, o argumento apresentado na seção 3.4.1.2, de que a

estratégia de redução do vetor de polinômios base deste algoritmo pode gerar um numero maior de

polinômios translineares, também é testado, para inclusive auxiliar no processo de decomposição

translinear paramétrica. Assim, a comparação no sentido de gerar mais polinômios translineares

é feita a partir de algumas realizações de circuitos translineares publicadas [26, 27, 48, 49], onde o

algoritmo desenvolvido é utilizado para encontrar os mesmos polinômios translineares a partir dos

polinômios modo-corrente de entrada utilizados nos referidos trabalhos.

  2 (y − z)

  4 3 (x + z)

  2

  2 e

  2 (x + y)x − (x − y)y b

  2

  3 (x + y − z)(x + z) − z

  2 c

  2

  4 (x − k)(x − y + z) − (k + z)(x + y − z) d

  3

  2 (x + y)

  2 (x − y) − xy

  3 3 x

  3 (y + x) h

  2 (x + y) − z

  2 (x − y) f

  3

  4 (x + k)(x − y)(k + z) − x

  2 (y + k − z) g

  4

  2 (−x + y)

  2 y

  2 − x

4.4.2 Realizações de circuitos Translineares publicados

  Capítulo 5 Resultados

  5.1 Introdução Neste capítulo são mostrados os resultados da aplicação dos procedimentos mostrados no ca- pítulo 4.

  5.2 Comparativo de esforço computacional entre algoritmos

algoritmos encontram todos os polinômios translineares bem como o número de operações de

expansões em frações parciais realizadas. Resultados de tempo de execução de zero segundos

indicam que o aplicativo levou menos que 1 segundo para concluir sua execução. Para o algoritmo

original, utiliza-se o vetor de polinômios-base ⌧ , e para o novo algoritmo utiliza-se o vetor de pares

  4 de polinômios-base ⌧

  3 . O resultados para os coeficientes [−1, . . . , +1] são mostrados na Tabela 5.1, sendo os melhores resultados destacados em negrito.

  Pode-se notar que o algoritmo original, em sua versão otimizada para menor tempo de execução

realizaria menos operações no pior caso para todos os polinômios de entrada. Entretanto, este não

é um indicador seguro para determinar qual algoritmo realizará a menor quantidade de expansões

em frações parciais e nem do tempo necessário para encontrar todos os polinômios translineares.

Exceto pelos resultados referentes ao polinômio de entrada “i”, o novo algoritmo executou em tempo

menor ou igual para os demais polinômios.

  Certamente, esta desconexão entre o número de operações de expansão em frações parciais

executadas e o tempo de execução refere-se ao fato de o procedimento de “Verificação Final” do

algoritmo original otimizado para menor tempo de execução, descrito na seção 3.3.3, efetua muitas

verificações ao combinar decomposições parciais da lista ↵ com as decomposições parciais da lista

x,n

  ↵

y,n , um comportamento de certa forma parecido com o do algoritmo trivial. Assim, nesta versão do

algoritmo original, o número de verificações pode ser tão grande que produz um impacto relevante

no tempo de execução. No entanto, demorar apenas alguns segundos de tempo de execução pode

  

Tabela 5.1: Comparativo de eficiência computacional entre algoritmos com coeficientes

[−1, . . . , +1]. tempo tempo tempo ops. ops. ops. E r N τ

  4 N τ

  3 N orig N novo original original novo original original novo (exec.) (mem.) (exec.) (mem.)

  4

  6 36 0s 0s 0s 66 120

  64 b

  24 a

  7

  12 84 144 0s 0s 0s 228 348 171 c 11 24 264 576 0s 0s 0s 920 1.430 687 d

  4

  6

  24 36 0s 0s 0s 174 381 261 e 11 30 330 900 0s 0s 0s 3.625 9.884 5.298 f 13 25 325 625 0s 0s 0s 2.207 3.970 1.112 g

  4

  6

  24 36 0s 1s 0s 354 906 695 h 13 27 351 729 3s 3s 1s 12.594 100.717 22.589 378 0s

  2.042 i 14 27 729 1s 1s 5.185 10.523 j

  4

  6

  24 36 0s 0s 0s 624 1.776 1510 k 12 30 360 900 5s 2s 1s 21.514 70.939 53.492

560 0s 19.149

l

  16 35 1.225 5s 3s 37.898 19.488

ser considerado um ótimo resultado para todos os algoritmos, de forma que a escolha entre um ou

outro é irrelevante para o intervalo de coeficientes [−1, . . . , +1].

  Procurando obter uma comparação mais significativa, repetiu-se o procedimento para o inter-

valo de coeficientes [−3, . . . , +3]. Os resultados para o algoritmo original em suas duas versões

utilizando o vetor ⌧ , e para o novo algoritmo utilizando ⌧ estão descritos na Tabela 5.2. Os

  4

  3

números N novo e N orig não são mostrados, pois este indicador mostrou-se irrelevante de acordo

com a análise feita nos parágrafos anteriores.

  

Os resultados da Tabela 5.2 mostram que não há uma relação direta entre os números N τ

3 e N τ 4 no tempo necessário para encontrar todas as soluções.

  Os resultados do algoritmo original, em sua versão otimizada para minimizar tempo de execu-

ção, para os polinômios “h”, “k”e “l”, não puderam ser obtidos porque o aplicativo, ao atingir cerca

de 3 GB de memória, foi finalizado pelo sistema operacional. Isso deve-se ao fato de que não há

como prever o quão grande as listas ↵ x,n e ↵ y,n podem ficar. Entretanto, tanto o novo algoritmo

quanto o algoritmo original em sua versão otimizada para minimizar memória ocupam memória

constante durante a execução das operações recursivas, de cerca de 3,6 MB.

  Pode-se verificar que o novo algoritmo supera o a versão otimizada para minimizar memória

do algoritmo original, tanto no aspecto do tempo de execução quanto no aspecto de número de

operações realizadas. É confirmada a afirmação feita na seção 3.4.1.4, de que polinômios-base que

fazem parte de um polinômio translinear sempre estão associados a outro, portanto é mais eficiente e seguro testá-los aos pares. Tabela 5.2: Comparativo de eficiência computacional entre algoritmos com coeficientes [−3, . . . , +3] E r

  N τ

4 N

  τ 3 tempo tempo tempo ops. ops. ops. original original novo original original novo

(exec.) (mem.) (exec.) (mem.)

a 16 120 1s 1s 1s 6.990 54.240 28.104 b

  2 como parâmetros, e a relação entre as funções k(I i , I ) e h(I i , I ) dada

  1 e I y

  

Em [49], um oscilador de segunda ordem é desenvolvido utilizando síntese translinear, e seu

esquemático pode ser visto na Fig. 5.1. Aplicando o método de decomposição paramétrica, utili- zando as correntes I y

  

Nesta seção, o novo algoritmo é aplicado em polinômios utilizados em realizações de circuitos

translineares já publicados, nos quais os autores omitem os detalhes do processo utilizado na obtenção dos polinômios translineares a partir de polinômios modo-corrente.

  

O resultado da Tabela 5.3 mostra o impacto que a redução no número de polinômios-base causa

na velocidade com que os algoritmos encontram todos os polinômios translineares. Assim, encontrar um algoritmo adequado de fatoração polinomial multivariável e implementá-lo no aplicativo é a principal proposta de trabalhos futuros.

  6 no novo algoritmo. Os resultados são descritos na Tabela 5.3.

  5 no algoritmo original em sua primeira versão e no trivial, e ⌧

  

Finalmente, para os coeficientes[−3, . . . , +3], efetua-se novamente a comparação utilizando

agora os vetores extremamente reduzidos de polinômios-base obtidos segundo o procedimento da seção 4.3.1, utilizando ⌧

  96 683 — 4h 45m

20m 43s

— 1.110.270.604 81.767.756

  16 120 1d 10h 1d 11h 1d 22h 1.742.102 355.320.098 464.949.583 54m 48s 9m 12s 53m 48s k 72 599 — 54m 8s 37m 12s — 322.719.203 221.858.419 l

  2.044.620 2.020.000 e 71 600 45s 81s 56s 498.303 9.751.122 6.703.563 f 73 520 14s 42s 6s 229.045 2.128.472 309.485 g 16 120 55m 37s 13m 20s 44m 15s 366.990 34.451.688 109.561.780

h 145 768 — 3h 9m 3s 2h 9m 47s — 58.156.468 39.980.584

i 77 539 53m 26s 14m 5s 1m 4s 163.054 54.381.588 4.005.024 j

  79 614 5s 21s 7s 405.606 605.514 181.740 d 16 120 55s 38s 36s 60.990

  49 353 2s 1s 1s 60.000 205.968 134.786 c

5.3 Aplicação do algoritmo desenvolvido em trabalhos publicados

5.3.1 Oscilador de segunda ordem

5 N τ

  1 = I

  2 , I ) (5.2b)

  1

  2

= −I

  1 (5.2a) I y

  I

  2 h(I 2 , I ) − I

  2 + I )I cap 2 = I

  1 , I ) (5.1b) (I

  

2

  2 (5.1a) I y

  

Tabela 5.3: Comparativo de eficiência computacional entre algoritmos com coeficientes [−3, . . . , +3]

e vetores de polinômios-base extremamente reduzidos E r N τ

  I

  2 h(I 1 , I ) + I

  

Figura 5.1: Circuito oscilador de segunda ordem [49]

(I 1 + I )I cap 1 = I

  80 995 572

pelas Eqs. (5.3) e (5.4), o autor parte dos conjuntos das Eqs. (5.1) e (5.2), e obtém os polinômios

translineares dados pelas Eqs. (5.5) e (5.6), utilizando um método manual não-especificado de [27].

  165 j 4 6 0s 0s 0s 624 1.880 1.510 k 6 13 0s 8s 0s 2.706 15.875 9.783 l 6 8 0s 0s 0s

  11 41 15s 11s 8s 21.329 319.204 242.546 i 5 6 0s 0s 0s 245 161

  88 g 5 10 0s 0s 0s 1.108 4.924 4.464 h

  9 24 0s 1s 0s 2.373 5.619 3.298 f 5

6 0s 0s 0s 193 171

  54.240 28.104 b 36 197 1s 1s 1s 28.280 88.410 44.367 c 67 464 4s 7s 4s 125.334 402.006 235.190 d 13 78 15s 10s 9s 26.076 581.178 541.817 e

  6 tempo tempo tempo ops. ops. ops. original original novo original original novo (exec.) (mem.) (exec.) (mem.) a 16 120 1s 1s 0s 6.990

  • I k(I
  • I k(I
  • h(I i , I ) (5.3) k(I i , I ) =

  • I
  • I )(I cap
  • I ) = 0 (5.5a) (I + I
  • I y
  • I )(I cap
  • I ) = 0 (5.6a) (I + I
  • I y
  • I )I cap
  • I

  • I )I cap
  • I
  • I
  • I y
  • I )(−I
  • I y
  • I y
  • I )(−I
  • I )(I + I cap
  • I y
  • I y
  • I y
  • I y
  • I y
  • I y
  • I y

  

1

) − I (−I cap

  1 (I + I cap

  I

  1 + I y 1 ) (5.9d)

  

1

) − I (−I

  1 + I )(I cap

  1 ) = 0 (5.9c) (I

  

1

) − I (I + I y

  1

  1 ) (5.9b) (I

  1 (−I

  1

  

1

) − I

  1

  1 − I cap

  1

  1 ) (5.9a) (I

  1 (I + I y

  

1

) − I

  1

  cap

  1

  1

  1 ) (5.9e)

  I

  

1

) − I cap

  1

  1 )(−I

  1

  

1

) − (−I cap

  1

  1 − I cap

  1 )(−I

  (5.9h) (I + I y

  1 (−I cap 1 + I y 1 )

  1 − I cap 1 + I y

  1 (I cap

  1 )(−I

  1 ) (5.9g) (I + I cap

  1 )(I cap

  

1

) − (I

  1

  1 )(−I

  1 ) (5.9f) (I + I cap

  1

  1 − I cap

  

1

) − I (−I

  2 = 0 (5.8b)

Como as Eqs. (5.7a) e (5.8a) são análogas, os polinômios translineares encontrados de uma delas

pode ser atribuída à outra, bastando apenas substituir os índices. Os polinômios translineares

obtidos com o novo algoritmo, utilizando o intervalo de coeficientes [−1, . . . , +1], são dados pelo

conjunto das Eqs. (5.9) (I

  G

  I I

  2 − I y

  2 )

  2

  2

  2 ) − (I

  1 ) = 0 (5.5b) I (I + I y

  2

  2 (I G − I

  1 )

  1

) − (I − I

  2 (I G + I

  1

  1 )

  1

  1

  1 ) − (I

  2 i (5.4) I (I + I y

  

2

  

I

  2I G I i

  

I

  onde: k(I i , I ) =

I i

  2 (I G + I

  2

) − (I − I

  

1

) − 2I

  

2

G

  2

  2 )(I y

  2

  2

  2 ) = 0 (5.8a) (I

  2 − I

  

2 − I

(I y

  2

  1 = 0 (5.7b) (I

  I I

  1

  2 )

  2 )(I y

  2

  1 ) = 0 (5.7a) (I

  1 − I

  

1 − I

(I y

  1

  (I

  2 ) = 0 (5.6b)

Para mostrar que a estratégia de se eliminar polinômios-base estritamente negativos, mostrada na

seção 3.4.1.2, torna o algoritmo de decomposição não-paramétrica útil no auxílio da decomposição

paramétrica, primeiramente desenvolve-se as Eqs. (5.1) e (5.2) utilizando as relações dadas pelas

Eqs. (5.3) e (5.4) de forma a eliminar os fatores k(I i , I ) e h(I i , I ), e obtém-se o conjunto de

polinômios modo-corrente dados pelas Eqs. (5.7) e (5.8)

  1 − I y

  2 (I G − I

  1 ) (5.9i) Foram encontradas nove polinômios translineares, dentre eles a Eq. (5.9c), que é equivalente ao

polinômio translinear da Eq. (5.5a), encontrado manualmente pelo autor. Aplicando o algoritmo

no polinômio dado pela Eq. (5.7b), novamente utilizando o intervalo de coeficientes [−1, . . . , +1],

obtém-se os polinômios translineares dados pelo conjunto da Eq. (5.10)

  2 (I + I ) + I I + I ) (5.10a)

  1 y

  1

  2 1 y

  1

  2 G (−I ) − 2I (−I − I

  2

  2 (5.10b)

(I + I ) y + I + I G y + I G )(I )

  1

  1

  2 1 − I 2 − I

  1 (−I ) − (I

  2

  2I I y + I + I G y )(I ) (5.10c)

  1

  1

  2 1 − I 2 − I

  1 (−I ) − (I Foram encontrados três polinômios translineares, e a Eq.(5.10b) é equivalente à Eq. (5.5b).

  

Aplicando o algoritmo no polinômio dado pela Eq. (5.8b), obtém-se polinômios translineares dados

pelo conjunto da Eq. (5.11).

  2 (I + I ) (I + I y I (I + I y + I G ) (5.11a)

  2

  1

  2

  2

  1

  2 ) − 2I

  2

  2 (I + I ) y + I G + I y + I G )(I ) (5.11b)

  2 1 − I

  2

  1 2 − I

  2 (−I ) − (I

  2

  2I I y + I + I y )(I ) (5.11c)

  2

  1

2 G

  1

  2

  2

(−I − I ) − (I − I

Novamente, foram encontrados três polinômios translineares, mas nenhum deles é equivalente

ao polinômio translinear encontrado pelo autor dado pela Eq. (5.6b). Para investigar a razão de o

polinômio translinear do autor não ter sido encontrado pelo algoritmo, expandiu-se e simplificou-se

a Eq. (5.6b), e o resultado é dado pela Eq. (5.12)

  2

  2 (I + I )(I + I ) + 2I

  I I = 0 (5.12)

  2 Percebe-se que o sinal do termo 2I é diferente nas Eqs. (5.12) e (5.8b), enquanto que G

  I I

  2

deveriam ser iguais. Assim, pode-se deduzir que o autor cometeu um erro de sinal ao realizar

o procedimento de decomposição paramétrica de forma manual, e fica comprovado que o novo

algoritmo é eficaz no auxílio do procedimento de decomposição paramétrica, podendo prevenir

este tipo de erro.

5.3.2 Conversor RMS-DC

  Em [26], foi desenvolvido um circuito translinear de conversão RMS-DC. A síntese deste circuito

foi utilizada no exemplo da seção 2.7. Entretanto, para verificar a eficácia do algoritmo, ele é

aplicado à Eq. (5.13a) com coeficientes [−1, . . . , +1], e os polinômios translineares gerados são

mostradas no conjunto da Eq.(5.13)

  2

  2

  2 I I + I

  I I (5.13a) cap out out − I in

  2 (5.13b) I cap

  I cap + I )(I out + I in )(I in out ) in − (I − I

  2

  2 I I cap + I )I = 0 (5.13c) in − (I out

  2 I cap I (I out + I in )(I in out ) (5.13d)

out − I − I

Assim, o polinômio translinear da Eq. (5.13a) é equivalente ao da Eq.(5.13c), e demonstra-se que

mais opções de polinômios translineares são obtidas.

5.3.3 Circuito da função Módulo

  2 (5.14c) I x (I y + I x

  Em [27], é desenvolvido um circuito translinear que realiza a função módulo. Este circuito

também foi utilizado na seção 2.7.1 como exemplo de síntese de circuitos translineares. Aplicando

o algoritmo desenvolvido na função módulo escolhida dada pela Eq. (5.14a), e utilizando o intervalo

de coeficientes [−1, . . . , +1], os polinômios translineares gerados são dados pelo conjunto das Eq.

(5.14):

  I

  

2

y − I 2 x

  (5.14a)

  2I x (−I y + I x

  ) − (−I y + I x )

  2 (5.14b)

  2I x

  (I y

  • I
  • I
  • I
  • I
  • I + I
  • I
  • I

  x )

  • I x )(I − I
  • I
  • I
  • I )(−I
  • I
  • I
  • I )(−I
  • I
  • I
O polinômio modo-corrente dado pela Eq. (5.15e) é o mesmo da Eq. (2.65), encontrado durante

a síntese do circuito, mostrando assim, a eficácia do algoritmo desenvolvido em automatizar o

processo de decomposição translinear.

  (5.15k)

  − I x ) (5.15h)

  (I y + I x )(−I y + I

  

) − (I

y + I x )(I

  − I x ) (5.15i)

  (I + I x

  )(−I y

  x

) − (−I

y

  y

  x ) (5.15j)

  I (−I y + I x

  

) − (−I

y + I

  − I x

  )(−I y + I x )

  2I x (−I y + I x

  

) − I

(I y + I x ) (5.15g) I (I y + I x

  

) − (−I

y + I x )

  2 (5.15l)

  2I x (I y + I x

) − (I

y + I x )

  2 (5.15m)

  I x

  (I y

  x

) − I

y

  (I y

  x ) (5.15n)

  I

  2

y − I

2 x

  (5.15o) I y (−I y + I x

  

) − I

x (I y

  − I x ) (5.15p)

  

) − (I

y + I x )(I y + I

  )(−I y + I + I x

  x ) − (I y

  2

− I

  ) − I y (I y + I x ) (5.14d)

  I

  

2

y − I 2 x

  (5.14e) I y (−I y + I x )I x (I y

  − I x ) (5.14f)

  Como I x pode assumir valores negativos, e I y

  = |I x

  |, os polinômios-base I x

  , (I y

  x ), e (−I y + I x ) não são estritamente positivos, podendo ser constantemente zero, logo nenhum dos

polinômios translineares da Eq. (5.14) são válidos. Utilizando um artifício de somar e subtrair um

termo constante I

  2 à Eq. (5.14a), o polinômio mantém a sua funcionalidade e a homogeneidade,

mas a presença nova variável pode produzir novos polinômios translineares. Aplicando o algo-

ritmo desenvolvido à Eq. (5.15a), novamente urilizando o intervalo de coeficientes [−1, . . . , +1], os

polinômios translineares obtidos são dados pelo conjunto da Eq. (5.15):

  I

  2 y − I

  2 x

  x ) (5.15f) (I y + I x

  2 (5.15a) (I y

  x )(−I y

  x ) − I (−I y

  x ) (5.15b) (I y + I + I x

  )(−I y + I x

  

) − (−I

y + I

  − I x

  )(−I y + I x )

  (5.15c) (I y + I )(I y + I x

) − (I

y + I x )(I + I x ) (5.15d)

  (I + I y )(I − I y

  x ) (5.15e) (I y

  y

  x ) − (I − I x

  )(−I y

  

) − (I

5.3.4 Circuito de Seno

  Em [48], o autor implementa uma função que aproxima o valor do seno do sinal de entrada

de forma estática. O polinômio modo-corrente relativo a esta função matemática, dado pela Eq.

(2.21), foi desenvolvido na seção 2.4.2, e é repetido aqui na Eq. (5.16). O polinômio translinear

encontrado pelo autor é dado pela Eq. (5.17):

  3

  2

  2

  2 I x + I x I y I x + I I y (5.16)

− I

  2

  2 (5.17)

(I + I x ) (I x y x ) (I + I x + I y )

  − I − I − I

) − (I

Aplicando o novo algoritmo à Eq. (5.16) com coeficientes [−1, . . . , +1], encontrou-se nove polinô-

mios translineares, dados pelo conjunto da Eq. (5.18).

  2 (5.18a) I y (I x + I y + I x + I y )(I x y )(I x y )

  − I − I − I ) − (I

  2 (I + I x ) (I x + I y I x (I + I x + I y ) (5.18b) ) − 2I

  2

  2 (I + I x ) (I x y x ) (I + I x + I y ) (5.18c) − I − I − I

  ) − (I

  I I y (I + I x x (I x )(I + I x + I y ) (5.18d) − I ) − I

  2 (I ) (I + I I (I ) (5.18e) x x y x x y

  − I ) − 2I − I − I

  2

  2 (5.18f) I (I x + I y (I x y ) x − I

  ) − I

  2

  2I y I + I x )(I x )(I + I y ) (5.18g) − (I − I

  I I y (I x x (I + I x )(I x y ) (5.18h) − I − I − I ) − I

  2

  2I I )(I + I )(I ) (5.18i) y x y x x x − (I − I − I

  A Eq. (5.18c) é idêntica à Eq. (5.17), o que significa que o algoritmo novamente funcionou

corretamente. Se a corrente I x é restrita ao intervalo 0 < I x < I , então I y é sempre positiva e

. Assim, qualquer polinômio translinear do conjunto da Eq. (5.18) é implementável em uma I y < I x

malha translinear válida, especialmente a Eq. (5.18f), que usa a menor quantidade de espelhos de

corrente, resultando em um design mais compacto, e seu esquemático pode ser visto na Fig. 5.2.

Este circuito foi simulado com V = 1V , emo I = 10nA, onde M , M e M implementam os

dd

  1

  3

  5

  2

  2 polinômios I , M e M implementam os polinômios I (I x + I y ), e M

  2

  4 6 (I x y ). x

  − I Todos os terminais de corpo são conectados com os terminais de fonte para eliminar o efeito de

corpo. As fontes de corrente foram implementadas com espelhos de corrente simples em inversão

forte, utilizando um total de 18 transistores, ao invés de 31 utilizados na implementação em [48]. O

resultado da simulação é mostrado nos gráficos da Figura 5.3, no qual a linha pontilhada representa

a saída do circuito e a linha sólida representa o resposta ideal dada pela Eq. (5.16). A diferença

mínima entre as curvas dentro do intervalo válido de 0 < I x < 10nA mostra o quão preciso

o processamento de sinais por meio de circuitos translineares pode ser, mesmo com tensões e

correntes muito baixas.

  

Figura 5.2: Circuito Seno compacto

4#

  Iy#(nA)# 3#

  Output# Ideal# 2# 1#

  Ix#(nA)# 0# 0# 2# 4# 6# 8# 10# 12# 14#

  

Figura 5.3: Saída do circuito Seno e seu valor ideal Entretanto, nem toda tecnologia CMOS implementa transistores tipo “N” com substrato iso-

lado. Nestes casos pode-se tentar implementar o circuito utilizando transistores tipo “p”, ou então utilizar técnicas de minimização do efeito de corpo [50]. Capítulo 6 Conclusões

  Neste trabalho, foi realizado um estudo detalhado a respeito de circuitos translineares e as

metodologias de sínteses destes circuitos disponíveis na literatura. Foi realizado uma análise do

algoritmo de decomposição translinear não-paramétrica automatizada de [23], e, baseado neste,

um novo algoritmo foi desenvolvido. Ambos algoritmos foram implementados em uma ferramenta

auto-contida utilizando linguagem de programação “C”, possibilitando a verificação da eficácia e

eficiência das implementações destes algoritmos. A implementação do novo algoritmo mostrou-se

ser mais eficiente em alguns casos e mais segura, por não apresentar riscos de utilização excessiva

da memória de aplicativos do computador. Foi implementada uma segunda versão do algoritmo

original otimizada para minimizar a memória utilizada, e esta implementação ficou menos eficiente

que a implementação do novo algoritmo em todos os casos de teste.

  O novo algoritmo também foi aplicado a realizações de circuitos translineares já publicados, o

que mostrou que esta ferramenta proporciona realizar a etapa de decomposição translinear de forma

automática, vencendo a barreira imposta pela necessidade de “criatividade algébrica” imposta pelos

métodos manuais. O novo algoritmo também mostrou-se mais eficaz, pois, para um determinado

polinômio modo-corrente, o novo algoritmo pode encontrar mais polinômios translineares que o

algoritmo original. O outro importante ganho em eficácia é que o novo algoritmo pode ser utilizado

no auxílio do procedimento de decomposição paramétrica, enquanto que o algoritmo original não

proporciona esta funcionalidade.

  O código fonte da ferramenta desenvolvida que implementa ambos algoritmos está disponível

  1

de forma gratuita sob a Licença Pública Geral GNU v.3 no anexo deste trabalho e em [51]. Esta

ferramenta é auto-contida, ou seja, não depende de pacotes de software proprietários para o seu

funcionamento, o que a torna bastante acessível.

1 GNU General Public License v.3

6.1 Proposta de Trabalhos Futuros A ferramenta foi implementada como um simples aplicativo de terminal de linha-de-comando.

  

Assim, o desenvolvimento de uma interface gráfica poderia tornar o seu uso mais conveniente.

Esta ferramenta também não explora a capacitade de multi-processamento dos processadores de

computadores pessoais atuais, que podem chegar a 8 núcleos. Dividir o processamento do vetor-

sementes ⌧ entre múltiplos processadores adicionaria um ganho fundamental em eficiência.

3 A respeito do novo algoritmo, ficou claro que a redução de polinômios-base do vetor ⌧ tem um

  2

impacto significativo em sua eficiência, portanto é desejável encontrar e implementar um algoritmo

adequado de fatoração polinomial muiltivariável para a ferramenta. A recente implementação

gratuita encontrada em [47] parece ser uma boa candidata.

  Pode-se investigar também, uma versão do algoritmo em que se possa utilizar coeficientes fra-

cionários de forma eficiente. O desenvolvimento de um algoritmo deste tipo poderia eliminar a

necessidade de decomposições paramétricas, pois sempre existe pelo menos um polinômio transli-

near de um polinômio modo-corrente se todos os coeficientes do conjunto dos números racionais Q

puderem ser utilizados.

  Finalmente, a ferramenta pode ser aplicada a sistemas de processamento de sinais conhecidos

que tenham restrições severas de nível de tensão de alimentação e de consumo de potência, de

modo a tentar encontrar soluções utilizando circuitos translineares que atendam a estas restrições. REFERÊNCIAS BIBLIOGRÁFICAS

[1] ZHANG, Y. et al. A batteryless 19µw mics/ism-band energy harvesting body sensor node soc

for exg applications. Solid-State Circuits, IEEE Journal of, v. 48, n. 1, p. 199–213, Jan 2013.

ISSN 0018-9200.

  

[2] CABRERA, F. L.; SOUSA, F. R. de. Optimal design of energy efficient inductive links for

powering implanted devices. In: IEEE. Biomedical Wireless Technologies, Networks, and Sensing Systems (BioWireleSS), 2014 IEEE Topical Conference on. [S.l.], 2014. p. 37–39.

[3] TANG, S.; JOLESZ, F.; CLEMENT, G. A wireless batteryless deep-seated implantable ultra-

sonic pulser-receiver powered by magnetic coupling. Ultrasonics, Ferroelectrics and Frequency

  Control, IEEE Transactions on, v. 58, n. 6, p. 1211–1221, June 2011. ISSN 0885-3010.

[4] ALI, M.; ALBASHA, L.; AL-NASHASH, H. A bluetooth low energy implantable glucose mo-

nitoring system. In: Radar Conference (EuRAD), 2011 European. [S.l.: s.n.], 2011. p. 377–380.

  

[5] YANG, Z. et al. Wireless energy transmission using ultrasound for implantable devices. In:

Piezoelectricity, Acoustic Waves and Device Applications (SPAWDA), 2013 Symposium on. [S.l.: s.n.], 2013. p. 1–4.

[6] KILINC, E. et al. A system for wireless power transfer of micro-systems in-vivo implantable

in freely moving animals. Sensors Journal, IEEE, v. 14, n. 2, p. 522–531, Feb 2014. ISSN 1530-

  437X.

[7] SALAM, M. et al. An implantable closedloop asynchronous drug delivery system for the treat-

ment of refractory epilepsy. Neural Systems and Rehabilitation Engineering, IEEE Transactions on, v. 20, n. 4, p. 432–442, July 2012. ISSN 1534-4320.

[8] FANG, Q. et al. Developing a wireless implantable body sensor network in mics band. Infor-

mation Technology in Biomedicine, IEEE Transactions on, v. 15, n. 4, p. 567–576, July 2011.

ISSN 1089-7771.

  

[9] YAKOVLEV, A.; KIM, S.; POON, A. Implantable biomedical devices: Wireless powering and

communication. Communications Magazine, IEEE, v. 50, n. 4, p. 152–159, April 2012. ISSN 0163-6804.

[10] MARNAT, L. et al. On-chip implantable antennas for wireless power and data transfer in a

glaucoma-monitoring soc. Antennas and Wireless Propagation Letters, IEEE, v. 11, p. 1671–

  1674, 2012. ISSN 1536-1225.

  

[11] HARB, A.; SAWAN, M. Low-power cmos implantable nerve signal analog processing circuit.

  In: Electronics, Circuits and Systems, 2000. ICECS 2000. The 7th IEEE International Confe- rence on. [S.l.: s.n.], 2000. v. 2, p. 911–914 vol.2.

[12] CROCE, R. et al. Low-power signal processing methodologies for implantable biosensing plat-

forms. In: Signal Processing in Medicine and Biology Symposium (SPMB), 2013 IEEE. [S.l.: s.n.], 2013. p. 1–5.

[13] FU, X. et al. A wireless implantable sensor network system for in vivo monitoring of physi-

ological signals. Information Technology in Biomedicine, IEEE Transactions on, v. 15, n. 4, p.

  577–584, July 2011. ISSN 1089-7771.

[14] NGUYEN, A.-T. et al. Miniaturization of package for an implantable heart monitoring device.

  In: Design, Test, Integration and Packaging of MEMS/MOEMS (DTIP), 2013 Symposium on. [S.l.: s.n.], 2013. p. 1–6.

  

[15] HADDAD, S. A.; SERDIJN, W. Ultra low-power biomedical signal processing: an analog

wavelet filter approach for pacemakers. [S.l.]: Springer, 2009. 4–9 p.

[16] PUNZENBERGER, M.; ENZ, C. Low-voltage companding current-mode integrators. In: Cir-

cuits and Systems, 1995. ISCAS ’95., 1995 IEEE International Symposium on. [S.l.: s.n.], 1995. v. 3, p. 2112–2115 vol.3.

[17] PYTHON, D.; ENZ, C. C. A micropower class-ab cmos log-domain filter for dect applications.

  Solid-State Circuits, IEEE Journal of, IEEE, v. 36, n. 7, p. 1067–1075, 2001.

[18] HADDAD, S. et al. An ultra low-power dynamic translinear cardiac sense amplifier for pa-

cemakers. In: Circuits and Systems, 2003. ISCAS ’03. Proceedings of the 2003 International

  Symposium on. [S.l.: s.n.], 2003. v. 5, p. V–37–V–40 vol.5.

[19] REDONDO, X.; SERRA-GRAELLS, F. 1 v compact class-ab cmos log filters. In: IEEE.

  Circuits and Systems, 2005. ISCAS 2005. IEEE International Symposium on. [S.l.], 2005. p. 2000–2003.

  

[20] HADDAD, S. A. P. et al. Ultra low-power analog morlet wavelet filter in 0.18 µm bicmos

technology. In: Solid-State Circuits Conference, 2005. ESSCIRC 2005. Proceedings of the 31st European. [S.l.: s.n.], 2005. p. 323–326.

[21] HADDAD, S. A.; SERDIJN, W. A. An ultra low-power class-ab sinh integrator. In: ACM.

  Proceedings of the 19th annual symposium on Integrated circuits and systems design. [S.l.], 2006. p. 74–79.

  

[22] FREY, D.; DRAKAKIS, E. Unifying perspective on log-domain filter synthesis. Electronics

letters, IET, v. 45, n. 17, p. 861–863, 2009.

[23] MULDER, J. et al. Dynamic translinear and log-domain circuits: analysis and synthesis. [S.l.]:

Springer, 1998. 74–104 p.

  

[24] ILSEN, D. Algebraische Aspekte der Synthese translinearer Netzwerke. Tese (Doutorado) —

Diploma Thesis, Universität Kaiserslautern, 2002.

[25] ILSEN, D.; ROEBBERS, E. J.; GREUEL, G. Algebraic and combinatorial algorithms for

translinear network synthesis. Circuits and Systems I: Regular Papers, IEEE Transactions on,

  IEEE, v. 55, n. 10, p. 3131–3144, 2008.

[26] MULDER, J. et al. An rms-dc converter based on the dynamic translinear principle. Solid-

State Circuits, IEEE Journal of, IEEE, v. 32, n. 7, p. 1146–1150, 1997.

  

[27] SEEVINCK, E. Analysis and synthesis of translinear integrated circuits. [S.l.]: Elsevier Ams-

terdam, 1988.

[28] MULDER, J. et al. General current-mode analysis method for translinear filters. Circuits and

Systems I: Fundamental Theory and Applications, IEEE Transactions on, IEEE, v. 44, n. 3, p.

  193–197, 1997.

[29] GILBERT, B. Translinear circuits: A proposed classification. Electronics Letters, IET, v. 11,

n. 1, p. 14–16, 1975.

  

[30] GILBERT, B. A new wide-band amplifier technique. Journal of Solid-State Circuits, IEEE,

v. 3, n. 4, p. 353–365, Dec 1968.

[31] GILBERT, B. Translinear circuits: an historical overview. Analog Integrated Circuits and

Signal Processing, Springer, v. 9, n. 2, p. 95–118, 1996.

[32] MINCH, B. A. Multiple-input translinear element log-domain filters. Circuits and Systems II:

Analog and Digital Signal Processing, IEEE Transactions on, IEEE, v. 48, n. 1, p. 29–36, 2001.

[33] TSIVIDIS, Y.; MCANDREW, C. Operation and Modeling of the MOS Transistor. [S.l.]: Ox-

ford Univ. Press, 2011.

[34] ADAMS, R. W. Filtering in the log domain. In: AUDIO ENGINEERING SOCIETY. Audio

Engineering Society Convention 63. [S.l.], 1979.

[35] HADDAD, S. A.; SERDIJN, W. A. High-frequency dynamic translinear and log-domain cir-

cuits in cmos technology. In: CITESEER. IEEE INTERNATIONAL SYMPOSIUM ON CIR-

  CUITS AND SYSTEMS. [S.l.], 2002. p. III–313.

[36] DUERDEN, G. D.; ROBERTS, G. W.; DEEN, M. J. The development of bipolar log domain

filters in a standard cmos process. In: IEEE. Circuits and Systems, 2001. ISCAS 2001. The

  2001 IEEE International Symposium on. [S.l.], 2001. v. 1, p. 145–148.

[37] MINCH, B. A. et al. Translinear circuits using subthreshold floating-gate mos transistors.

  Analog Integrated Circuits and Signal Processing, Springer, v. 9, n. 2, p. 167–179, 1996.

[38] MULDER, J. et al. A generalized class of dynamic translinear circuits. Circuits and Systems

II: Analog and Digital Signal Processing, IEEE Transactions on, v. 48, n. 5, p. 501–504, May 2001. ISSN 1057-7130.

  

[39] FREY, D. Log-domain filtering: an approach to current-mode filtering. IEE Proceedings G

(Circuits, Devices and Systems), IET, v. 140, n. 6, p. 406–416, 1993.

[40] PERRY, D.; ROBERTS, G. W. The design of log-domain filters based on the operational

simulation of lc ladders. Circuits and Systems II: Analog and Digital Signal Processing, IEEE

  Transactions on, IEEE, v. 43, n. 11, p. 763–774, 1996.

[41] DRAKAKIS, E. M.; PAYNE, A. J.; TOUMAZOU, C. ?log-domain state-space?: a systematic

transistor-level approach for log-domain filtering. Circuits and Systems II: Analog and Digital

  Signal Processing, IEEE Transactions on, IEEE, v. 46, n. 3, p. 290–305, 1999.

[42] BERNARDIN, L.; MONAGAN, M. B. Efficient multivariate factorization over finite fields.

  In: Applied Algebra, Algebraic Algorithms and Error-Correcting Codes. [S.l.]: Springer, 1997. p. 15–28.

  

[43] STEEL, A. Conquering inseparability: primary decomposition and multivariate factorization

over algebraic function fields of positive characteristic. Journal of Symbolic Computation, Else- vier, v. 40, n. 3, p. 1053–1075, 2005.

[44] ALLEM, L. E. Polinômios Multivariados: fatoraçao e mdc. Tese (Doutorado) — UNIVERSI-

DADE FEDERAL DO RIO GRANDE DO SUL, 2010.

  

[45] CHEN, C.; MAZA, M. M. Algorithms for computing triangular decompositions of polynomial

systems. In: ACM. Proceedings of the 36th international symposium on Symbolic and algebraic computation. [S.l.], 2011. p. 83–90.

[46] LECERF, G. Improved dense multivariate polynomial factorization algorithms. Journal of

Symbolic Computation, Elsevier, v. 42, n. 4, p. 477–494, 2007.

  

[47] LEE, M. M.-D. Factorization of multivariate polynomials. Tese (Doutorado) — Technische

Universität Kaiserslautern, 2013.

[48] MULDER, J. et al. Translinear sin (x)-circuit in mos technology using the back gate. In:

IEEE. Solid-State Circuits Conference, 1995. ESSCIRC’95. Twenty-first European. [S.l.], 1995. p. 82–85.

[49] SERDIJN, W. A. et al. A low-voltage translinear second-order quadrature oscillator. In: IEEE.

  Circuits and Systems, 1999. ISCAS’99. Proceedings of the 1999 IEEE International Symposium on. [S.l.], 1999. v. 2, p. 701–704.

[50] SERRANO-GOTARREDONA, T.; LINARES-BARRANCO, B.; ANDREOU, A. A general

translinear principle for subthreshold mos transistors. Circuits and Systems I: Fundamental

  Theory and Applications, IEEE Transactions on, v. 46, n. 5, p. 607–616, May 1999. ISSN 1057- 7122.

[51] ANDRADE, D. NParametricTLDecomp — 2014 Source Code for Non-parametric Transli- near Decomposition Application. 2014. https://github.com/mudo007/NParametricTLDecomp. git . ANEXOS

I. CÓDIGO FONTE DO APLICATIVO

  O código fonte deste anexo compreende o aplicativo com a implementação do algoritmo de-

senvolvido neste trabalho e a implementação do algoritmo de Mulder et. al. [23]. Da forma como

está implementado, o aplicativo primeiro executa o algoritmo de Mulder, depois o deste trabalho,

e depois re-executa ambos a partir do vetor de polinômios extremamente reduzido ⌧ .

  4 Para compilar o código, basta colocar o arquivo “main.c” e o arquivo “main.h” na mesma pasta, e a partir de um terminal executar o comando:

gcc main.c -o NParametricTLDecomp

c

  Este código-fonte foi compilado e executado nos sistemas operacionais Windows 7, CentOS

5.5, e OS X 10.9.4. A versão mais recente deste código, bem como a contribuição de outros

desenvolvedores pode ser encontrada em [51].

I.1 arquivo “main.c’

  1

  /*

  2 D e c o m p _ n p a r a m e t r i c a : " R e o r g a n i z e s a m u l t i v a r i a b l e e q u a t i o n so it is

  3

  s u i t a b l e to be r e a l i z e d onto a s i n g l u a r t r a n s l i n e a r loop a n a l o g u e

  4

  c u r r e n t mode c i r c u i t ."

  5

  6 C o p y r i g h t ( C ) 2014 Diogo A n d r a d e

  7

  8 This p r o g r a m is free s o f t w a r e : you can r e d i s t r i b u t e it and / or modify

  9

  it under the terms of the GNU G e n e r a l Public L i c e n s e as p u b l i s h e d by

  10

  the Free S o f t w a r e Foundation , either v e r s i o n 3 of the License , or

  11 ( at your option ) any later v e r s i o n .

  12

  13 This p r o g r a m is d i s t r i b u t e d in the hope that it will be useful ,

  14

  but W I T H O U T ANY W A R R A N T Y ; w i t h o u t even the i mp l i e d w a r r a n t y of

  15 M E R C H A N T A B I L I T Y or F I T N E S S FOR A P A R T I C U L A R P U R P O S E . See the

  16 GNU G e n e r a l Public L i c e n s e for more d e t a i l s .

  17

  18 You should have r e c e i v e d a copy of the GNU G e n e r a l Public L i c e n se

  19 along with this p r o gr a m . If not , see < http :// www . gnu . org / l i c e n s e s / >.

  20

  21

  email : d i o g o 0 0 7 @ g m a i l . com

  22

  23

  • /

  24

  # i n c l u d e " main . h "

  25

  26

  int main ( int argc , char * argv [])

  27

  {

  28

  // V a r i a v e i s

  29

  char e q u a c a o _ e n t r a d a [302];

  30

  int i ;

  31

  token * l i s t a _ t o k e n = NULL ;

  32

  t a b e l a _ l i t e r a i s * l i s t a _ l i t e r a i s = NULL ;

  33

  token * e x p r e s s a o _ R P N = NULL ;

  34

  a r v o r e _ e x p r * arvore = NULL ;

  35

  l i s t a _ e x p r * e x p r _ e x p a n d i d a = NULL ;

  36

  l i s t a _ e x p r * e x p r _ s i m p l i f i c a d a = NULL ;

  37

  l i s t a _ e x p r * p o l i n o m i o _ b a s e ;

  38

  v e t o r _ p o l i n o m i o s * l i s t a _ p o l i n o m i o s = NULL ;

  39

  v e t o r _ p o l i n o m i o s * p e r c o r r e _ p o l i n o m i o s ;

  40

  v e t o r _ s e m e n t e s * l i s t a _ s e m e n t e s = NULL ;

  41

  v e t o r _ s e m e n t e s * p e r c o r r e _ s e m e n t e s = NULL ;

  42

  int c o n t a d o r ;

  43

  v e t o r _ d e c o m p * d e c o m p o s i c o e s _ e n c o n t r a d a s ;

  44

  int l i m _ i n f e r i o r ;

  45

  int l i m _ s u p e r i o r ;

  46

  time_t c r o n o m e t r o ;

  47

  48

  49

  50

  // * * * * * * * * *

  51

  // INICIO *

  52

  // * * * * * * * * *

  53

  54

  printf ( " N P a r a m e t r i c T L D e c o m p C o p y r i g h t ( C ) 2014 Diogo A n d r a d e \ nThis p r o g r a m comes with A B S O L U T E L Y NO W A R R A N T Y .\

nThis is free software , and you are w e l c o m e to r e d i s t r i b u t e it under c e r t a in c o n d i t i o n s .\ n \ nThis a p p l i c a t i o n

p e r f o r m s non - p a r a m e t r i c T r a n s l i n e a r d e c o m p o s i t i o n onto a h o m o g e n e o u s ( all m o n o m i a l s having the same degree )

m u l t i v a r i a t e p o l y n o m i a l .\ nThe r e s u l t s are s u i t a b l e for T r a n s l i n e a r analog c i r c u i t r e a l i z a t i o n with proper

a d j u s t m e n t s .\ nIf an error occurs , send a brief d e s c r i p t i o n with the p o l y n o m i a l i n s e r t e d to d i o g o 0 0 7 @ g m a i l . com .\ n \ r \

55 Below , type the p o l y n o m i a l to be d e c o m p o s e d (100 c h a r a c t e r s m a x i m u m ) . C o e f f i c i e n t s should be only i n t e g e r

  56

  97

  // E x p a n s a o da arvore de e x p r e s s o e s

  102 103

  # endif

  101

  i m p r i m e _ l i s t a _ e x p r ( e x p r e s s a o _ R P N ) ;

  100

  i m p r i m e _ a r v o r e _ e x p r ( arvore ) ;

  99

  # if d e f i n e d D E B U G _ E X P R

  98

  arvore = c o n s t r o i _ a r v o r e _ e x p r ( e x p r e s s a o _ R P N ) ;

  e x p r e s s a o _ R P N = c o n s t r o i _ l i s t a _ e x p r ( l i s t a _ t o k e n ) ;

  e x p r _ e x p a n d i d a = c o n s t r o i _ l i s t a _ e x p r e s s o e s _ e x p ( arvore ) ;

  96

  95

  // C r i a c ao das pilhas de a v a l i a c a o de e x p r e s s a o

  94

  93

  // * * * * * * * * * * * * * * * * * * * *

  92

  // A N A L I S E S I N T A T I C A *

  91

  // * * * * * * * * * * * * * * * * * * * *

  90

  104

  105

  # endif

  113 114

  i m p r i m e _ l i s t a _ e x p r _ e x p a n d i d a ( e x p r _ s i m p l i f i c a d a , l i s t a _ l i t e r a i s ) ;

  119

  printf ( " \ n e q u a c a o s i m p l i f i c a d a : " ) ;

  118

  # if d e f i n e d D E B U G _ S I M P L I F Y

  117

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( e x p r _ e x p a n d i d a ) ;

  116

  e x p r _ s i m p l i f i c a d a = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( e x p r _ e x p a n d i d a ) ;

  115

  // S i m p l i f i c a c a o da e x p r e s s a o

  // * * * * * * * * * * * * * * * * * * * *

  # if d e f i n e d D E B U G _ E X P A N D

  112

  // A N A L I S E S E M A N T I C A *

  111

  // * * * * * * * * * * * * * * * * * * * *

  109 110

  # endif

  108

  i m p r i m e _ l i s t a _ e x p r _ e x p a n d i d a ( ex p r _ e x p a n d i d a , l i s t a _ l i t e r a i s ) ;

  107

  printf ( " \ n e q u a c a o e x p a n d i d a : " ) ;

  106

  89

  88

  x ^3 + x ^2* y - x * z ^2 + y * z ^2\ n \ r ( Hit \" enter \" to use it ) " ) ;

  64

  // * * * * * * * * * * * * * * * * *

  70

  69

  s p r i n t f ( e q u a c a o _ e n t r a d a , " x ^3 + x ^2* y - x * z ^2 + y * z ^2 " ) ;

  68

  if (* e q u a c a o _ e n t r a d a == ’\ n ’ || * e q u a c a o _ e n t r a d a == ’\ r ’)

  67

  // e q u a c ao padrao , caso o u s u a r i o aperte enter direto . pode ser igual a nova linha ou r e t o rn o de carro para tratar como o s i s t e m a o p e r a c i o n a l r e c o n h e c e o ENTER em varias p l a t a f o r m a s d i f e r e n t e s

  66

  65

  }

  return (0) ;

  // A N A L I S E LEXICA *

  63

  erro ( E R R O _ 0 0 2 ) ;

  62

  {

  61

  if ( fgets ( e q u a c a o _ e n t r a d a , 100 , stdin ) == NULL )

  60

  59

  // l e i t u ra da string de e n t r a d a

  58

  57

  71

  72

  i m p r i m e _ t o k e n s ( l i s t a _ t o k e n ) ;

  return 0; }

  87

  // caso a l e i tu r a dos tokens tenha sido correta , i m p r i m i r os tokens

  86

  # if d e f i n e d D E B U G _ L E X I C O

  85

  84

  n u m b e r s . \ n \ r \ t E x a m p l e :\ n \ r \ t \

  83

  // c o n v e r t e os l i t e r a i s em c o d i g o s - apenas de e x e m p l o

  82

  81

  79

  // * * * * * * * * * * * * * * * * *

  system ( " PAUSE " ) ;

  78

  // l i m p e z a de p o n t e i r o s

  77

  {

  76

  if (( l i s t a _ t o k e n = l e _ t o k e n s ( e q u a c a o _ e n t r a d a ) ) == NULL )

  75

  // l e i t u ra dos tokens

  74

  73

  c o n s t r o i _ t a b e l a _ l i t e r a i s (& l i s t a _ l i t e r a i s , l i s t a _ t o k e n ) ;

  • /

  }

  180

  // c o n s t r u c a o dos vetores , aqui com c o e f i c i e n t e s e s p e c i f i c a d o s pelo us u a r i o

  177 178 179

  printf ( " \ n c o e f f i c i e n t s u p e r i o r limit : % d \ n " , l i m _ s u p e r i o r ) ;

  176

  printf ( " \ n c o e f f i c i e n t i n f e r i o r limit : % d " , l i m _ i n f e r i o r ) ;

  175

  i m p r i m e _ l i s t a _ e x p r _ e x p a n d i d a ( e x p r _ s i m p l i f i c a d a , l i s t a _ l i t e r a i s ) ;

  174

  printf ( " \ n Expanded , s i m p l i f i e d and re - o r d e r e d P o l y n o m i a l : " ) ;

  173

  // i m p r i m i r os p a r a m e t r o s c o l h i d o s

  171 172

  170

  181 182

  l i m _ s u p e r i o r = atoi ( e q u a c a o _ e n t r a d a ) ;

  169

  {

  168

  else

  167

  l i m _ s u p e r i o r = 1;

  166

  if (* e q u a c a o _ e n t r a d a == ’\ n ’ || * e q u a c a o _ e n t r a d a == ’\ r ’)

  165

  // se ap e r t a r enter direto , e -1

  164

  // t r a t a m e n t o do numero i n s e r i d o

  l i s t a _ p o l i n o m i o s = g e r a _ v e t o r ( l i s t a _ p o l i n o m i o s , p o l i n o m i o _ b a s e , p o l i n o m i o _ b a s e , lim_inferior , l i m _ s u p e r i o r ) ;

  // r e b o b i n a a lista

  return (0) ; }

  192

  l i s t a _ p o l i n o m i o s = e l i m i n a _ z e r o ( l i s t a _ p o l i n o m i o s ) ;

  199

  // e l i m i na o p o l i n o m i o nulo

  197 198

  printf ( " \ n Total number of Base - P o l y n o m i a l s g e n e r a t e d ( T0 set ) is : % d \ n " , c o n t a d o r ) ;

  196

  }

  195

  p e r c o r r e _ p o l i n o m i o s = p e r c o r r e _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  194

  c o n t a d o r ++;

  193

  {

  while ( p e r c o r r e _ p o l i n o m i o s != NULL )

  183

  191

  c o n t a d o r = 0;

  190

  p e r c o r r e _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  189

  // c o n t a g e m de p o l i n o m i o s T0

  187 188

  }

  186

  l i s t a _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s - > p o l i n o m i o _ a n t e r i o r ;

  185

  {

  184

  while ( l i s t a _ p o l i n o m i o s - > p o l i n o m i o _ a n t e r i o r != NULL )

  162 163

  160

  120

  /* * * * * * * * * * * * * * * * * * * * * * *

  if ( fgets ( e q u a c a o _ e n t r a d a , 100 , stdin ) == NULL )

  140

  printf ( " \ n Insert the i n f e r i o r limit of v a r i a b l e s c o e f f i c i e n t s ( s t a n d a r d -1) " ) ;

  139

  // l e i t u ra dos l i m i t e s s u p e r i o r e s e i n f e r i o r e s dos c o e f i c i e n t e s

  137 138

  p o l i n o m i o _ b a s e = g e r a _ p o l i n o m i o _ b a s e ( l i s t a _ l i t e r a i s ) ;

  135 136

  // i m p r i m i r a lista de l i t e r a i s e c o n s t r u i r o p o l i n o m i o base

  133 134

  132

  Base - P o l y n o m i a l g e n e r a t i o n and r e d u c t i o n

  131

  128 129 130

  {

  # endif

  127

  i m p r i m e _ l i s t a _ e x p r _ e x p a n d i d a ( e x p r _ s i m p l i f i c a d a , l i s t a _ l i t e r a i s ) ;

  126

  printf ( " \ n e q u a c a o r e o r d e n a d a lex : " ) ;

  125

  # if d e f i n e d D E B U G _ S I M P L I F Y

  124

  e x p r _ s i m p l i f i c a d a = l e x d e g b u b b l e s o r t ( e x p r _ s i m p l i f i c a d a ) ;

  123

  // o r d e n a c a o lexdeg

  121 122

  # endif

  141

  142

  erro ( E R R O _ 0 0 2 ) ;

  {

  159

  {

  158

  if ( fgets ( e q u a c a o _ e n t r a d a , 100 , stdin ) == NULL )

  157

  printf ( " \ n Insert the s u p e r i o r limit of v a r i a b l e s c o e f f i c i e n t s ( s t a n d a r d +1) " ) ;

  156

  // limite s u p e r i o r

  154 155

  }

  153

  l i m _ i n f e r i o r = atoi ( e q u a c a o _ e n t r a d a ) ;

  152

  151

  erro ( E R R O _ 0 0 2 ) ;

  else

  150

  l i m _ i n f e r i o r = -1;

  149

  if (* e q u a c a o _ e n t r a d a == ’\ n ’ || * e q u a c a o _ e n t r a d a == ’\ r ’)

  148

  // se ap e r t a r enter direto , e -1

  147

  // t r a t a m e n t o do numero i n s e r i d o

  145 146

  }

  144

  return (0) ;

  143

  200 switch ( e q u a c a o _ e n t r a d a [0])

  280

  p e r c o r r e _ p o l i n o m i o s = p e r c o r r e _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  // l e i t u ra dos l i m i t e s s u p e r i o r e s e i n f e r i o r e s dos c o e f i c i e n t e s

  259

  // E s c o l ha de qual a l g o r i t m o sera u t i l i z a d o

  257 258

  256

  R e c u r s i v e D i v i s i o n By BP pairs

  255

  /* * * * * * * * * * * * * * * * * * * * * * *

  252 253 254

  printf ( " \ n Number of Base - P o l y n o m i a l s after seed g e n e r a t i o n ( r e d u c ed set T4 ) is : % d \ n " , c o n t a d o r ) ;

  251

  }

  250

  249

  

printf ( " \ n Select r e c u r s i v e d i v i s i o n A l g o r i t h m :[ A ] ndrade , [ M ] ulder fast , Mulder Memory [ S ] afe : ( D e f a ul t : A ) " ) ;

  c o n t a d o r ++;

  248

  {

  247

  while ( p e r c o r r e _ p o l i n o m i o s != NULL )

  246

  c o n t a d o r = 0;

  245

  p e r c o r r e _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  244

  // c o n t a g e m de T4

  243

  l i s t a _ p o l i n o m i o s = r e c o n t a _ p o l i n o m i o s ( li s t a _ s e m e n t e s , l i s t a _ p o l i n o m i o s ) ;

  241

  260

  261

  239 240

  {

  // s e l e c i o n a r o a l g o r i t m o a ser u t i l i z a d o

  278 279

  i n i c i a _ c r o n o m e t r o (& c r o n o m e t r o ) ;

  277

  d e c o m p o s i c o e s _ e n c o n t r a d a s = NULL ;

  276

  g l o b a l _ n u m _ p a r f r a c = 0;

  275

  // p r e p a r a r para a e x e c u c a o

  273 274

  }

  272

  e q u a c a o _ e n t r a d a [0] = ’A ’;

  271

  270

  if ( fgets ( e q u a c a o _ e n t r a d a , 100 , stdin ) == NULL )

  e q u a c a o _ e n t r a d a [0] != ’S ’ && e q u a c a o _ e n t r a d a [0] != ’s ’)

  269

  if ( e q u a c a o _ e n t r a d a [0] != ’M ’ && e q u a c a o _ e n t r a d a [0] != ’m ’ && e q u a c a o _ e n t r a d a [0] != ’A ’ && e q u a c a o _ e n t r a d a [0] != ’a ’ &&

  268

  // Se opcao e s t r a n h a for utilizada , rea ; lizar a l g o r i t m o de diogo

  266 267

  }

  265

  return (0) ;

  264

  erro ( E R R O _ 0 0 2 ) ;

  263

  {

  262

  // gerar T4 Ů aps T3 ter sido gerado

  printf ( " \ n Number of Base - P o l y n o m i a l pairs ( T3 set ) is : % d \ n " , c o n t a d o r ) ;

  201

  210

  p e r c o r r e _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  218

  // c o n t a g e m de p o l i n o m i o s T2

  216 217

  l i s t a _ p o l i n o m i o s = r e m o v e _ p o l i n o m i o s _ r e d u n d a n t e s ( l i s t a _ p o l i n o m i o s ) ;

  215

  // e l i m i na os p o l i n o m i o s r e d u n d a n t e s

  213 214

  printf ( " \ n Number of Base - P o l y n o m i a l s after r e m o v i n g stri ct n e g a t i v e BP ’s ( T1 set ) is : % d \ n " , c o n t a d o r ) ;

  212

  }

  211

  p e r c o r r e _ p o l i n o m i o s = p e r c o r r e _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  c o n t a d o r ++;

  c o n t a d o r = 0;

  209

  {

  208

  while ( p e r c o r r e _ p o l i n o m i o s != NULL )

  207

  c o n t a d o r = 0;

  206

  p e r c o r r e _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  205

  // c o n t a g e m de p o l i n o m i o s T1

  203 204

  l i s t a _ p o l i n o m i o s = r e m o v e _ p o l i n o m i o s _ n e g a t i v o s ( l i s t a _ p o l i n o m i o s ) ;

  202

  // e l i m i na os p o l i n o m i o s i n t e i r a m e n t e n e g a t i v o s

  219

  220

  238

  // c o n t a g e m de pares de p o l i n o m i o s T3

  }

  237

  p e r c o r r e _ s e m e n t e s = p e r c o r r e _ s e m e n t e s - > c o n j u n t o _ p r o x ;

  236

  c o n t a d o r ++;

  235

  {

  234

  while ( p e r c o r r e _ s e m e n t e s != NULL )

  233

  c o n t a d o r = 0;

  232

  p e r c o r r e _ s e m e n t e s = l i s t a _ s e m e n t e s ;

  231

  229 230

  while ( p e r c o r r e _ p o l i n o m i o s != NULL )

  l i s t a _ s e m e n t e s = g e r a _ v e t o r _ s e m e n t e ( l i s t a _ p o l i n o m i o s , e x p r _ s i m p l i f i c a d a ) ;

  228

  // gerar vetor T3

  226 227

  printf ( " \ n Number of Base - P o l y n o m i a l s after r e d u n d a n c y r e m o v a l ( T2 set ) is : % d \ n " , c o n t a d o r ) ;

  225

  }

  224

  p e r c o r r e _ p o l i n o m i o s = p e r c o r r e _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  223

  c o n t a d o r ++;

  222

  {

  221

  • /

  281

  332

  {

  339

  while ( l i s t a _ p o l i n o m i o s != NULL )

  338

  // d e s t r oi o vetor de p o l i n o m i o s

  336 337

  l i s t a _ s e m e n t e s = NULL ;

  335

  d e c o m p o s i c o e s _ e n c o n t r a d a s = NULL ;

  334

  d e s t r o i _ l i s t a _ s e m e n t e s ( l i s t a _ s e m e n t e s ) ;

  333

  d e s t r o i _ v e t o r _ d e c o m p ( d e c o m p o s i c o e s _ e n c o n t r a d a s ) ;

  // e l i m i na o vetor de p o l i n o m i o s t r a n s l i n e a r e s

  p e r c o r r e _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  329 330 331

  }

  328

  p e r c o r r e _ p o l i n o m i o s = p e r c o r r e _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  327

  printf ( " \ t % d \ n " , p e r c o r r e _ p o l i n o m i o s - > polinomio - > id ) ;

  326

  // i mp r i m e o i d e n t i f i c a d o r do p o l i n o m i o

  325

  i m p r i m e _ l i s t a _ e x p r _ e x p a n d i d a ( p e r c o r r e _ p o l i n o m i o s - > p olinomio - >P , l i s t a _ l i t e r a i s ) ;

  324

  c o n t a d o r ++;

  323

  340

  341

  322

  d e s t r o i _ l i s t a ( l i s t a _ t o k e n ) ;

  357

  return 0;

  356

  g e t c h a r () ;

  355

  printf ( " \ nPress any key to c o n t i n u e ... " ) ;

  354

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( e x p r _ s i m p l i f i c a d a ) ;

  353

  d e s t r o i _ l i s t a _ e x p r ( e x p r e s s a o _ R P N ) ;

  352

  d e s t r o i _ a r v o r e _ e x p r ( arvore ) ;

  351

  350

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p o l i n o m i o s - > poli nomio - > P ) ;

  d e s t r o i _ t a b e l a _ l i t e r a i s ( l i s t a _ l i t e r a i s ) ;

  349

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( p o l i n o m i o _ b a s e ) ;

  348

  // d e s t r oi e s t r u t u r a s de dados a u x i l i a r e s

  346 347

  }

  345

  l i s t a _ p o l i n o m i o s = p e r c o r r e _ p o l i n o m i o s ;

  344

  free ( l i s t a _ p o l i n o m i o s ) ;

  343

  free ( l i s t a _ p o l i n o m i o s - > p o l i n o m i o ) ;

  342

  {

  while ( p e r c o r r e _ p o l i n o m i o s != NULL )

  {

  printf ( " \ n R u n n i ng Mulder ’s a l g o r i t h m ( fast v e r s i o n ) ... " ) ;

  298

  d e c o m p o s i c o e s _ e n c o n t r a d a s = e n c o n t r a _ d e c o m p _ m u l d e r _ s a f e ( l i s t a _ p o l i n o m i o s , deg ( e x p r _ s i m p l i f i c a d a ) , e x p r _ s i m p l i f i c a d a , l i s t a _ l i t e r a i s ) ;

  297

  printf ( " \ n R u n n i ng Mulder ’s a l g o r i t h m ( memory safe v e r s i o n ) ... " ) ;

  296

  case ’s ’:

  295

  case ’S ’:

  293 294

  break ;

  292

  

d e c o m p o s i c o e s _ e n c o n t r a d a s = e n c o n t r a _ d e c o m p _ m u l d e r ( l i s t a _ p o l i n o m i o s , deg ( e x p r _ s i m p l i f i c a d a ) ,

e x p r _ s i m p l i f i c a d a , l i s t a _ l i t e r a i s ) ;

  291

  290

  299 300

  case ’m ’:

  289

  case ’M ’:

  287 288

  break ;

  286

  d e c o m p o s i c o e s _ e n c o n t r a d a s = e n c o n t r a _ d e c o m p ( l i s t a _ s e m e n te s , deg ( e x p r _ s i m p l i f i c a d a ) , e x p r _ s i m p l i f i c a d a , l i s t a _ l i t e r a i s ) ;

  285

  printf ( " \ n R u n n i ng A n d r a d e ’s a l g o r i t h m ... " ) ;

  284

  case ’a ’:

  283

  case ’A ’:

  282

  break ;

  }

  321

  311

  c o n t a d o r = 0;

  320

  p e r c o r r e _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  319

  // i m p r i me apenas os p o l i n o m i o s u t i l i z a d o s em alguma d e c o m p o s i c a o printf ( " \ n The base p o l y n o m i a l s used in any of the t r a n s l i n e a r p o l y n o m i a l s found are :\ n " ) ;

  316 317

  printf ( " \ n Number of Base - P o l y n o m i a l s e f f e c t i v e l y used in any t r a n s l i n e a r p o l y n o m i a l ( e x t r e m e l y r e d u c e d set T5 ) is : % d " , c o n t a d o r ) ;

  314 315

  }

  313

  p e r c o r r e _ p o l i n o m i o s = p e r c o r r e _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  312

  c o n t a d o r ++;

  {

  301

  310

  while ( p e r c o r r e _ p o l i n o m i o s != NULL )

  309

  c o n t a d o r = 0;

  308

  p e r c o r r e _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  307

  // c o n t a g e m Ů ps - e n c o n t r a r d e c o m p o s i c o e s

  305 306

  l i s t a _ p o l i n o m i o s = r e m o v e _ p o l i n o m i o s _ n a o _ p e r t e n c e n t e s ( d e c o m p o s i c o e s _ e n c o n t r a d a s , l i s t a _ p o l i n o m i o s ) ;

  304

  // v e r i f i c a q u a n t o s PB ’s de fato f i ze r a m parte de alguma d e c o m p o s i c a o

  302 303

  p a r a _ c r o n o m e t r o (& c r o n o m e t r o ) ;

  }

I.2 arquivo “main.h”

  12 ( at your option ) any later v e r s i o n .

  23

  email : d i o g o 0 0 7 @ g m a i l . com

  22

  21

  20 along with this p r o gr a m . If not , see < http :// www . gnu . org / l i c e n s e s / >.

  19 You should have r e c e i v e d a copy of the GNU G e n e r a l Public L i c e n se

  18

  17 GNU G e n e r a l Public L i c e n s e for more d e t a i l s .

  16 M E R C H A N T A B I L I T Y or F I T N E S S FOR A P A R T I C U L A R P U R P O S E . See the

  but W I T H O U T ANY W A R R A N T Y ; w i t h o u t even the i mp l i e d w a r r a n t y of

  15

  14 This p r o g r a m is d i s t r i b u t e d in the hope that it will be useful ,

  13

  the Free S o f t w a r e Foundation , either v e r s i o n 3 of the License , or

  1

  11

  it under the terms of the GNU G e n e r a l Public L i c e n s e as p u b l i s h e d by

  10

  9 This p r o g r a m is free s o f t w a r e : you can r e d i s t r i b u t e it and / or modify

  8

  7 C o p y r i g h t ( C ) 2014 Diogo A n d r a d e

  6

  c u r r e n t mode c i r c u i t ."

  5

  s u i t a b l e to be r e a l i z e d onto a s i n g l u a r t r a n s l i n e a r loop a n a l o g u e

  4

  3 D e c o m p _ n p a r a m e t r i c a : " R e o r g a n i z e s a m u l t i v a r i a b l e e q u a t i o n so it is

  /*

  2

  24

  • /

  # i n c l u d e < stdio .h >

  59 struct _token * p r o x i m o _ t o k e n ; // p o n t e i r o para o p r o x i m o token da fila .

  {

  64

  t y p e d e f struct _ t a b e l a _ l i t e r a i s

  63

  // e s t r u t u r a para a lista de l i t e r a i s e seus codigos , l i m i t a d o s a 50 no total

  62

  61

  } token ;

  60

  int a b r e _ f e c h a ; // abre ou fecha p a r e n t e s e s

  char * l it e r a l ;

  58

  int o p e r a d o r ; // o p e r a d o r á m a t e m t i c o

  57

  int p a r a m e t r o ; // valor n u m e r i c o do p a r a m e t r o

  56

  char codigo ; // c a r a c t e r do codigo c o r r e s p o n d e n t e Ĺ string do literal , ou no caso de o p e r a d o r e s e a b r e _ f e c h a pareneteses , o c a r a c t e r c o r r e s p o n d e n t e

  55

  char * l it e r a l ; // string do l i t e r a l

  54

  int tipo ; // d e p e n d e n d o do tipo do token , uma das á v a r i v e i s abaixo é p r e e n c h i d a

  65

  66

  {

  73

  struct _ l i s t a _ e x p r * p r o x i m o ;

  77

  double p a r a m e t r o ; // I n t e i ro que m u l t i p l i c a o termo

  76

  // char sinal ; // se e p o s i t i v o ou n e g a t i v o

  75

  struct _ l i s t a _ e x p r * c o d i g o s _ d e n o m i n a d o r ; // As v a r i a v e i s c o n t i d a s no n u m e r a d o r do termo

  74

  char * c o d i g o s _ n u m e r a d o r ; // As v a r i a v e i s c o n t i d a s no n u m e r a d o r do termo

  {

  char codigo ; // o codigo e so uma letra de A - Z m a i u s c u l a ou m i n u s c u l a

  72

  t y p e d e f struct _ l i s t a _ e x p r

  71

  // E s t r u t u r a da lista que r e p r e s e n t a r a a e x p r e s s a o e x p a n d i d a

  70

  69

  } t a b e l a _ l i t e r a i s ;

  68

  struct _ t a b e l a _ l i t e r a i s * p r o x i m o _ c o d i g o ;

  67

  53

  52

  26

  33

  // # define D E B U G _ S I M P L I F Y

  37

  // # define D E B U G _ E X P A N D

  36

  // # define D E B U G _ E X P R

  35

  // # define D E B U G _ L E X I C O

  34

  // d e f i n i c a o de debug

  32

  39

  31

  # i n c l u d e < time .h >

  30

  # i n c l u d e < ctype .h >

  29

  # i n c l u d e < math .h >

  28

  # i n c l u d e < string .h >

  27

  # i n c l u d e < stdlib .h >

  38

  // M e n s a g e n s de erro

  t y p e d e f struct _token

  # define TRUE

  51

  // e s t r u t u r a de tokens para parse i n i c i a l

  50

  // tipos

  49

  48

  # define FALSE

  47

  1

  46

  40

  // d e f i n i c o e s b o l e a n a s

  45

  44

  25

  43

  # define E R R O _ 0 0 3 " ERRO : E q u a c a o errada "

  42

  # define E R R O _ 0 0 2 " ERRO : E q u a c a o muito longa "

  41

  # define E R R O _ 0 0 1 " ERRO : M e m o r i a I n s u f i c i e n t e "

  # define E R R O _ 0 0 4 " ERRO : Limite de v a r i a v e i s v i o l a d o (50) "

  78

  126

  t y p e d e f struct _ v e t o r _ d e c o m p

  134

  // e s t r u t u r a que guarda d e c o m p o s i c a o p a r a m e t r i c a e n c o n t r a d a

  132 133

  } v e t o r _ s e m e n t e s ;

  130 131

  struct _ v e t o r _ s e m e n t e s * c o n j u n t o _ a n t ;

  129

  struct _ v e t o r _ s e m e n t e s * c o n j u n t o _ p r o x ;

  128

  l i s t a _ e x p r * R2 ;

  127

  l i s t a _ e x p r * R1 ;

  l i s t a _ e x p r * q u o c i e n t e ;

  {

  125

  p o l i n o m i o P2 ;

  124

  p o l i n o m i o P1 ;

  123

  {

  122

  t y p e d e f struct _ v e t o r _ s e m e n t e s

  121

  

// e s t r u t u r a que guarda c o m b i n a c o e s de p o l i n o m i o s que podem ser s e me n t e de uma d e c o m p o s i c a o

  120

  } v e t o r _ p o l i n o m i o s ;

  117 118

  struct _ v e t o r _ p o l i n o m i o s * p o l i n o m i o _ a n t e r i o r ;

  135

  136

  struct _ v e t o r _ p o l i n o m i o s * p r o x i m o _ p o l i n o m i o ;

  t y p e d e f struct _ v e t o r _ d e c o m p _ s i m p l e

  157 158

  } v e t o r _ d e c o m p _ s i m p l e ;

  155 156

  struct _ v e t o r _ d e c o m p _ s i m p l e * a n t _ d e c o m p ;

  154

  struct _ v e t o r _ d e c o m p _ s i m p l e * p r o x _ d e c o m p ;

  152 153

  l i s t a _ e x p r * resto ;

  151

  v e t o r _ p o l i n o m i o s * p o l i n o m i o s ;

  150

  {

  149

  148

  v e t o r _ p o l i n o m i o s * p o l y _ p a r e s ;

  // e s t r u t u r a que guarda d e c o m p o s i c o e s p a r c i a i s e n c o n t r a d a s ao e x e c u t a r o a l g o r i t m o do mulder

  146 147

  } v e t o r _ d e c o m p ;

  143 144 145

  struct _ v e t o r _ d e c o m p * a n t _ d e c o m p ;

  142

  struct _ v e t o r _ d e c o m p * p r o x _ d e c o m p ;

  140 141

  l i s t a _ e x p r * r e s t o _ p a r ;

  139

  l i s t a _ e x p r * r e s t o _ i m p a r ;

  138

  v e t o r _ p o l i n o m i o s * p o l y _ i m p a r e s ;

  137

  116

  115

  struct _ l i s t a _ e x p r * a n t e r i o r ;

  87

  94

  struct _ p i l h a _ e x p r * p r o x i m o ;

  93

  

token * e l e m e n t o ; // p o n t e i r o para o token que sera i n s e r i d o na pilha

  92

  {

  91

  t y p e d e f struct _ p i l h a _ e x p r

  90

  // E s t r u t u r a de pilha para c o n v e r s a o da e x p r e s s a o em RPN

  89

  88

  } a r v o r e _ e x p r ;

  struct _ a r v o r e _ e x p r * d i r e i t a ; // p o n t e i r o para o e l e m e n t o a e s q u e r d a

  95

  86

  struct _ a r v o r e _ e x p r * e s q u e r d a ; // p o n t e i r o para o e l e m e n t o a d i r e i t a

  85

  token * e l e m e n t o ; // p o n t e i r o para o token que sera i n s e r i d o na arvore

  84

  {

  83

  t y p e d e f struct _ a r v o r e _ e x p r

  82

  // E s t r u t u r a da arvore de e x p r e s s o e s :

  81

  80

  } l i s t a _ e x p r ;

  79

  } p i l h a _ e x p r ;

  96

  p o l i n o m i o * p o l i n o m i o ;

  l i s t a _ e x p r * P ;

  114

  {

  113

  t y p e d e f struct _ v e t o r _ p o l i n o m i o s

  112

  // e s t r u t u r a de vetor de c o m b i n a c a o linear das v a r i a v e i s de e n t ra d a

  110 111

  } p o l i n o m i o ;

  108 109

  int f l a g _ a p p r o v e d ;

  107

  int id ;

  106

  105

  // E s t r u t u r a das pilhas de c o n s t r u c a o da arvore

  {

  104

  t y p e d e f struct _ p o l i n o m i o

  102 103

  } p i l h a _ a r v o r e ;

  101

  struct _ p i l h a _ a r v o r e * p ro x i m o ;

  100

  a r v o r e _ e x p r * node ;

  99

  {

  98

  t y p e d e f struct _ p i l h a _ a r v o r e

  97

  // g l o b ai s

  159 160

  209 210

  218

  l i s t a _ e x p r * s i m p l i f i c a _ e x p r _ e x p a n d i d a ( l i s t a _ e x p r *) ;

  217

  // p r o t o t i p o das f u n c o e s de s i m p l i f i c a d o r de õ e x p r e s s e s

  215 216

  void d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ e x p r *) ;

  214

  l i s t a _ e x p r * m u l t i p l i c a _ e x p r ( l i s t a _ e x p r * , l i s t a _ e x p r *) ;

  213

  l i s t a _ e x p r * c o n s t r o i _ l i s t a _ e x p r e s s o e s _ e x p ( a r v o r e _ e x p r *) ;

  212

  void s t r i n g _ s o r t ( char **) ;

  211

  // p r o t o t i p o das f u n c o e s de e x p a n s o r de e x p r e s s o e s

  void d e s t r o i _ l i s t a _ e x p r ( token *) ;

  219

  204

  201

  token * c o n s t r o i _ l i s t a _ e x p r ( token *) ;

  202

  int p r i o r i d a d e _ o p e r a d o r ( token *) ;

  203

  a r v o r e _ e x p r * c o n s t r o i _ a r v o r e _ e x p r ( token *) ;

  a r v o r e _ e x p r * c r i a _ n o _ a r v o r e ( token *) ;

  208

  205

  int i n s e r e _ p i l h a _ a r v o r e ( p i l h a _ a r v o r e ** , a r v o r e _ e x p r *) ;

  206

  a r v o r e _ e x p r * r e t i r a _ p i l h a _ a r v o r e ( p i l h a _ a r v o r e **) ;

  207

  void d e s t r o i _ a r v o r e _ e x p r ( a r v o r e _ e x p r *) ;

  l i s t a _ e x p r * r e m o v e _ l i s t a _ e x p r ( l i s t a _ e x p r * , l i s t a _ e x p r *) ;

  l i s t a _ e x p r * c o p i a _ l i s t a _ e x p r ( l i s t a _ e x p r *) ;

  199

  v e t o r _ p o l i n o m i o s * g e r a _ v e t o r ( v e t o r _ p o l i n o m i o s * , l i s t a _ e x p r * , l i s t a _ e x p r * , int , int ) ;

  int p a r t i a l _ f r a c t i o n _ e x p a n s i o n ( l i s t a _ e x p r * , l i s t a _ e x p r * , l i s t a _ e x p r * , l i s t a _ e x p r ** , l i s t a _ e x p r ** , l i s t a _ e x p r **) ;

  232

  l i s t a _ e x p r * s u b s t i t u i _ v a r ( l i s t a _ e x p r * , l i s t a _ e x p r * , char ) ;

  233 234

  // p r o t o t i p o das f u n c o e s de g e r a c a o do vetor de p o l i n o m i o s

  235

  236

  // p r o t o t i p o das f u n c o e s de e x p a n s a o em f r a c o e s p a r c i a i s

  v e t o r _ p o l i n o m i o s * e l i m i n a _ z e r o ( v e t o r _ p o l i n o m i o s *) ;

  237

  v e t o r _ p o l i n o m i o s * r e m o v e _ p o l i n o m i o ( v e t o r _ p o l i n o m i o s *) ;

  238

  v e t o r _ p o l i n o m i o s * r e m o v e _ p o l i n o m i o _ r e t o r n a _ a n t e r o r ( v e t o r _ p o l i n o m i o s *) ;

  239

  231

  229 230

  220 221

  int p o l y d i v ( l i s t a _ e x p r * , l i s t a _ e x p r * , l i s t a _ e x p r ** , l i s t a _ e x p r **) ;

  // p r o t o t i p o de f u n c o e s de d i v i s a o p o l i n o m i a l

  222

  int lexdeg ( char * , char *) ;

  223

  l i s t a _ e x p r * l e x d e g b u b b l e s o r t ( l i s t a _ e x p r *) ;

  224

  225

  l i s t a _ e x p r * c o n s t r o i _ e l e m e n t o _ z e r a d o ( void ) ;

  l i s t a _ e x p r * d i v i d e _ m o n o m i o ( l i s t a _ e x p r * , l i s t a _ e x p r *) ;

  226

  void s u b t r a i _ e x p r ( l i s t a _ e x p r ** , l i s t a _ e x p r *) ;

  227

  void s o m a _ e x p r ( l i s t a _ e x p r * , l i s t a _ e x p r *) ;

  228

  void d e s t r o i _ p i l h a ( p i l h a _ e x p r *) ; int i n s e r e _ l i s t a _ e x p r ( token ** , token *) ;

  int i n s e r e _ p i l h a ( p i l h a _ e x p r ** , token *) ;

  // v a r i a v e l global para debug

  3

  175

  3

  # define o p e r a d o r _ m u l t i p l i c a c a o

  174

  2

  # define o p e r a d o r _ m e n o s

  173

  1

  # define o p e r a d o r _ m a i s

  172

  // tipos de o p e r a d o r e s

  170 171

  # define t i p o _ a b r e _ f e c h a 4

  169

  # define t i p o _ o p e r a d o r

  4

  164 165

  161

  int global = 0;

  162

  // c o n t a d o r de f r a c o e s p a r c i a i s e x e c u t a d a s

  163

  u n s i g n e d int g l o b a l _ n u m _ p a r f r a c = 0;

  // d e f i n i c o e s para a struct

  168

  166

  # define t i p o _ l i t e r a l

  1

  167

  # define t i p o _ p a r a m e t r o

  2

  # define o p e r a d o r _ p o t e n c i a c a o

  176

  198

  192

  188 189

  token * c r i a _ t o k e n ( token **) ;

  190

  void d e s t r o i _ l i s t a ( token *) ;

  191

  char i n s e r e _ t a b e l a _ l i t e r a i s ( t a b e l a _ l i t e r a i s ** , char *) ;

  void d e s t r o i _ t a b e l a _ l i t e r a i s ( t a b e l a _ l i t e r a i s *) ;

  187

  193

  void c o n s t r o i _ t a b e l a _ l i t e r a i s ( t a b e l a _ l i t e r a i s ** , token *) ;

  194 195 196

  // p r o t o t i p o das f u n c o e s de c o n s t r u t o r de arvore de e x p r e s s o e s

  197

  token * r e t i r a _ p i l h a ( p i l h a _ e x p r **) ;

  int i s a b r e _ f e c h a ( char ) ;

  int i s o p e r a t o r ( char ) ;

  # define o p e r a d o r _ n e g a c a o

  # define f e c h a _ p a r e n t e s e s

  5

  177 178 179

  // tipos de a b r e _ f e c h a

  180

  # define a b r e _ p a r e n t e s e s

  181

  1

  186

  182 183

  // p r o t o t i p o s de f u n c o e s de a n a l i s e lexica

  184

  void erro ( char * ) ;

  185

  token * l e _ t o k e n s ( char *) ;

  l i s t a _ e x p r * g e r a _ p o l i n o m i o _ b a s e ( t a b e l a _ l i t e r a i s *) ;

  • ) ;

  287

  void i m p r i m e _ d e c o m p o s i c a o ( v e t o r _ d e c o m p * , t a b e l a _ l i t e r a i s *) ;

  294

  void i m p r i m e _ t o k e n s ( token * ) ;

  293

  void i m p r i m e _ a r v o r e _ e x p r ( a r v o r e _ e x p r *) ;

  292

  void p r i n t _ m o n o m i o ( char * , t a b e l a _ l i t e r a i s *) ;

  291

  void i m p r i m e _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ e x p r * , t a b e l a _ l i t e r a i s *) ;

  290

  // p r o t o t i p o das f u n c o e s de i n t e r f a c e

  288 289

  int e x p r _ s i z e ( l i s t a _ e x p r *) ;

  int p o l y _ s i z e ( v e t o r _ p o l i n o m i o s *) ;

  // erro - i m pr i m e uma m e n s a g e m de erro na tela

  286

  int d e c o m p _ s i z e ( v e t o r _ d e c o m p *) ;

  285

  // f u n c oe s de t am a n h o de m e m o r i a

  283 284

  

void e n c o n t r a _ d e c o m p _ p a r c i a l _ s e c u n d a r i a ( v e t o r _ d e c o m p _ s i m p l e * , p o l i n o m i o * , l i s t a _ e x p r * , v e t o r _ p o l i n o m i o s * , int ,

v e t o r _ d e c o m p ** , v e t o r _ d e c o m p _ s i m p l e * , p o l i n o m i o * base_ primario , int * , t a b e l a _ l i t e r a i s * , l i s t a _ e x p r *) ;

  282

  void e n c o n t r a _ d e c o m p _ p a r c i a l _ p r i m a r i a ( v e t o r _ d e c o m p _ s i m p l e * , p o l i n o m i o * , l i s t a _ e x p r * , p o l i n o m i o * , l i s t a _ e x p r * , v e t o r _ p o l i n o m i o s * , int , v e t o r _ d e c o m p ** , int * , t a b e l a _ l i t e r a i s * , l i s t a _ e x p r *) ;

  281

  // f u n c oe s e x p e r i m e n t a i s do a l g o r i t m o do mulder memory safe

  279 280

  v e t o r _ d e c o m p _ s i m p l e * n o v o _ v e t o r _ d e c o m p _ s i m p l e s ( void ) ; void d e s t r o i _ v e t o r _ d e c o m p _ s i m p l e s ( v e t o r _ d e c o m p _ s i m p l e *) ;

  277

  void d e s t r o i _ d e c o m p _ s i m p l e s ( v e t o r _ d e c o m p _ s i m p l e *) ;

  295 296

  297

  v e t o r _ d e c o m p _ s i m p l e * i n s e r e _ d e c o m p _ s i m p l e s ( v e t o r _ d e c o m p _ s i m p l e * , v e t o r _ d e c o m p _ s i m p l e *) ;

  int estado = 0; // v a r i a v e l de estado

  314

// r e p e t ir é at e n c o n t r a r o c a r a c t e r nulo , e c o n t i n u a r o laco se e s t iv e r no meio de um r e c o n h e c i m e n t o de l i t e r a l .

315

  int cont = 0; // c o n t a d o r de c a r a c t e r e s

  313

  int n _ c h a r s ; // c a l c u l o de numero de c a r a c t e r e s de um l i t e r a l

  312

  // v a r i a v e i s para c a l c u l o s t e m p o r a r i o s

  310 311

  token * t o k e n _ a t u a l = NULL ; // p r o x i m o token a ser p r e e n c h i d o ;

  309

  token * l i s t a _ t o k e n = NULL ; // p o n t e i r o para a lista de tokens a ser r e t o r n a d a

  308

  char * i n i c i o _ l i t e r a l = NULL ; // p o n t e i r o t e m p o r a r i o para m a n i p u l a c a o de l i t e r a i s

  307

  306

  void erro ( char * n_erro )

  // o parser e uma m a q u i n a de e s t a d o s que p e r c o r r e a string da ã equaao c a r a c t e r a c a r a c t e r

  305

  {

  304

  token * l e _ t o k e n s ( char * e q u a c a o _ e n t r a d a )

  303

  // l e _ t o k e n s - r e a l i z a o parse da ã equaao de e n tr a d a para c o n s t r u i r uma lista de tokens

  301 302

  }

  300

  printf ( " \ n \ r \ t % s \ n " , n_erro ) ;

  299

  {

  298

  276

  275

  240

  249

  void d e s t r o i _ v e t o r _ d e c o m p ( v e t o r _ d e c o m p *) ;

  255

  void d e s t r o i _ v e t o r _ p o l i n o m i o s ( v e t o r _ p o l i n o m i o s *) ;

  254

  void d e s t r o i _ d e c o m p ( v e t o r _ d e c o m p *) ;

  253

  void i n s e r e _ p o l i n o m i o ( v e t o r _ p o l i n o m i o s ** , p o l i n o m i o *) ;

  252

  v e t o r _ d e c o m p * n o v o _ v e t o r _ d e c o m p ( void ) ;

  251

  v e t o r _ p o l i n o m i o s * n o v o _ v e t o r _ p o l i n o m i o s ( void ) ;

  250

  void d e s t r o i _ l i s t a _ s e m e n t e s ( v e t o r _ s e m e n t e s *) ;

  v e t o r _ s e m e n t e s * n o v o _ v e t o r _ s e m e n t e ( void ) ;

  v e t o r _ d e c o m p * e n c o n t r a _ d e c o m p ( v e t o r _ s e m e n t e s * , int , l i s t a _ e x p r * , t a b e l a _ l i t e r a i s *) ;

  248

  v e t o r _ s e m e n t e s * g e r a _ v e t o r _ s e m e n t e ( v e t o r _ p o l i n o m i o s * , l i s t a _ e x p r *) ;

  247

  int deg ( l i s t a _ e x p r *) ;

  246

  // p r o t o t i p o das f u n c o e s que i m p l e m e n t a m o a l g o r i t m o p r o p r i a m e n t e dito

  244 245

  v e t o r _ p o l i n o m i o s * r e m o v e _ p o l i n o m i o s _ n a o _ p e r t e n c e n t e s ( v e t o r _ d e c o m p * , v e t o r _ p o l i n o m i o s *) ;

  243

  v e t o r _ p o l i n o m i o s * r e c o n t a _ p o l i n o m i o s ( v e t o r _ s e m e n t e s * , v e t o r _ p o l i n o m i o s *) ;

  242

  v e t o r _ p o l i n o m i o s * r e m o v e _ p o l i n o m i o s _ r e d u n d a n t e s ( v e t o r _ p o l i n o m i o s *) ;

  241

  v e t o r _ p o l i n o m i o s * r e m o v e _ p o l i n o m i o s _ n e g a t i v o s ( v e t o r _ p o l i n o m i o s *) ;

  256

  257

  v e t o r _ d e c o m p _ s i m p l e * n o v o _ v e t o r _ d e c o m p _ s i m p l e s ( void ) ;

  int c o m p a r a _ d e c o m p ( v e t o r _ d e c o m p * , v e t o r _ d e c o m p *) ;

  274

  v e t o r _ d e c o m p _ s i m p l e * c o p i a _ d e c o m p _ s i m p l e s ( v e t o r _ d e c o m p _ s i m p l e *) ;

  273

  void e n c o n t r a _ d e c o m p _ p a r c i a l ( v e t o r _ d e c o m p _ s i m p l e * , p o l i n o m i o * , l i s t a _ e x p r * , v e t o r _ p o l i n o m i o s * , int grau , v e t o r _ d e c o m p _ s i m p l e **) ;

  271 272

  v e t o r _ d e c o m p * e n c o n t r a _ d e c o m p _ m u l d e r _ s a f e ( v e t o r _ p o l i n o m i o s * , int , l i s t a _ e x p r * , t a b e l a _ l i t e r a i s *) ;

  270

  v e t o r _ d e c o m p * e n c o n t r a _ d e c o m p _ m u l d e r ( v e t o r _ p o l i n o m i o s * , int , l i s t a _ e x p r * , t a b e l a _ l i t e r a i s *) ;

  269

  void c o m b i n a _ d e c o m p _ m u l d e r ( v e t o r _ d e c o m p _ s i m p l e * , v e t o r _ d e c o m p _ s i m p l e * , p o l i n o m i o * , p o l i n o m i o * , l i s t a _ e x p r * , v e t o r _ d e c o m p ** , int * , t a b e l a _ l i t e r a i s *) ;

  268

  // f u n c oe s que i m p l e m e n t a m o a l g o r i t m o do mulder

  266 267

  265

  int p r o v a _ r e a l ( v e t o r _ d e c o m p * , l i s t a _ e x p r *) ;

  v e t o r _ p o l i n o m i o s * o r d e n a _ p o l i n o m i o s ( v e t o r _ p o l i n o m i o s *) ;

  264

  void e l i m i n a _ d e c o m p _ r e d u n d a n t e s ( v e t o r _ d e c o m p *) ;

  263

  v e t o r _ d e c o m p * c o p i a _ d e c o m p ( v e t o r _ d e c o m p *) ;

  262

  v e t o r _ d e c o m p * c o p i a _ s e m e n t e ( v e t o r _ s e m e n t e s *) ;

  261

  void e n c o n t r a _ d e c o m p _ r e c u r s i v a ( v e t o r _ d e c o m p * , v e t o r _ d e c o m p * , v e t o r _ d e c o m p ** , int , l i s t a _ e x p r * , t a b e l a _ l i t e r a i s * , int

  260

  v e t o r _ d e c o m p * c o p i a _ v e t o r _ s e m e n t e ( v e t o r _ s e m e n t e s *) ;

  259

  v e t o r _ d e c o m p * i n s e r e _ l i s t a _ d e c o m p ( v e t o r _ d e c o m p * , v e t o r _ d e c o m p *) ;

  258

  while (*( e q u a c a o _ e n t r a d a + cont ) != ’ \0 ’ || estado == 2)

  316

  363

  374

  // muda o estado

  371 372 373

  

token_atual - > p a r a m e t r o = ( int ) (*( e q u a c a o _ e n t r a d a + cont ) - ’0 ’) ;

  370

  // comeaa a p r e e n c h e r o numero

  368 369

  token_atual - > tipo = t i p o _ p a r a m e t r o ;

  367

  // p r e e n c h e o tipo

  365 366

  t o k e n _ a t u a l = c r i a _ t o k e n (& l i s t a _ t o k e n ) ;

  364

  // cria um token na lista

  {

  375

  362

  if ( i s d i g i t (*( e q u a c a o _ e n t r a d a + cont ) ) )

  361

  // p a r a m e t r o s

  360

  }

  359

  break ;

  358

  break ; }

  356

  token_atual - > codigo = ’^ ’;

  355

  token_atual - > o p e r a d o r = o p e r a d o r _ p o t e n c i a c a o ;

  estado = 1;

  break ;

  case ’^ ’:

  386 387

  396

  // abre e fecha p a r e n t e s e s

  395

  }

  394

  break ;

  392 393

  estado = 2;

  391

  // muda o estado

  389 390

  token_atual - > l i t e r a l = ( e q u a c a o _ e n t r a d a + cont ) ;

  388

  // marca o inicio do li t e r a l

  token_atual - > tipo = t i p o _ l i t e r a l ;

  376

  385

  // p r e e n c h e o tipo

  383 384

  t o k e n _ a t u a l = c r i a _ t o k e n (& l i s t a _ t o k e n ) ;

  382

  // cria um token na lista

  380 381

  {

  379

  if ( i s a l p h a (*( e q u a c a o _ e n t r a d a + cont ) ) )

  378

  // l i t e r a i s

  377

  }

  354

  353

  {

  {

  // cria um token na lista

  331

  {

  330

  if ( i s o p e r a t o r (*( e q u a c a o _ e n t r a d a + cont ) ) )

  329

  // o p e r a d o r e s m a t e m a t i c o s

  328

  }

  327

  break ;

  326

  // nada é feito

  325

  324

  t o k e n _ a t u a l = c r i a _ t o k e n (& l i s t a _ t o k e n ) ;

  if ( i s s p a c e (*( e q u a c a o _ e n t r a d a + cont ) ) )

  323

  case 0: // estado i ni c i a l

  322

  {

  321

  switch ( estado )

  320

  # endif

  319

  printf ( " \ n % c \ n " ,*( e q u a c a o _ e n t r a d a + cont ) ) ;

  318

  # if d e f i n e d D E B U G _ L E X I C O

  317

  332

  333 334

  break ;

  344

  352

  token_atual - > codigo = ’* ’;

  351

  token_atual - > o p e r a d o r = o p e r a d o r _ m u l t i p l i c a c a o ;

  350

  case ’* ’:

  349

  break ;

  348

  token_atual - > codigo = ’ - ’;

  347

  token_atual - > o p e r a d o r = o p e r a d o r _ m e n o s ;

  345 // a d i f e r e n c i a c a o entre s u b t r a c a o e a o p e r a c a o de n e g a c a o sera t r a t ad a mais tarde . 346

  case ’ - ’:

  break ;

  // p r e e n c h e o tipo

  339

  335

  token_atual - > tipo = t i p o _ o p e r a d o r ;

  336 337

  // d e s c o b r e qual o o p e r a d o r e p r e e n c h e na e s t r u t u r a

  338

  switch (*( e q u a c a o _ e n t r a d a + cont ) )

  {

  343

  340

  case ’+ ’:

  341

  token_atual - > o p e r a d o r = o p e r a d o r _ m a i s ;

  342

  token_atual - > codigo = ’+ ’;

  if ( i s a b r e _ f e c h a (*( e q u a c a o _ e n t r a d a + cont ) ) ) break ;

  476

  break ;

  

// aloca m e m o r i a para o l i t e r a l e n c o n t r a d o com espaao para o t e r m i n a d o r nulo

  454 455

  n _ c h a r s = ( int ) (( e q u a c a o _ e n t r a d a + cont ) - i n i c i o _ l i t e r a l ) ;

  453

  // c a l c u la o numero de c a r a c t e r e s n e c e s s a r i o s

  451 452

  i n i c i o _ l i t e r a l = token_atual - > l i t e r a l ;

  450

  // salva a ã posiao do inico do l i t e r a l

  449

  {

  448

  else

  447

  446

  

if (( token_atual - > l i t e r a l = ( char *) malloc (( n _ c h a r s + 1) * sizeof ( char ) ) ) == NULL )

  }

  // q u a l q u e r outra coisa s i g n i f i c a que o numero ja foi lido

  437

  // volta o caracter , para que seja lido no p r o x i m o loop cont - -;

  439

  estado = 0;

  440

  441

  if ( i s d i g i t (*( e q u a c a o _ e n t r a d a + cont ) ) || i s a l p ha (*( e q u a c a o _ e n t r a d a + cont ) ) || (*( e q u a c a o _ e n t r a d a + cont ) == ’_ ’) )

  break ;

  442 443

  case 2: // l i t e r a l

  444

  // se o p r o x i m o for digito ou letra , ou _ , c o n t i n u a r lendo

  445

  456

  457

  {

  466

  estado = 0;

  475

  cont - -;

  474

  // volta o caracter , para que seja lido no p r o x i m o loop

  472 473

  471

  // coloca o t e r m i n a d o r nulo

  469 470

  }

  468

  return ( NULL ) ;

  467

  d e s t r o i _ l i s t a ( l i s t a _ t o k e n ) ;

  erro ( E R R O _ 0 0 1 ) ;

  {

  461

  458

  erro ( E R R O _ 0 0 1 ) ;

  459

  d e s t r o i _ l i s t a ( l i s t a _ t o k e n ) ;

  460

  return ( NULL ) ;

  }

  465

  462

  // copia a string do li t e r a l ;

  463

  if (( s t r n c p y ( token_atual - > literal , i n i c i o _ l i t e r a l , n _ c h a r s ) ) == NULL )

  464

  {

  436

  435

  397

  case ’( ’:

  break ;

  413

  token_atual - > codigo = ’) ’;

  412

  token_atual - > a b r e _ f e c h a = f e c h a _ p a r e n t e s e s ;

  411

  case ’) ’:

  410

  break ;

  409

  token_atual - > codigo = ’( ’;

  408

  token_atual - > a b r e _ f e c h a = a b r e _ p a r e n t e s e s ;

  407

  406

  }

  // p r e e n c h e o tipo

  {

  398

  // cria um token na lista

  399

  t o k e n _ a t u a l = c r i a _ t o k e n (& l i s t a _ t o k e n ) ;

  400 401

  402

  {

  token_atual - > tipo = t i p o _ a b r e _ f e c h a ;

  403

  // d e s c o b r e qual o o p e r a d o r e p r e e n c h e na e s t r u t u r a

  404

  switch (*( e q u a c a o _ e n t r a d a + cont ) )

  405

  414

  415

  else

  425 426

  434

  }

  433

  token_atual - > p a r a m e t r o += ( int ) (*( e q u a c a o _ e n t r a d a + cont ) - ’0 ’) ;

  432

  token_atual - > p a r a m e t r o *= 10;

  431

  {

  430

  if ( i s d i g i t (*( e q u a c a o _ e n t r a d a + cont ) ) )

  428 429

  // se o p r o x i m o c a r a c t e r é um digito , m u l t i p l i c a r o p a r a m e t r o atual por 10 e a d i c i o n a r o digito

  427

  case 1: // numero

  break ;

  break ;

  420

  416

  }

  417 418

  // se ã no e n c o n t r a r nenhum dos c a r a c t e r e s esprados , a ã equaao á est errada

  419

  d e s t r o i _ l i s t a ( l i s t a _ t o k e n ) ;

  erro ( E R R O _ 0 0 3 ) ;

  424

  421

  // i m p r i m i r é tamm a e q u a c a o a partir do erro

  422

  printf ( " -> % s \ n " ,( e q u a c a o _ e n t r a d a + cont ) ) ;

  423

  return ( NULL ) ;

  • ( token_atual - > l i t e r a l + n _c h a r s ) = ’ \0 ’;

  477

  if (( token_atual - > p r o x i m o _ t o k e n = ( token *) malloc ( sizeof ( token ) ) ) != NULL )

  {

  531

  t o k e n _ a t u a l = token_atual - > p r o x i m o _ t o k e n ;

  532

  }

  533

  534

  while ( token_atual - > p r o x i m o _ t o k e n != NULL )

  {

  535

  token_atual - > pr oximo_token - > p r o x i m o _ t o k e n = NULL ;

  536

  token_atual - > pr oximo_token - > tipo = 0;

  537

  530

  529

  538

  }

  (* l i s t a _ t o k e n ) -> o p e r a d o r = 0;

  521

  (* l i s t a _ t o k e n ) -> a b r e _ f e c h a = 0;

  522 523

  return (* l i s t a _ t o k e n ) ;

  524

  525

  t o k e n _ a t u a l = (* l i s t a _ t o k e n ) ;

  }

  526

  else

  527

  {

  528

  token_atual - > pr oximo_token - > l i t e r a l = NULL ;

  token_atual - > pr oximo_token - > p a r a m e t r o = 0;

  (* l i s t a _ t o k e n ) -> p a r a m e t r o = 0;

  if ( lista - > p r o x i m o _ t o k e n != NULL )

  void d e s t r o i _ l i s t a ( token * lista )

  550

  {

  551

  // p e r c o r r e a lista r e c u r s i v a m e n t e é at e n c o n t r a r o ultimo e l e m e n t o

  552

  553

  // d e s t ro i lista - ã funao para d e s t r u i r todos os p o n t e i r o s da lista em caso de erro ou fim do p r o g r a m a

  {

  554

  d e s t r o i _ l i s t a ( lista - > p r o x i m o _ t o k e n ) ;

  555

  }

  556 // d e s t r oi os p o n t e i r o s dos l i t e r a i s e dos p r o p r i o s tokens nos r e t o r n o s das c h a m a d a s r e c u r s i v a s . 557

  549

  547 548

  539

  }

  token_atual - > pr oximo_token - > o p e r a d o r = 0;

  540

  token_atual - > pr oximo_token - > a b r e _ f e c h a = 0;

  541

  return ( token_atual - > p r o x i m o _ t o k e n ) ;

  542

  543

  }

  }

  544

  // se oc o r r e u um erro apenas r e to r n a NULL

  545

  return ( NULL ) ;

  546

  520

  519

  }

  492

  489

  int i s o p e r a t o r ( char digito )

  490

  {

  491

  if (( digito == ’+ ’) || ( digito == ’ - ’) || ( digito == ’* ’) || ( digi to == ’^ ’) )

  return TRUE ;

  487 488

  493

  else

  494

  return FALSE ;

  495

  }

  // i s o p e r a t o r - v e r i f i c a se o c a r a c t e r é um o p e r a d o r á m a t e m t i c o

  }

  // i s o a b r e _ f e c h a - v e r i f i c a se o c a r a c t e r é um abre ou fecha p a r e n t e s e s

  482

  478

  break ;

  479 480

  }

  481

  // p ro x i m o c a r a c t e r a ser lido

  cont ++;

  486

  483

  }

  484

  // r e t o r na a lista de tokens

  485

  return ( l i s t a _ t o k e n ) ;

  496 497

  498

  (* l i s t a _ t o k e n ) -> tipo = 0; (* l i s t a _ t o k e n ) -> l i t e r a l = NULL ;

  {

  token * t o k e n _ a t u a l ; // v a r i a v e l para p e r c o r r e r a lista

  510 511

  // v e r i f i c a se a lista esta vazia e a cria se á n e c e s s r i o

  512

  if ((* l i s t a _ t o k e n ) == NULL )

  513

  514

  {

  if (((* l i s t a _ t o k e n ) = ( token *) malloc ( sizeof ( token ) ) ) != NULL )

  515

  {

  516

  (* l i s t a _ t o k e n ) -> p r o x i m o _ t o k e n = NULL ;

  517

  509

  508

  int i s a b r e _ f e c h a ( char digito )

  502

  499

  {

  500

  if (( digito == ’( ’) || ( digito == ’) ’) )

  501

  return TRUE ;

  else

  token * c r i a _ t o k e n ( token ** l i s t a _ t o k e n )

  503

  return FALSE ;

  504

  }

  505 506

  // c r i a _ t o k e n - aloca m e m or i a para um novo token no fim da fila e r e t o r n a o p o n t e i r o para ele

  507

  if ( lista - > l i t e r a l != NULL )

  558

  {

  559

  free ( lista - > l i t e r a l ) ;

  560

  }

  561

  lista - > l i t e r a l = NULL ;

  562

  lista - > p r o x i m o _ t o k e n = NULL ;

  563

  free ( lista ) ;

  564

  }

  565 566

  // p e r c o r r e a lista i m p r i m i n d o os tokens e n c o n t r a d o s

  567

  void i m p r i m e _ t o k e n s ( token * l i s t a _ t o k e n )

  568

  {

  569

  int c o n t a d o r = 0;

  570

  token * p _ l i s t a = l i s t a _ t o k e n ;

  571 572

  while ( p _ l i s t a != NULL )

  573

  {

  574

  switch ( p_lista - > tipo )

  575

  {

  576

  case t i p o _ l i t e r a l :

  577

  printf ( " #% d l i t e r a l \"% s \"\ n \ r " , contador , p_lista - > l i t e r a l ) ;

  578

  c o n t a d o r ++;

  579

  break ;

  580 581

  case t i p o _ p a r a m e t r o :

  582

  printf ( " #% d p a r a m e t r o \"% d \"\ n \ r " , contador , p_lista - > p a r a m e t r o ) ;

  583

  c o n t a d o r ++;

  584

  break ;

  585

  case t i p o _ o p e r a d o r :

  586

  printf ( " #% d o p e r a d o r \"% c \"\ n \ r " , contador , p_lista - > co digo ) ;

  587

  c o n t a d o r ++;

  588

  break ;

  589

  case t i p o _ a b r e _ f e c h a :

  590

  printf ( " #% d a b r e _ f e c h a \"% c \"\ n \ r " , contador , p_lista - > codigo ) ;

  591

  c o n t a d o r ++;

  592

  break ;

  593 594

  }

  595

  p _ l i s t a = p_lista - > p r o x i m o _ t o k e n ;

  596

  }

  597

  }

  598

  // c r i a _ t a b l e a _ l i t e r a i s - aloca m e m o r i a para um novo l i t e r al e r e t o r n a o seu codigo

  600

  char i n s e r e _ t a b e l a _ l i t e r a i s ( t a b e l a _ l i t e r a i s ** l i s t a _ l i t e r a i s , char * l i t e r a l )

  601

  {

  602

  t a b e l a _ l i t e r a i s * c o d i g o _ a t u a l ; // v a r i a v e l para p e r c o r r e r a lista

  603 604

  // v e r i f i c a se a lista á est vazia e a cria se á n e c e s s r i o

  605

  if ((* l i s t a _ l i t e r a i s ) == NULL )

  606

  {

  607

  

if (((* l i s t a _ l i t e r a i s ) = ( t a b e l a _ l i t e r a i s *) malloc ( sizeof ( t a b e l a _ l i t e r a i s ) ) ) != NULL )

  608

  {

  609

  // alocar m e m o r i a e copiar a string

  610

  (* l i s t a _ l i t e r a i s ) -> l i t e r a l = ( char *) malloc ( strlen ( l i t e r a l ) +1) ; // TODO : erro a l o c a c a o m e m o r i a

  611

  strcpy ((* l i s t a _ l i t e r a i s ) -> literal , l i te r a l ) ;

  612

  (* l i s t a _ l i t e r a i s ) -> codigo = ’A ’; // o p r i m e i r o

  613

  (* l i s t a _ l i t e r a i s ) -> p r o x i m o _ c o d i g o = NULL ;

  614 615

  return ((* l i s t a _ l i t e r a i s ) -> codigo ) ;

  616

  }

  617

  }

  618

  else

  619

  {

  620

  c o d i g o _ a t u a l = (* l i s t a _ l i t e r a i s ) ;

  621 622

  while (1)

  623

  {

  624

  // p r o cu r a se o ó cdigo á j ã no existe

  625

  if ( ! strcmp ( codigo_atual - > literal , l i t e r a l ) )

  626

  return ( codigo_atual - > codigo ) ;

  627 628

  if ( codigo_atual - > p r o x i m o _ c o d i g o == NULL )

  629

  break ;

  630

  else

  631

  c o d i g o _ a t u a l = codigo_atual - > p r o x i m o _ c o d i g o ;

  632

  }

  633 634 635

  if (( codigo_atual - > p r o x i m o _ c o d i g o = ( t a b e l a _ l i t e r a i s *) ma lloc ( sizeof ( t a b e l a _ l i t e r a i s ) ) ) != NULL )

  636

  {

  637

  codigo_atual - > p r o x i m o _ c o d i g o - > p r o x i m o _ c o d i g o = NULL ;

  638

  // alocar m e m o r i a e fazer uma s t r i n g c o p y

  }

  686

  695

  {

  694

  void d e s t r o i _ p i l h a ( p i l h a _ e x p r * p i l h a _ d e s t r u i d a )

  693

  // d e s t r u i c a o de pilhas

  691 692

  // F u n c oe s de m a n i p u l a c a o da pilha

  689 690

  }

  688

  }

  687

  p _ l i s t a = p_lista - > p r o x i m o _ t o k e n ;

  }

  696

  685

  # endif

  684

  printf ( " # codigo :% c l i t e ra l \"% s \"\ n \ r " , codigo , p_lista - > l i t e r al ) ;

  683

  # if d e f i n e d D E B U G _ L E X I C O

  682

  p_lista - > codigo = codigo ;

  681

  codigo = i n s e r e _ t a b e l a _ l i t e r a i s ( l i s t a _ l i t e r a i s , p_lista - > l i t e r a l ) ; // tem que trocar a string do token apenas pelo codigo na lista de tokens , senao isso nao faz s e n t i d o .

  679

  {

  678

  if ( p_lista - > tipo == t i p o _ l i t e r a l )

  if ( p i l h a _ d e s t r u i d a - > p r o x i m o != NULL )

  d e s t r o i _ p i l h a ( p i l h a _ d e s t r u i d a - > p r o x i m o ) ;

  {

  if ( t o p o _ p i l h a == NULL )

  718 719

  return (1) ; // s u c es s o

  716 717

  715

  topo_pilha - > p r o x i m o = * pilha ;

  714

  // p o s i c i o n a o novo e l e m e n t o no topo da pilha

  712 713

  topo_pilha - > e l e m e n t o = e l e m e n t o ;

  711

  // aponta o e l e m e n t o da pilha para o token a d e q u a d o

  709 710

  return (0) ; // houve erro de falta de m e m o r i a

  708

  707

  697

  int i n s e r e _ p i l h a ( p i l h a _ e x p r ** pilha , token * e l e m e n t o )

  free ( p i l h a _ d e s t r u i d a ) ;

  698

  }

  699 700

  // i n s e ri r um e l e m e n t o na pilha

  701

  702

  t o p o _ p i l h a = ( p i l h a _ e x p r *) malloc ( sizeof ( p i l h a _ e x p r ) ) ;

  {

  703

  p i l h a _ e x p r * t o p o _ p i l h a ;

  704 705

  // aloca m e m o r i a para o p r o x i m o e l e m e n t o

  706

  677

  676

  639

  }

  return ( ’ \0 ’) ;

  654

  // se oc o r r e u um erro apenas r e to r n a NULL

  653

  }

  652

  }

  651

  return ( codigo_atual - > p r o x i m o _ c o d i g o - > codigo ) ;

  650

  codigo_atual - > p r o x i m o _ c o d i g o - > codigo = codigo_atual - > codigo + 1;

  649

  else

  648

  647

  }

  codigo_atual - > p r o x i m o _ c o d i g o - > codigo = ’a ’;

  codigo_atual - > p r o x i m o _ c o d i g o - > l i t e r a l = ( char *) malloc ( strlen ( l i t e r a l ) +1) ; // TODO : erro a l o c a c a o m e m o r i a

  640

  strcpy ( codigo_atual - > p r o x i m o _ c o d i g o - > literal , l i t e r a l ) ;

  641

  if ( codigo_atual - > codigo == ’Z ’) // passar para as letras m i n u s c u l a s

  642

  643

  return (0) ;

  else if ( codigo_atual - > codigo == ’z ’) // e s t o u r o de c o d i g o s

  644

  {

  645

  erro ( E R R O _ 0 0 4 ) ;

  646

  655

  656

  while ( p _ l i s t a != NULL )

  666

  674 675

  char codigo ;

  673

  token * p _ l i s t a = l i s t a _ t o k e n ;

  672

  {

  671

  void c o n s t r o i _ t a b e l a _ l i t e r a i s ( t a b e l a _ l i t e r a i s ** l i s t a _ l i t e r a i s , token * l i s t a _ t o k e n )

  670

  // p e r c o r r e a lista i m p r i m i n d o os tokens e n c o n t r a d o s

  668 669

  }

  667

  free ( l i s t a _ l i t e r a i s ) ;

  free ( l i s t a _ l i t e r a i s - > l i t e r a l ) ;

  // d e s t ro i lista - ã funao para d e s t r u i r todos os p o n t e i r o s da lista em caso de erro ou fim do p r o g r a m a

  660

  657

  void d e s t r o i _ t a b e l a _ l i t e r a i s ( t a b e l a _ l i t e r a i s * l i s t a _ l i t e r a i s )

  658

  {

  659

  // p e r c o r r e a lista r e c u r s i v a m e n t e é at e n c o n t r a r o ultimo e l e m e n t o

  if ( l i s t a _ l i t e r a i s - > p r o x i m o _ c o d i g o != NULL )

  664 // d e s t r oi os e l e m e n t o s de forma r e c u r s i v a . 665

  661

  {

  662

  d e s t r o i _ t a b e l a _ l i t e r a i s ( l i s t a _ l i t e r a i s - > p r o x i m o _ c o d i g o ) ;

  663

  }

  • pilha = t o p o _ p i l h a ;
  • pilha = t o p o _ p i l h a ;

  720 721

  if ( p_lista - > proximo_tok en - > tipo == t i p o _ o p e r a d o r )

  // devo v e r i f i c a r a p r e c e d e n c i a do o p e r a d o r ( quanto menor o valor , maior a p r e c e d e n c i a ) e i n s e r i r na pilha d i r e t a m e n t e se o novo e s t i v e r p r i o r i d a d e maior em r e l a c ao ao topo da pilha .

  775

  p_lista - > o p e r a d o r = o p e r a d o r _ n e g a c a o ;

  774

  if ( f l a g _ u n a r i o && ( p_lista - > o p e r a d o r == o p e r a d o r _ m e n o s ) )

  773

  // unario : devo v e r i f i c a r a flag_unario , caso seja 1 , e for um o p e r a d o r ’ - ’ , s i g n i f i c a que e um o p e r a d o r unario no inicio da e x p r e s s a o

  772

  p_lista - > proximo_to ken - > o p e r a d o r = o p e r a d o r _ n e g a c a o ;

  771

  if ( p_lista - > p roximo_token - > o p e r a d o r == o p e r a d o r _ m e n o s )

  770

  769

  if (( p i l h a _ o p e r a d o r e s != NULL ) && ( p r i o r i d a d e _ o p e r a d o r ( p _ l i s t a ) < p r i o r i d a d e _ o p e r a d o r ( p i l h a _ o p e r a d o r e s - > e l e m e n t o ) ) )

  if ( p_lista - > p r o x i m o _ t o k e n != NULL )

  768

  // e devo m o d i f i c a r o token s e g u i n t e

  767

  // unario : caso e s p e c i a l . Se e n c o n t r o u um o p e r a d o r qualquer , e o p r o x i m o token e o o p e r a d o r ’ - ’ , s i g n i f i c a que e uma o p e r a c a o unaria ,

  766

  case t i p o _ o p e r a d o r :

  764 765

  break ;

  763

  i n s e r e _ l i s t a _ e x p r (& l i s t a _ e x p r e s s a o , p _ l i s t a ) ;

  762

  case t i p o _ p a r a m e t r o : case t i p o _ l i t e r a l : // pilha de o p e r a n d o s

  776

  777

  {

  785

  793

  // unario : caso e s p e c i a l . Se o p r o x i m o token e o o p e r a d o r ’ - ’ , apos abre parenteses , s i g n i f i c a que e uma o p e r a c a o unaria ,

  792

  case t i p o _ a b r e _ f e c h a : // p r e c e d e n c i a de p a r e n t e s e s

  790 791

  break ;

  789

  }

  787 788

  i n s e r e _ p i l h a (& p i l h a _ o p e r a d o r e s , p _ l i s t a ) ;

  786

  // i n s e r ir o novo o p e r a d o r na pilha

  i n s e r e _ l i s t a _ e x p r (& l i s t a _ e x p r e s s a o , r e t i r a _ p i l h a (& p i l h a _ o p e r a d o r e s ) ) ;

  {

  784

  while (( p i l h a _ o p e r a d o r e s != NULL ) && ( p r i o r i d a d e _ o p e r a d o r ( p _ l i s t a ) >= p r i o r i d a d e _ o p e r a d o r ( p i l h a _ o p e r a d o r e s - > e l e m e n t o ) ) )

  783

  {

  782

  // caso contrario , devo r e m o v e r todos os o p e r a d o r e s da pilha de maior p r i o r i d a d e e i n s e r ir o novo o p e r a d o r na pilha

  781

  else

  780

  }

  779

  i n s e r e _ p i l h a (& p i l h a _ o p e r a d o r e s , p _ l i s t a ) ;

  778

  760

  759

  // r e t i ra r um e l e m e n t o da pilha

  731

  return ( e l e m e n t o ) ;

  740

  // r e t o r na o e l e m e n t o

  738 739

  737

  // a t u a l i z a o topo da pilha

  735 736

  free (* pilha ) ;

  734

  // d e s t r oi o p o n t e i r o a ser r e m o v i d o

  732 733

  t o p o _ p i l h a = (* pilha ) -> p r o x i m o ;

  // guarda o novo topo da pilha

  }

  729 730

  e l e m e n t o = (* pilha ) -> e l e m e n t o ;

  728

  // guarda o token que sera r e t o r n a d o

  726 727

  p i l h a _ e x p r * t o p o _ p i l h a ;

  725

  token * e l e m e n t o ;

  724

  {

  723

  token * r e t i r a _ p i l h a ( p i l h a _ e x p r ** pilha )

  722

  741

  742 743

  switch ( p_lista - > tipo )

  751

  758

  {

  757

  while ( p _ l i s t a != NULL )

  755 756

  // e n q u a n t o nao chegar ao final da lista , iterar :

  754

  int f l a g _ u n a r i o = 1;

  753

  // flag para d e t e c c a o de o e p r a d o r n e g a t i v o unario no inicio da e x p r e s s a o

  752

  token * l i s t a _ e x p r e s s a o = NULL ;

  // crio a lista de nos da arvore de e x p r e s s o e s

  // c o n s t r u i r pilha de o p e r a n d o s e o p e r a d o r e s

  750

  p i l h a _ e x p r * p i l h a _ o p e r a d o r e s = NULL ;

  749

  // crio a pilha de o p e r a d o r e s

  748

  token * p _ l i s t a = l i s t a _ t o k e n ;

  747

  // crio uma v a r i a v e l para p e r c o r r e r a lista de tokens

  746

  {

  745

  token * c o n s t r o i _ l i s t a _ e x p r ( token * l i s t a _ t o k e n )

  744

  // e devo m o d i f i c a r o token s e g u i n t e

  794

  // abre p a r e n t e s e s e i n s e r i d o na pilha , mas jamais sera c o l o c a d o na lista de expressao , serve apenas como c o n t r o l e

  795

  if ( p_lista - > a b r e _ f e c h a == a b r e _ p a r e n t e s e s )

  796

  {

  797

  if ( p_lista - > p r o x i m o _ t o k e n != NULL )

  798

  if ( p_lista - > p roximo_token - > tipo == t i p o _ o p e r a d o r )

  799

  if ( p_lista - > proximo_toke n - > o p e r a d o r == o p e r a d o r _ m e n o s )

  800

  

p_lista - > proximo_tok en - > o p e r a d o r = o p e r a d o r _ n e g a c a o ;

  801

  i n s e r e _ p i l h a (& p i l h a _ o p e r a d o r e s , p _ l i s t a ) ;

  802

  }

  803

  else if ( p_lista - > a b r e _ f e c h a == f e c h a _ p a r e n t e s e s )

  804

  // se for fecha parenteses , tenho que r e t i r a r todos os o p e r a d o r e s ate e n c o n t r a r o abre - p a r e n t e s e s na pilha , e coloca - los na lista

  805

  {

  806

  while ( p i l h a _ o p e r a d o r e s - > elemento - > tipo != t i p o _ a b r e _ f e c h a )

  807

  {

  808

  

// retiro um o p e r a d o r da pilha e coloco no fim da lista de e x p r e s s a o

  809

  

i n s e r e _ l i s t a _ e x p r (& l i s t a _ e x p r e s s a o , r e t i r a _ p i l h a (& p i l h a _ o p e r a d o r e s ) ) ;

  810 811

  // se r e t i r o u o ultimo e l e m e n t o da pilha sem e n c o n t r a r abre - fecha , erro de p a r e n t e e s

  812

  if ( p i l h a _ o p e r a d o r e s == NULL )

  813

  {

  814

  // erro p a r e n t e s e s mal c o l o c a d o s

  815

  return NULL ;

  816

  }

  817

  }

  818

  // retiro o abre p a r e n t e s e s que sobrou na pilha

  819

  if ( p i l h a _ o p e r a d o r e s - > elemento - > a b r e _ f e c h a == a b r e _ p a r e n t e s e s )

  820

  r e t i r a _ p i l h a (& p i l h a _ o p e r a d o r e s ) ;

  821

  }

  822

  break ;

  823 824

  }

  825 // limpa o flag_unario , pois ja nao e s t a m o s mais no p r i m e i r o token . 826

  f l a g _ u n a r i o = 0;

  827

  p _ l i s t a = p_lista - > p r o x i m o _ t o k e n ;

  828 829

  }

  830

  // d e s e m p i l h a r todos os o p e r a d o r e s r e s t a n t e s

  831

  while ( p i l h a _ o p e r a d o r e s != NULL )

  832

  { i n s e r e _ l i s t a _ e x p r (& l i s t a _ e x p r e s s a o , r e t i r a _ p i l h a (& p i l h a _ o p e r a d o r e s ) ) ;

  834

  }

  835

  return ( l i s t a _ e x p r e s s a o ) ;

  836

  }

  837 838

  void i m p r i m e _ l i s t a _ e x p r ( token * lista )

  839

  {

  840

  token * p _ l i s t a = lista ;

  841 842

  // titulo

  843

  printf ( " \ n A e x p r e s s a o em f o r m a t o RNP e : " ) ;

  844

  while ( p _ l i s t a != NULL )

  845

  {

  846

  switch ( p_lista - > tipo )

  847

  {

  848

  case t i p o _ l i t e r a l :

  849

  printf ( " % s " , p_lista - > l i t e r a l ) ;

  850

  break ;

  851 852

  case t i p o _ p a r a m e t r o :

  853

  printf ( " % d " , p_lista - > p a r a m e t r o ) ;

  854

  break ;

  855 856

  case t i p o _ o p e r a d o r :

  857

  case t i p o _ a b r e _ f e c h a :

  858 859

  printf ( " % c " , p_lista - > codigo ) ;

  860

  break ;

  861 862

  }

  863

  p _ l i s t a = p_lista - > p r o x i m o _ t o k e n ;

  864

  }

  865

  }

  866 867

  // i n s e ri r um e l e m e n t o na lista e n c a d e a d a dupla d e x p r e s s o e s

  868

  int i n s e r e _ l i s t a _ e x p r ( token ** lista , token * e l e m e n t o )

  869

  {

  870

  token * p _ l i s t a = * lista ;

  871

  token * f i m _ l i s t a = NULL ;

  872

  • lista = f i m _ l i s t a ;

  924

  932

  {

  931

  void d e s t r o i _ l i s t a _ e x p r ( token * lista )

  930

  // d e s t ro i lista - funcao para d e s t r u i r todos os p o n t e i r o s da lista em caso de erro ou fim do p r o g r a m a

  928 929

  }

  927

  return (0) ;

  926

  }

  925

  return (1) ;

  case o p e r a d o r _ p o t e n c i a c a o :

  933

  919

  916

  case o p e r a d o r _ m a i s :

  917

  case o p e r a d o r _ m e n o s :

  918

  return (4) ;

  case o p e r a d o r _ m u l t i p l i c a c a o :

  923

  920

  return (3) ;

  921

  case o p e r a d o r _ n e g a c a o :

  922

  return (2) ;

  // p e r c o r r e a lista r e c u r s i v a m e n t e é at e n c o n t r a r o ultimo e l e m e n t o

  if ( lista - > p r o x i m o _ t o k e n != NULL )

  915

  a r v o r e _ e x p r * t e m p _ n o d e = NULL ;

  {

  946

  token * p _ l i s t a = lista ;

  947

  p i l h a _ a r v o r e * pilha = NULL ;

  948

  949

  a r v o r e _ e x p r * c o n s t r o i _ a r v o r e _ e x p r ( token * lista )

  // p e r c o r r e a lista da e x p r e s s a o RPN c o n s t r u i n d o a pilha de arvore

  950

  while ( p _ l i s t a != NULL )

  951

  {

  952

  945

  944

  934

  lista - > l i t e r a l = NULL ;

  {

  935

  d e s t r o i _ l i s t a _ e x p r ( lista - > p r o x i m o _ t o k e n ) ;

  936

  }

  937

  938

  // funcao que c o n s t r o i a arvore b i n a r i a de e x p r e s s o e s a partir da e x p r e s s a o RPN gerada

  lista - > p r o x i m o _ t o k e n = NULL ;

  939

  free ( lista ) ;

  940

  }

  941 942 943

  {

  switch ( elemento - > o p e r a d o r )

  873

  888

  {

  885

  886

  return (1) ; // s u c e s s o

  887

  }

  else

  if (* lista == NULL )

  889

  {

  890

  // p e r c o r r e a lista ate o final

  891

  while ( p_lista - > p r o x i m o _ t o k e n != NULL )

  884

  883

  {

  return (0) ; // houve erro de falta de m e m o r i a

  // aloca m e m o r i a para o novo e l e m e n t o

  874

  f i m _ l i s t a = ( token *) malloc ( sizeof ( token ) ) ;

  875

  if ( f i m _ l i s t a == NULL )

  876

  877 878

  // se a lista e s t i v e r vazia , r e t o r n a r o e l e m e n t o criado

  // p r e e n c h e os campos do e l e m e n t o

  879

  memcpy ( fim_lista , elemento , sizeof ( token ) ) ;

  880

  fim_lista - > p r o x i m o _ t o k e n = NULL ;

  881 882

  892

  893

  914

  909

  906

  // se tentar c o m p a r a r com um token i n e x i s t e n t e

  907

  if ( e l e m e n t o == NULL )

  908

  return (99) ;

  // p a r e n t e s e s sempre tem p r i o r i d a d e maior

  905

  910

  if ( elemento - > tipo == t i p o _ a b r e _ f e c h a )

  911

  return (99) ;

  912

  else // caso sejam o p e r a d o r e s

  {

  int p r i o r i d a d e _ o p e r a d o r ( token * e l e m e n t o )

  p _ l i s t a = p_lista - > p r o x i m o _ t o k e n ;

  898 899

  894

  }

  895 896

  // aponta o p o n t e i r o a n t e r i o r do novo e l e m e n t o para o final da lista , e vice - versa

  897

  p_lista - > p r o x i m o _ t o k e n = f i m _ l i s t a ;

  return (1) ; // s u c e s s o

  904

  900

  }

  901

  }

  902 903

  // p r i o r i d a d e _ o p e r a d o r -> funcao que r e t o r n a a p r e c e d e n c i a do oeprador , sendo que um numero menor s i g n i g f i c a maior p r i o r i d a d e

  switch ( p_lista - > tipo ) if (* pilha != NULL )

  1031 1032

  1001

  int i n s e r e _ p i l h a _ a r v o r e ( p i l h a _ a r v o r e ** pilha , a r v o r e _ e x p r * e l e m e n t o )

  1009

  // i n s e ri r um e l e m e n t o na pilha

  1007 1008

  }

  1006

  return ( n o v o _ no ) ;

  1004 1005

  novo_no - > e s q u e r d a = NULL ;

  1003

  novo_no - > di r e i t a = NULL ;

  1002

  novo_no - > e l e m e n t o = e l e m e n t o ;

  // aponta o no da pilha para o e l e m e n t o e i n i c i a l i z a o resto da e s t r u t u r a node

  {

  1000

  return (0) ; // houve erro de falta de m e m o r i a

  999

  if ( n o v o _ n o == NULL )

  998

  n o v o _ n o = ( a r v o r e _ e x p r *) malloc ( sizeof ( a r v o r e _ e x p r ) ) ;

  997

  // aloca m e m o r i a para o p r o x i m o e l e m e n t o

  996

  a r v o r e _ e x p r * n o v o _ n o ;

  995

  {

  994

  a r v o r e _ e x p r * c r i a _ n o _ a r v o r e ( token * e l e m e n t o )

  1010

  1011

  }

  1022

  p i l h a _ a r v o r e * t o p o _ p i l h a ;

  1030

  a r v o r e _ e x p r * e l e m e n t o ;

  1029

  {

  1028

  a r v o r e _ e x p r * r e t i r a _ p i l h a _ a r v o r e ( p i l h a _ a r v o r e ** pilha )

  1027

  // r e t i ra r um e l e m e n t o da pilha

  1025 1026

  }

  1023 1024

  return (1) ; // s u c es s o

  1021

  p i l h a _ a r v o r e * t o p o _ p i l h a = NULL ;

  topo_pilha - > p r o x i m o = * pilha ;

  1020

  topo_pilha - > node = e l e m e n t o ;

  1019

  // p o s i c i o n a o novo e l e m e n t o no topo da pilha

  1017 1018

  // cria um novo e l e m e n t o na pilha

  1016

  return (0) ; // erro

  1015

  if ( t o p o _ p i l h a == NULL )

  1014

  t o p o _ p i l h a = ( p i l h a _ a r v o r e *) malloc ( sizeof ( p i l h a _ a r v o r e ) ) ;

  1012 1013

  992

  991

  953

  961 962

  temp_node - > e s q u e r d a = NULL ;

  969

  temp_node - > d i r e i t a = r e t i r a _ p i l h a _ a r v o r e (& pilha ) ;

  968

  {

  967

  if ( p_lista - > o p e r a d o r == o p e r a d o r _ n e g a c a o )

  966

  // unario : Para o p e r a c o e s n e g ac a o unaria , p r e e n c h o apenas o no da d i r e i t a

  964 965

  t e m p _ n o d e = c r i a _ n o _ a r v o r e ( p _ l i s t a ) ;

  963

  // c o n s t r u i r o node do o p e r a d o r

  // para operadores , r e t i r a r os u l t i m o s 2 nos de arvore , criar uma arvore a partir deles e re - i n s e r i r na pilha

  }

  960

  case t i p o _ o p e r a d o r :

  959

  break ;

  958

  i n s e r e _ p i l h a _ a r v o r e (& pilha , c r i a _ n o _ a r v o r e ( p _ l i s t a ) ) ;

  957

  // para l i t e r a i s ou parametros , os tokens sao i n s e r i d o s d i r e t a m e n t e na pilha

  956

  case t i p o _ p a r a m e t r o :

  955

  case t i p o _ l i t e r a l :

  954

  {

  970

  971

  return ( r e t i r a _ p i l h a _ a r v o r e (& pilha ) ) ;

  // reseta o p o n t e i r o de t e m p _ n o d e

  990

  

// ao final do processo , devera sobrar apenas um e l e m e n t o na pilha , c o n t n e d o a arvore c o m p l e t a da e x p r e s s a o

  988 989

  }

  987

  p _ l i s t a = p_lista - > p r o x i m o _ t o k e n ;

  986

  }

  985

  break ;

  983 984

  t e m p _ n o d e = NULL ;

  982

  980 981

  else

  i n s e r e _ p i l h a _ a r v o r e (& pilha , t e m p _ n o d e ) ;

  979

  // re - insere o no na pilha

  977 978

  }

  976

  temp_node - > e s q u e r d a = r e t i r a _ p i l h a _ a r v o r e (& pilha ) ;

  975

  temp_node - > d i r e i t a = r e t i r a _ p i l h a _ a r v o r e (& pilha ) ;

  974

  

// retira os u l t i m o s 2 e l e m e n t o s da pilha para c o n s t r u i r a e x p r e s s a o do no

  973

  {

  972

  • pilha = t o p o _ p i l h a ;
  • pilha = t o p o _ p i l h a ;

  1033

  printf ( " % s " , arvore - > elemento - > l i t e ra l ) ;

  break ;

  1094

  printf ( " % c " , arvore - > elemento - > codigo ) ;

  1093

  case t i p o _ o p e r a d o r :

  1091 1092

  break ;

  1090

  printf ( " % d " , arvore - > elemento - > p a r a m e t r o ) ;

  1089

  case t i p o _ p a r a m e t r o :

  1087 1088

  break ;

  1086

  1085

  }

  case t i p o _ l i t e r a l :

  1084

  {

  1083

  switch ( arvore - > elemento - > tipo )

  1082

  // i m pr i m e o c a r a c t e r do token

  1081

  i m p r i m e _ a r v o r e _ e x p r ( arvore - > e s q u e r d a ) ;

  1080

  // p e r c o r r e a sub - arvore da e s q u e r d a

  1079

  }

  1078

  1095

  1096

  1077

  1105 1106

  1113

  // o loop so para quando nao houve r e o r d e n a c a o alguma

  1112

  int flag = 0;

  1111

  char swap ;

  1110

  char * p _ i np u t ;

  1109

  {

  1108

  void s t r i n g _ s o r t ( char ** input )

  1107

  // funcao que r e o r d e n a um a s t r i n g em ordem a l f a b e t i c a

  }

  // p e r c o r r e a sub - arvore da d i r e i t a

  1100

  1097

  i m p r i m e _ a r v o r e _ e x p r ( arvore - > d i r e i t a ) ;

  1098

  if ( arvore - > elemento - > tipo == t i p o _ o p e r a d o r )

  1099

  {

  // cada sub - e x p r e s s a o estara c o n t i d a em p a r e n t e s e s

  1104

  1101

  printf ( " ) " ) ;

  1102

  }

  1103

  }

  printf ( " ( " ) ;

  // cada sub - e x p r e s s a o estara c o n t i d a em p a r e n t e s e s

  {

  1045 1046

  1054

  // funcao que d e s a l o c a a m e m o r i a da arvore

  1052 1053

  }

  1051

  return ( NULL ) ;

  1050

  else

  1049

  }

  1048

  return ( e l e m e n t o ) ;

  1047

  // r e to r n a o e l e m e n t o

  1044

  1055

  // a t u a l i z a o topo da pilha

  1042 1043

  free (* pilha ) ;

  1041

  // d e s a l o c a m e m o r i a da e s t r u t u r a da pilha

  1039 1040

  t o p o _ p i l h a = (* pilha ) -> p r o x i m o ;

  1038

  // guarda o novo topo da pilha

  1036 1037

  e l e m e n t o = (* pilha ) -> node ;

  1035

  // guarda o token que sera r e t o r n a d o

  1034

  void d e s t r o i _ a r v o r e _ e x p r ( a r v o r e _ e x p r * arvore )

  {

  1076

  }

  {

  1075

  { if ( arvore - > elemento - > tipo == t i p o _ o p e r a d o r )

  1073

  if ( arvore != NULL )

  1072

  {

  1071

  void i m p r i m e _ a r v o r e _ e x p r ( a r v o r e _ e x p r * arvore )

  1070

  // funcao que i m pr i m e a e x p r e s s a o da arvore

  1068 1069

  }

  1067

  1066

  1056 1057

  d e s t r o i _ a r v o r e _ e x p r ( arvore - > e s q u e r d a ) ;

  if ( arvore != NULL )

  1058

  {

  1059

  // p e r c o r r e sub - arvore e s q u e r d a

  1060

  1061

  free (( void *) arvore ) ;

  // p e r c o r r e sub - arvore d i r e i t a

  1062

  d e s t r o i _ a r v o r e _ e x p r ( arvore - > d i r e i t a ) ;

  1063 1064

  // apos ter d e s a l o c a d o todas as sub - arvores , d e s a l o c a o p r o p r i o no

  1065

  do

  • p _ i n p u t = *( p _ i n p u t +1) ;
  • ( p _ in p u t + 1) = swap ;

  {

  }

  1168

  // aloca apenas 2 posicoes , uma para a v a r i a v e l e outra para o \0

  1169

  

if (( e l e m e n t o _ l i s t a - > c o d i g o s _ n u m e r a d o r = ( char *) malloc (2* sizeof ( char ) ) ) == NULL )

  1170

  1171

  return ( NULL ) ;

  // erro m e m o r i a i n s u f i c i e n t e

  1172

  return ( NULL ) ;

  1173

  }

  1174

  1167

  1166

  1175

  // se chegou ate um l i t e r a l ou um parametro , e uma folha da arvore , p o r t a n t o d e v e m o s alocar o e l e m e n t o da lista de e x p r e s s o e s e x p a n d i d a s

  // R e al i z a o p e r a c o e s d e p e n d e n d o do tipo do no

  1159

  switch ( arvore - > elemento - > tipo )

  1160

  {

  1161

  1162

  // erro m e m o r i a i n s u f i c i e n t e

  case t i p o _ l i t e r a l :

  1163

  if (( e l e m e n t o _ l i s t a = ( l i s t a _ e x p r *) malloc ( sizeof ( l i s t a _ e x p r ) ) ) == NULL )

  1164

  {

  1165

  // copia o codigo e o \0 na string

  e l e m e n t o _ l i s t a - > c o d i g o s _ n u m e r a d o r [0] = arvore - > elemento - > codigo ;

  no_dir = c o n s t r o i _ l i s t a _ e x p r e s s o e s _ e x p ( arvore - > d i r ei t a ) ;

  // erro m e m o r i a i n s u f i c i e n t e

  case t i p o _ p a r a m e t r o :

  1187

  if (( e l e m e n t o _ l i s t a = ( l i s t a _ e x p r *) malloc ( sizeof ( l i s t a _ e x p r ) ) ) == NULL )

  1188

  {

  1189

  1190

  break ;

  return ( NULL ) ;

  1191

  }

  1192

  // e s c a l a r e s nao tem n e n h u m a lista de c o d i g o s a s s o c i a d o

  1193

  1185 1186

  1184

  1176

  // e l e m en t o _ l i s t a - > sinal = o p e r a d o r _ m a i s ;

  e l e m e n t o _ l i s t a - > c o d i g o s _ n u m e r a d o r [1] = ’ \0 ’;

  1177

  e l e m e n t o _ l i s t a - > c o d i g o s _ d e n o m i n a d o r = NULL ;

  1178

  // por padrao , todos os termos sao p o s i t i v o s

  1179

  1180

  e l e m e n t o _ l i s t a - > a n t e r i o r = NULL ;

  // a v a r i a v e l inicia - se m u l t i p l i c a d a por 1

  1181

  e l e m e n t o _ l i s t a - > p a r a m e t r o = 1.0;

  1182

  e l e m e n t o _ l i s t a - > p r o x i m o = NULL ;

  1183

  1158

  1157

  1114

  swap = * p _ i n p u t ;

  if ((* p _ i n p u t ) > *( p _ i n p u t +1) )

  1127

  {

  1128

  // r e al i z a a troca entre os termos adjacentes , caso o a n t e r i o r seja maior

  1129

  1130

  // c o m p ar a termos a d j a c e n t e s

  1131

  1132 1133

  // s i n a l i z a que houve troca

  1134

  flag = 1;

  1135

  1126

  1124 1125

  1136

  // reset na flag de c o n t r o l e do loop

  {

  1115

  // aponta para o inicio da string

  1116

  p _ i n p u t = * input ;

  1117 1118

  1119

  {

  flag = 0;

  1120 1121

  // p e r c o r r e a string ate chegar ao final

  1122

  while (*( p _ i n p u t + 1) != ’ \0 ’)

  1123

  }

  // i n c r e m e n t a o p o n t e i r o para p r o x i ma c o m p a r a c a o

  // p e r c o r r e a sub - arvore da d i r e i t a

  int i ; // indice de p r o p o s i t o geral

  l i s t a _ e x p r * e l e m e n t o _ l i s t a = NULL ; // e l e m e n t o novo a ser a l o c a d o

  1148

  l i s t a _ e x p r * e l e m e n t o _ a n t = NULL ; // r e f e r e n c i a para o ultimo e l e m e n t o criado

  1149

  l i s t a _ e x p r * p _ e l e m e n t o _ d i r ; // p o n t e i r o para p e r c o r r e r a lista da sub - arvore d i r e i t a

  1150

  1151 1152

  l i s t a _ e x p r * no_dir ; // toda a e x p r e s s a o r e p r e s e n t a d a pelo no d i r e i t o

  if ( arvore != NULL )

  1153

  {

  1154

  // p e r c o r r e a sub - arvore da e s q u e r d a no_esq = c o n s t r o i _ l i s t a _ e x p r e s s o e s _ e x p ( arvore - > e s q u e r d a ) ;

  1156

  1147

  1146

  1137

  }

  p _ i n p u t ++;

  1138

  }

  1139

  } while ( flag ) ;

  1140

  1141 1142

  l i s t a _ e x p r * no_esq ; // toda a e x p r e s s a o r e p r e s e n t a d a pelo no e s q u e r d o

  // funcao que i m pr i m e a e x p r e s s a o da arvore

  1143

  l i s t a _ e x p r * c o n s t r o i _ l i s t a _ e x p r e s s o e s _ e x p ( a r v o r e _ e x p r * arvore )

  1144

  {

  1145

  e l e m e n t o _ l i s t a - > c o d i g o s _ n u m e r a d o r = NULL ;

  1194

  1242 1243

  break ;

  1250

  e l e m e n t o _ l i s t a = e l e m e n t o _ l i s t a - > a n t e r i o r ;

  1249

  while ( e l e m e n t o _ l i s t a - > a n t e r i o r != NULL )

  1248

  // r e c u p e r a o inicio da lista

  1246 1247

  no_dir - > a n t e r i o r = e l e m e n t o _ l i s t a ;

  1245

  e l e m e n t o _ l i s t a - > p r o x i m o = no_dir ;

  1244

  // c o n c a t e n a c a o das e x p r e s s o e s

  e l e m e n t o _ l i s t a = e l e m e n t o _ l i s t a - > p r o x i m o ;

  case o p e r a d o r _ n e g a c a o :

  1241

  while ( e l e m e n t o _ l i s t a - > p r o x i m o != NULL )

  1240

  e l e m e n t o _ l i s t a = no_esq ;

  1239

  // aponta para o final da lista do no e s q u e r d o

  1237 1238

  }

  1236

  p _ e l e m e n t o _ d i r = p _ e l e m e n t o _ d i r - > p r o x i m o ;

  1234 1235

  p _ e l e m e n t o _ d i r - > sinal = o p e r a d o r _ m a i s ; */ p _ e l e m e n t o _ d i r - > p a r a m e t r o *= -1.0;

  1232

  1251 1252

  1253

  1231

  p _ e l e m e n t o _ d i r - > p a r a m e t r o *= -1.0;

  1271 1272

  case o p e r a d o r _ m u l t i p l i c a c a o :

  1269 1270

  break ;

  1268

  e l e m e n t o _ l i s t a = no_dir ;

  1267

  // como nao ha o p e r a n d o na no esquerdo , nao ha o que c o n c a t e n a r

  1265 1266

  }

  1264

  p _ e l e m e n t o _ d i r = p _ e l e m e n t o _ d i r - > p r o x i m o ;

  1262 1263

  1261

  // o o p e r a d o r n e g a c a o apenas troca todos os sinais dos e l e m e n t o s da sub - arvore d ir e i t a

  p _ e l e m e n t o _ d i r - > sinal = o p e r a d o r _ m a i s ; */

  1260

  else

  1259

  p _ e l e m e n t o _ d i r - > sinal = o p e r a d o r _ m e n o s ;

  1258

  /* if ( p _ e l e m e nt o _ d i r - > sinal == o p e r a d o r _ m a i s )

  1257

  {

  1256

  while ( p _ e l e m e n t o _ d i r != NULL )

  1255

  p _ e l e m e n t o _ d i r = no_dir ;

  1254

  else

  p _ e l e m e n t o _ d i r - > sinal = o p e r a d o r _ m e n o s ;

  e l e m e n t o _ l i s t a - > c o d i g o s _ d e n o m i n a d o r = NULL ;

  

// aqui estara a maior c o m p l e x i d a d e do codigo , onde as e x p a n s o e s serao de fato r e a l i z a d a s

  1210

  // se o no e s q u e r d o for nulo , s i g n i f i c a que ha apenas uma o p e r a c a o unaria , entao nao deve haver c o n c a t e n a c a o

  1209

  // o o p e r a d o r p o s i t i v o apenas c o n c a t e n a a lista do no e s q u e r d o com a lista do no d i r e i t o

  1208

  case o p e r a d o r _ m a i s :

  1207

  {

  1206

  switch ( arvore - > elemento - > o p e r a d o r )

  1205

  case t i p o _ o p e r a d o r :

  1204

  1202 1203

  1211

  break ;

  1201

  e l e m e n t o _ l i s t a - > a n t e r i o r = NULL ;

  1200

  e l e m e n t o _ l i s t a - > p r o x i m o = NULL ;

  1199

  e l e m e n t o _ l i s t a - > p a r a m e t r o = ( double ) ( arvore - > elemento - > p a r a m e t r o ) ;

  1198

  // insere - se o p a r a m e t r o ja t r a n s f o r m a d o para i n t e i r o

  1197

  // e l e m e n t o _ l i s t a - > sinal = o p e r a d o r _ m a i s ;

  1196

  // por padrao , todos os termos sao p o s i t i v o s

  1195

  // aponta para o final da lista do no e s q u e r d o

  e l e m e n t o _ l i s t a = no_esq ;

  1230

  1222

  /* if ( p _ e l e m e n t o _ d i r - > sinal == o p e r a d o r _ m a i s )

  1229

  {

  1228

  while ( p _ e l e m e n t o _ d i r != NULL )

  1227

  p _ e l e m e n t o _ d i r = no_dir ;

  1226

  // o o p e r a d o r n e g a t i v o troca todos os sinais dos e l e m e n t o s da sub - arvore d i r e i t a e depois c o n c a t e n a como na adicao

  1225

  case o p e r a d o r _ m e n o s :

  1223 1224

  break ;

  e l e m e n t o _ l i s t a = e l e m e n t o _ l i s t a - > a n t e r i o r ;

  1212

  1221

  while ( e l e m e n t o _ l i s t a - > a n t e r i o r != NULL )

  1220

  // r e c u p e r a o inicio da lista

  1218 1219

  no_dir - > a n t e r i o r = e l e m e n t o _ l i s t a ;

  1217

  e l e m e n t o _ l i s t a - > p r o x i m o = no_dir ;

  1216

  // c o n c a t e n a c a o das e x p r e s s o e s

  1214 1215

  e l e m e n t o _ l i s t a = e l e m e n t o _ l i s t a - > p r o x i m o ;

  1213

  while ( e l e m e n t o _ l i s t a - > p r o x i m o != NULL )

  

// o p r o c e d i m e n t o foi e n c a p s u l a d o para ser u t i l i z a d o na p o t e n c i a c a o

  1273

  1323

  1332 1333

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( no_dir ) ;

  1331

  // d e s a l o c a r o no d i r ei t o

  1329 1330

  e l e m e n t o _ l i s t a = no_esq ;

  1328

  {

  1327

  else if ( no_dir - > p a r a m e t r o == 1.0)

  1326

  } // se o e x p o e n t e for 1 , r e t o r n a r o p r o p r i o no e s q u e r d o

  1324 1325

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( no_esq ) ;

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( no_dir ) ;

  1334

  1322

  // d e s a l o c a r as listas do no di r e i t o e e s q u e r d o

  1320 1321

  e l e m e n t o _ l i s t a - > a n t e r i o r = NULL ;

  1319

  e l e m e n t o _ l i s t a - > p r o x i m o = NULL ;

  1318

  e l e m e n t o _ l i s t a - > p a r a m e t r o = 1.0;

  1317

  // insere - se o numero 1 no campo do p a r a m e t r o

  1316

  // e l e me n t o _ l i s t a - > sinal = o p e r a d o r _ m a i s ;

  1315

  e l e m e n t o _ l i s t a - > c o d i g o s _ d e n o m i n a d o r = NULL ; // por padrao , todos os termos sao p o s i t i v o s

  }

  else // m u l t i p l i c a r o no e s q u e r d o por si mesmo q u a n t a s vezes for o p a r a m e t r o do no d i r e i t o

  e l e m e n t o _ l i s t a - > c o d i g o s _ n u m e r a d o r = NULL ;

  1344 1345

  1353

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( no_esq ) ;

  1352

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( no_dir ) ;

  1351

  // d e s a l o c a as listas o r i g i n a i s

  1349 1350

  }

  1348

  }

  1347

  e l e m e n t o _ a n t = e l e m e n t o _ l i s t a ;

  1346

  // aponta o e l e m e n t o a n t e r i o r para o atual

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( e l e m e n t o _ a n t ) ;

  1335

  1343

  if ( e l e m e n t o _ a n t != no_esq )

  1342

  // d e s a l o c a o e l e m e n t o anterior , mas apenas se nao for o no_Esq o r i g i n a l

  1340 1341

  e l e m e n t o _ l i s t a = m u l t i p l i c a _ e x p r ( elemento_ant , no_esq ) ;

  1339

  {

  1338

  for ( i =0; i < ( int ) ( no_dir - > p a r a m e t r o - 1.0) ; i ++)

  1337

  e l e m e n t o _ a n t = no_esq ;

  1336

  {

  1313

  1312

  e l e m e n t o _ l i s t a = m u l t i p l i c a _ e x p r ( no_esq , no_dir ) ;

  return ( NULL ) ;

  // erro - e x p r e s s a o no e x p o e n t e

  1291

  {

  1290

  if ( no_dir - > c o d i g o s _ n u m e r a d o r != NULL )

  1289

  

// p r i m e i r a m e n t e v e r i f i c a r se o e x p o e n t e e um numero i n t e i r o

  1288

  case o p e r a d o r _ p o t e n c i a c a o :

  1286 1287

  break ;

  1285

  }

  1284

  1283

  return ( NULL ) ;

  // erro

  1282

  {

  1281

  if ( e l e m e n t o _ l i s t a == NULL )

  1280

  // erro

  1278 1279

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( no_esq ) ;

  1277

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( no_dir ) ;

  1276

  // d e s a l o c a r as listas o r i g i n a i s

  1274 1275

  1292

  1293

  

// e s c a l a r e s nao tem n e n h u m a lista de c o d i g o s a s s o c i a d o

  1304

  1311

  }

  1310

  return ( NULL ) ;

  1309

  // erro m e m o r i a i n s u f i c i e n t e

  1308

  {

  1307

  if (( e l e m e n t o _ l i s t a = ( l i s t a _ e x p r *) malloc ( sizeof ( l i s t a _ e x p r ) ) ) == NULL )

  1306

  {

  1305

  if ( no_dir - > p a r a m e t r o == 0.0)

  // se o e x p o e n t e for 0 , r e t o r n a r 1

  }

  1298

  1294 1295

  

// TODO d i v i s a o : tambem r e t o r n a r erro se o e x p o e n t e for n e g a t i v o

  1296

  // if ( no_dir - > sinal == o p e r a d o r _ m e n o s )

  1297

  if ( no_dir - > p a r a m e t r o < 0.0)

  {

  1302 1303

  1299

  // erro - e x p o e n t e n e g a t i v o

  1300

  return ( NULL ) ;

  1301

  }

  break ;

  1434

  1405

  elemento - > c o d i g o s _ d e n o m i n a d o r = NULL ;

  1414

  1413

  elemento - > c o d i g o s _ n u m e r a d o r = ( char *) malloc ( sizeof ( char ) *(1 + temp ) ) ;

  1411 1412

  }

  1410

  temp += strlen ( p _ e l e m e n t o _ di r - > c o d i g o s _ n u m e r a d o r ) ;

  1409

  {

  1408

  if ( p _ e l e m e n t o _ d i r - > c o d i g o s _ n u m e r a d o r != NULL )

  1406 1407

  }

  temp += strlen ( p _ e l e m e n t o _ es q - > c o d i g o s _ n u m e r a d o r ) ;

  // copio a string das v a r i a v e i s do p r i m e i r o e l e m e n t o

  1404

  {

  1403

  if ( p _ e l e m e n t o _ e s q - > c o d i g o s _ n u m e r a d o r != NULL )

  1402

  temp = 0; // a c u m u l a d o r de t a m a n h o de string

  1401

  {

  1400

  if (( p _ e l e m e n t o _ e s q - > c o d i g o s _ n u m e r a d o r != NULL ) || ( p _ e l e m e n t o _ d i r - > c o d i g o s _ n u m e r a d o r != NULL ) )

  1399

  // vejo a q u a n t i d a d e de v a r i a v e i s em cada termo da m u l t i p l i c a c a o e aloco uma string a d e q u a d a

  1398

  // TODO : D I V I S A O i m p l e m e n t a r as o p e r a c o e s c a b i v e i s com os d e n o m i n a d o r e s tambem

  1415

  1416

  elemento - > p r o x i m o = NULL ; elemento - > a n t e r i o r = NULL ;

  else // m u l t i p l i c a c a o entre 2 p a r a m e t r o s

  elemento - > p a r a m e t r o = p_ e l e m e n t o _ e s q - > p a r a m e t r o * p _ e le m e n t o _ d i r - > p a r a m e t r o ;

  1433

  // m u l t i p l i c a r os p a r a m e t r o s

  1431 1432

  elemento - > c o d i g o s _ d e n o m i n a d o r = NULL ;

  1430

  // i n i c i a l i z a r o p o n t e i r o do d e n o m i n a d o r

  1428 1429

  }

  1427

  elemento - > c o d i g o s _ n u m e r a d o r = NULL ;

  1426

  {

  1425

  1424

  if ( p _ e l e m e n t o _ e s q - > c o d i g o s _ n u m e r a d o r != NULL )

  }

  1423

  s t r i n g _ s o r t (&( elemento - > c o d i g o s _ n u m e r a d o r ) ) ;

  1422

  // finalmente , r e o r d e n o a nova string

  1421

  

strcat ( elemento - > c o d i g o s _ n u m e r a d o r , p _ el e m e n t o _ d i r - > c o d i g o s _ n u m e r a d o r ) ;

  1420

  if ( p _ e l e m e n t o _ d i r - > c o d i g o s _ n u m e r a d o r != NULL )

  1419

  // e c o n c a t e n o com os do s e gu n d o

  1418

  

strcpy ( elemento - > c o d i g o s _ n u m e r a d o r , p _ el e m e n t o _ e s q - > c o d i g o s _ n u m e r a d o r ) ;

  1417

  1396 1397

  1394

  1354

  1363

  1372 // no p r o c e s s o que devera ser d e s a l o c a d a ao final da o p e r a c a o . 1373

  // aqui deve - se c o m b i n a r todos os e l e m e n t o s da lista e s q u e r d a com os da lista direita , g e r a n d o uma nova lista

  1370 1371

  int temp ;

  1369

  l i s t a _ e x p r * p _ e l e m e n t o _ d i r ; // p o n t e i r o para p e r c o r r e r a lista da sub - arvore d i r e i t a

  1368

  l i s t a _ e x p r * p _ e l e m e n t o _ e s q ; // p o n t e i r o para p e r c o r r e r a lista da sub - arvore e s q u e r d a

  1367

  l i s t a _ e x p r * e l e m e n t o _ a n t = NULL ; // r e f e r e n c i a para o ultimo e l e m e n t o criado

  1366

  l i s t a _ e x p r * e l e m e n t o = NULL ; // e l e m e n t o novo a ser a l o c a d o

  1364 1365

  {

  l i s t a _ e x p r * m u l t i p l i c a _ e x p r ( l i s t a _ e x p r * no_esq , l i s t a _ e x p r * no_dir )

  1374

  1362

  // r e a l iz a m u l t i p l i c a c a o entre duas listas de e x p r e s s a o

  1360 1361

  }

  1359

  return ( e l e m e n t o _ l i s t a ) ;

  1358

  }

  1357

  }

  1356

  break ;

  1355

  }

  p _ e l e m e n t o _ e s q = no_esq ;

  p _ e l e m e n t o _ d i r = no_dir ;

  // i n i c i a l i z a r p o n t e i r o s

  1385

  1392 1393

  }

  1391

  return ( NULL ) ;

  1390

  // erro m e m o r i a i n s u f i c i e n t e

  1389

  {

  1388

  if (( e l e m e n t o = ( l i s t a _ e x p r *) malloc ( sizeof ( l i s t a _ e x p r ) ) ) == NULL )

  1387

  // aloco cada e l e m e n t o novo

  1386

  e l e m e n t o = NULL ;

  // reseta o p o n t e i r o e l e m e n t o para a etapa

  1375 1376

  1384

  {

  1383

  while ( p _ e l e m e n t o _ d i r != NULL )

  1382

  {

  1381

  while ( p _ e l e m e n t o _ e s q != NULL )

  1379 1380

  return NULL ;

  1378

  if ( no_esq == NULL || no_dir == NULL )

  1377

  // caso algum dos termos seja um p o n t e i r o nulo

  • ( elemento - > c o d i g o s _ n u m e r a d o r ) = ’ \0 ’;

  1435

  // a t u a l i z a r os p o n t e i r o s

  1436

  if ( e l e m e n t o _ a n t == NULL )

  1437

  e l e m e n t o _ a n t = e l e m e n t o ;

  1438

  else

  1439

  {

  1440

  elemento_ant - > p r o x i m o = e l e m e n t o ;

  1441

  elemento - > a n t e r i o r = e l e m e n t o _ a n t ;

  1442

  e l e m e n t o _ a n t = e l e m e n t o ;

  1443

  }

  1444 1445

  // i n c r e m e n t a o p o n t e i r o da lista do no da d i r e i t a

  1446

  p _ e l e m e n t o _ d i r = p _ e l e m e n t o _ d i r - > p r o x i m o ;

  1447

  }

  1448

  // avanco o p o n t e i r o da lista do no e s q u e r d o

  1449

  p _ e l e m e n t o _ e s q = p _ e l e m e n t o _ e s q - > p r o x i m o ;

  1450 1451

  // reseto o p o n t e i r o da sub - arvore e s q u e r d a

  1452

  p _ e l e m e n t o _ d i r = no_dir ;

  1453

  }

  1454

  // a p r o v e i t a n d o que a lista e d u p l a m e n t e encadeada , eu posso r e c u p e r a r o inicio a t r a v e s dos p o n t e i r o s para a n t e r i o r

  1455

  while ( elemento - > a n t e r i o r != NULL )

  1456

  e l e m e n t o = elemento - > a n t e r i o r ;

  1457

  return ( e l e m e n t o ) ;

  1458

  }

  1459 1460

  // d e s a l o c a r um lista de e x p r e s s o e s

  1461

  void d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ e x p r * lista )

  1462

  {

  1463

  // teste de c o n s i s t e n c i a

  1464

  if ( lista == NULL )

  1465

  return ;

  1466 1467

  // c h a m a d a s r e c u r s i v a s

  1468

  if ( lista - > p r o x i m o != NULL )

  1469

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( lista - > p r o x i m o ) ;

  1470 1471

  // d e s a l o c a r cada e s t r u t u r a da lista

  1472

  if ( lista - > c o d i g o s _ d e n o m i n a d o r != NULL )

  1473

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( lista - > c o d i g o s _ d e n o m i n a d o r ) ;

  1474

  if ( lista - > c o d i g o s _ n u m e r a d o r != NULL )

  1475

  free ( lista - > c o d i g o s _ n u m e r a d o r ) ; // d e s a l o c a r o no

  1477

  free ( lista ) ;

  1478 1479

  }

  1480 1481

  void i m p r i m e _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ e x p r * lista , t a b e l a _ l i t e r a i s * tabela )

  1482

  {

  1483

  l i s t a _ e x p r * p _ l i s t a = lista ;

  1484

  double teste ;

  1485 1486

  // i m p r i m e todos os campos do e l e m e n t o

  1487

  while ( p _ l i s t a != NULL )

  1488

  {

  1489

  // i m pr i m e o sinal

  1490

  if ( p_lista - > p a r a m e t r o > 0.0)

  1491

  printf ( " + " ) ;

  1492

  else if ( p_lista - > p a r a m e t r o == -1.0)

  1493

  printf ( " -" ) ;

  1494 1495

  // i m pr i m e o p a r a m e t r o

  1496

  if ( p_lista - > p a r a m e t r o != 1.0 && p_lista - > p a r a m e t r o != -1.0)

  1497

  // checar se o c o e f i c i e n t e e in t e i r o

  1498

  if (( teste = ( int ) p_lista - > p a r a m e t r o - p_lista - > p a r a m e t r o ) == 0.0)

  1499

  printf ( " % d " ,( int ) ( p_lista - > p a r a m e t r o ) ) ;

  1500

  else

  1501

  {

  1502

  printf ( " %2.2 f " , p_lista - > p a r a m e t r o ) ;

  1503

  }

  1504 1505

  // i m pr i m e o n u m e r a d o r

  1506

  if ( p_lista - > c o d i g o s _ n u m e r a d o r != NULL )

  1507

  // printf ("% s " , p_lista - > c o d i g o s _ n u m e r a d o r ) ;

  1508

  p r i n t _ m o n o m i o ( p_lista - > c o d i g o s _ n u m e r a d o r , tabela ) ;

  1509

  else if ( p_lista - > p a r a m e t r o == 1.0 || p_lista - > p a r a m e t r o == -1.0)

  1510

  printf ( " 1.00 " ) ;

  1511 1512

  // i m pr i m e o d e n o m i n a d o r

  1513

  if ( p_lista - > c o d i g o s _ d e n o m i n a d o r != NULL )

  1514

  // printf ("/(% s ) " , p_lista - > c o d i g o s _ d e n o m i n a d o r ) ;

  1515

  i m p r i m e _ l i s t a _ e x p r _ e x p a n d i d a ( p_lista - > c o d i g o s _ d e n o m i n a d o r , tabela ) ;

  1516 1517

  1568 1569

  p_1 = p _ i n i c i o ;

  1577

  // i n i c i a l i z a os p o n t e i r o s

  1575 1576

  p _ i n i c i o = c o p i a _ l i s t a _ e x p r ( p _l i s t a ) ;

  1573 1574

  return NULL ;

  1572

  if ( p _ l i s t a == NULL )

  1571

  // TODO : c o n t r o l e de erro

  1570

  // r e a l i z a uma copia de p _ l i s t a

  double r e s u l t a d o ; // a v a l i a c a o da soma ou s u b t r a c a o dos termos

  if ( p_1 - > pr o x i m o == NULL )

  1567

  l i s t a _ e x p r * p_1 , * p_2 , * p_remove , * p _ i n i c i o ; // p o n t e i r o s para p e r c o r r e r a lista

  1566

  {

  1565

  l i s t a _ e x p r * s i m p l i f i c a _ e x p r _ e x p a n d i d a ( l i s t a _ e x p r * p _ l i s t a )

  1564

  // funcao que agrupa e l e m e n t o s iguais da e x p r e s s a o e x p a n d i d a

  1562 1563

  }

  1560 1561

  }

  1559

  printf ( " * " ) ;

  1578 1579

  1580

  // a d i c i o n a r um sinal de m u l t i p l i c a c a o caso o p r o x i m o nao seja o \0 if (* m o n o m i o != ’ \0 ’)

  p_2 = p_1 - > p r o x i m o ;

  1596

  {

  1595

  if ( p_1 - > c o d i g o s _ n u m e r a d o r != NULL && p_2 - > c o d i g o s _ n u m e r a d o r != NULL )

  1594

  // TODO d i v i s a o : levar em conta o d e n o m i n a d o r tambem

  1593

  // v e r i f i c a r se o c o n j u n t o de v a r i a v e i s dos dois e l e m e n t o s sao iguais

  1592

  {

  1591

  while ( p_2 != NULL )

  1590

  1589

  {

  // i n i c i a l i z a r p_2 como o s e g u nd o e l e m e n t o

  1588

  {

  1587

  while ( p_1 != NULL )

  1586

  // loop de c o m p a r a c a o

  1584 1585

  }

  1583

  return ( p_1 ) ;

  1582

  // a e x p r e s s a o so tem um e l e m e n t o

  1581

  1558

  1555 1556

  // i m pr i m e um espaco para o p r o x i m o e l e m e n t o

  {

  1535

  i = 1; // p r i m e i r a v a r i a v e l

  1534

  {

  1533

  while (* m on o m i o != ’ \0 ’)

  1532

  // p e r c o r r e r os c o d i g o s dos monomios , c o n t a n d o q u a n t o s tem igual , e i m p r i m i n d o com e x p o e n t e quando for o caso

  1530 1531

  t a b e l a _ l i t e r a i s * p _ t a b e l a ;

  1529

  int i ;

  1528

  1527

  1536

  void p r i n t _ m o n o m i o ( char * monomio , t a b e l a _ l i t e r a i s * tabela )

  1526

  // funcao que i m pr i m e o m o n o m i o s e g u n d o suas v a r i a v e i s a partir dos c o d i g o s i n t e r n o s

  1524 1525

  }

  1523

  }

  1522

  p _ l i s t a = p_lista - > p r o x i m o ;

  1521

  // i m pr i m e o p r o x i m o e l e m e n t o

  1519 1520

  printf ( " " ) ;

  1518

  // testar se os p r o x i m o s c o d i g o s sao iguais

  while (* m o no m i o == *( m o n o m i o + 1) )

  m o n o m i o ++;

  1545

  1554

  // p r ox i m o codigo

  1553

  printf ( " ^% d " ,i ) ;

  1552

  if ( i > 1)

  1551

  // i m pr i m e o e x p o e n t e

  1549 1550

  printf ( " % s " , p_tabela - > l i t e r a l ) ;

  1548

  // i m pr i m e a v a r i a v e l c o r r e s p o n d e n t e ao codigo

  1546 1547

  p _ t a b e l a = p_tabela - > p r o x i m o _ c o d i g o ;

  while ( p_tabela - > codigo != * m o n o m i o )

  1537

  1544

  // P e s q u i s a o codigo na tabela de l i t e r a i s

  1543

  p _ t a b e l a = tabela ;

  1542

  // i n i c i a l i z a a tabela de l i t e r i a s

  1541

  }

  1540

  m o n o m i o ++;

  1539

  i ++; // i n c r e m e n t a o numero de v a r i a v e i s iguais

  1538

  {

  if (! strcmp ( p_1 - > c o d i g o s _ n u m e r a d o r , p_2 - > c o d i g o s _ n u m e r a d o r ) )

  1597

  {

  1598

  // i n i c i a l i z a r a v a r i a v e l de r e s u l t a d o

  1599

  r e s u l t a d o = 0.0;

  1600

  // somar ou s u b t r a i r o p r i m e i r o termo

  1601

  r e s u l t a d o += p_1 - > p a r a m e t r o ;

  1602 1603

  // somar ou s u b t r a i r o s e g u n d o termo

  1604

  r e s u l t a d o += p_2 - > p a r a m e t r o ;

  1605 1606

  // BUG : a r r e d o n d a r quando o r e s u l t a d o e r e s i d u a l . Por exemplo , 0.9 - 0.9 = 11.1 E -15

  1607 1608

  if (( r e s u l t a d o <= 0 . 0 0 0 0 0 0 0 0 0 0 0 0 1 && r e s u l t a d o >= 0.0) || ( r e s u l t a d o >= - 0 . 0 0 0 0 0 0 0 0 0 0 0 0 1 && r e s u l t a d o <= 0.0) )

  1609

  r e s u l t a d o = 0.0;

  1610

  // g u a r d ar o r e s u l t a d o em p_1 sem sinal

  1611

  p_1 - > p a r a m e t r o = r e s u l t a d o ;

  1612 1613

  // ja a t u a l i z a p_2

  1614

  p _ r e m o v e = p_2 ;

  1615

  p_2 = p_2 - > p r o x i m o ;

  1616

  // r e m o v er p_2 da lista

  1617

  // TODO : i m p l e m e n t a r a funcao

  1618

  p _ i n i c i o = r e m o v e _ l i s t a _ e x p r ( p_inicio , p _ r e m o v e ) ;

  1619

  }

  1620

  else // a t u a l i z a p_2

  1621

  p_2 = p_2 - > p r o x i m o ;

  1622

  }

  1623

  else // a t u a l i z a p_2

  1624

  p_2 = p_2 - > p r o x i m o ;

  1625 1626

  }

  1627

  // a t u a l i z a p_1

  1628

  p_1 = p_1 - > p r o x i m o ;

  1629

  }

  1630

  // p e r c o r r e a lista n o v a m e n t e e l i m i e n a n d o todos os r e s u l t a d o s 0 , d e i x a n d o s o m e n t e um caso nao sobre e l e m e n t o s na lista

  1631

  p_1 = p _ i n i c i o ;

  1632

  while ( p_1 != NULL )

  1633

  {

  1634

  // se sobrou apenas um e l e m e n t o ( p_1 == p _ i n i c i o ) e ( p_1 - > p r o x i m o == NULL ) entao nao descarta - lo

  1635

  if (( p_1 - > p a r a m e t r o == 0.0) && ( p_1 == p _ i n i c i o ) && ( p_1 - > p r o x i m o == NULL ) )

  1636

  { // d e s a l o c a r os c o d i g o s se houver algum

  1638

  if ( p_1 - > c o d i g o s _ n u m e r a d o r != NULL )

  1639

  {

  1640

  free ( p_1 - > c o d i g o s _ n u m e r a d o r ) ;

  1641

  p_1 - > c o d i g o s _ n u m e r a d o r = NULL ;

  1642

  }

  1643

  if ( p_1 - > c o d i g o s _ d e n o m i n a d o r != NULL )

  1644

  {

  1645

  // free ( p_1 - > c o d i g o s _ d e n o m i n a d o r ) ;

  1646

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( p_1 - > c o d i g o s _ d e n o m i n a d o r ) ;

  1647

  p_1 - > c o d i g o s _ d e n o m i n a d o r = NULL ;

  1648

  }

  1649 1650

  p_1 = p_1 - > p r o x i m o ;

  1651 1652

  }

  1653

  // caso o p a r a m e t r o seja 0 em outras c i r c u n s t a n c i a s

  1654

  else if ( p_1 - > p a r a m e t r o == 0.0)

  1655

  {

  1656

  // a t u a l i z a p_1

  1657

  p _ r e m o v e = p_1 ;

  1658

  p_1 = p_1 - > p r o x i m o ;

  1659

  // remove p_1 da lista

  1660

  p _ i n i c i o = r e m o v e _ l i s t a _ e x p r ( p_inicio , p _ r e m o v e ) ;

  1661

  }

  1662

  else

  1663

  p_1 = p_1 - > p r o x i m o ; // nao e zero

  1664

  }

  1665

  return p _ i n i c i o ;

  1666

  }

  1667 1668

  // funcao que remove um p o n t e i r o da lista de e x p r e s s o e s e x p a n d i d a

  1669

  l i s t a _ e x p r * r e m o v e _ l i s t a _ e x p r ( l i s t a _ e x p r * p_inicio , l i s t a _ e x p r * p _ r e m o v e )

  1670

  {

  1671

  l i s t a _ e x p r * p _ l i s t a ; // p o n t e i r o para p e r c o r r e r a lista

  1672 1673

  // i n i c i a l i z a p_ l i s t a

  1674

  p _ l i s t a = p _ i n i c i o ;

  1675 1676

  // p e r c o r r e a lista a p r o c u r a de p _ r e m o v e

  1677

  1730

  // TODO c o n t r o l e de erro

  1737

  {

  1736

  if ( lista - > c o d i g o s _ n u m e r a d o r != NULL )

  1735

  // p_lista - > sinal = lista - > sinal ;

  1734

  p_lista - > p a r a m e t r o = lista - > p a r a m e t r o ;

  1733

  // copia os e l e m e n t o s

  1731 1732

  p_lista - > c o d i g o s _ d e n o m i n a d o r = NULL ;

  p_lista - > p ro x i m o = NULL ;

  p_lista - > c o d i g o s _ n u m e r a d o r = ( char *) malloc (( strlen ( lista - > c o d i g o s _ n u m e r a d o r ) +1) * sizeof ( char ) ) ;

  1729

  p_lista - > a n t e r i o r = NULL ;

  1728

  // i n i c i a l i z a os e l e m e n t o s

  1726 1727

  p _ l i s t a = ( l i s t a _ e x p r *) malloc ( sizeof ( l i s t a _ e x p r ) ) ;

  1725

  // TODO c o n t r o l e de erro

  1724

  // alocar me m o r i a para o no :

  1722 1723

  p _ l i s t a _ p r o x = c o p i a _ l i s t a _ e x p r ( lista - > p r o x i m o ) ;

  1721

  1738

  1739

  1720

  }

  1756 1757

  p_lista_prox - > a n t e r i o r = p _ l i s t a ;

  1755

  if ( p _ l i s t a _ p r o x != NULL )

  1754

  p_lista - > p ro x i m o = p _ l i s t a _ p r o x ;

  1753

  // a t u a l i z a os p o n t e i r o s de a n t e r i o r e p r o x i m o

  1751 1752

  p_lista - > c o d i g o s _ d e n o m i n a d o r = NULL ;

  1750

  else

  1749

  1748

  strcpy ( p_lista - > c o d i g o s _ n u m e r a d o r , lista - > c o d i g o s _ n u m e r a d o r ) ;

  p_lista - > c o d i g o s _ d e n o m i n a d o r = c o p i a _ l i s t a _ e x p r ( lista - > c o d i g o s _ d e n o m i n a d o r ) ;

  1747

  // TODO c o n t r o l e de erro

  1746

  {

  1745

  if ( lista - > c o d i g o s _ d e n o m i n a d o r != NULL )

  1743 1744

  p_lista - > c o d i g o s _ n u m e r a d o r = NULL ;

  1742

  else

  1741

  }

  1740

  if ( lista - > p r o x i m o != NULL )

  // c h a m a d a s r e c u r s i v a s

  while ( p _ l i s t a != p _ r e m o v e && p _ l i s t a != NULL )

  if ( p _ l i s t a == p _ i n i c i o )

  1695 1696

  ( p_remove - > a n t e r i o r ) -> p r o x i m o = p_remove - > p r o x i m o ;

  1694

  if ( p_remove - > a n t e r i o r != NULL )

  1693

  // a t u a l i z a r o p o n t i e r o p r o x i m o do e l e m e n t o a n t e r i o r a p _ r e m o v e

  1691 1692

  }

  1690

  p _ i n i c i o = p_inicio - > p r o x i m o ;

  1689

  {

  1688

  1687

  1697

  

// se o p o n t e i r o a ser r e m o v i d o esta no inicio da lista a t u a l i z a r p _ i n i c i o antes da r e m o c a o

  1685 1686

  }

  1684

  return p _ i n i c i o ;

  1683

  {

  1682

  if ( p _ l i s t a == NULL )

  1681

  // se nao e n c o n t r o u o elemento , r e t o r n a s i m p l e s m e n t e o inicio da lista denovo

  1679 1680

  p _ l i s t a = p_lista - > p r o x i m o ;

  1678

  // a t u a l i z a r o p o n t e i r o a n t e r i o r do e l e m e n t o p r o x i mo a p _ r e m o v e

  if ( p_remove - > p r o x i m o != NULL )

  1719

  1709

  l i s t a _ e x p r * p _ l i s t a _ p r o x = NULL , * p _ l i s t a ;

  1717

  {

  1716

  l i s t a _ e x p r * c o p i a _ l i s t a _ e x p r ( l i s t a _ e x p r * lista )

  1714 1715

  }

  1713

  return p _ i n i c i o ;

  1712

  // r e t o r n a r o inicio da lista

  1710 1711

  free ( p _ r e m o v e ) ;

  // d e s a l o c a r p _ r e m o v e

  1698

  1707 1708

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( p_remove - > c o d i g o s _ d e n o m i n a d o r ) ;

  1706

  // free ( p_remove - > c o d i g o s _ d e n o m i n a d o r ) ;

  1705

  if ( p_remove - > c o d i g o s _ d e n o m i n a d o r != NULL )

  1703 1704

  free ( p_remove - > c o d i g o s _ n u m e r a d o r ) ;

  1702

  if ( p_remove - > c o d i g o s _ n u m e r a d o r != NULL )

  1701

  // l i b e r a r m e m o r i a dos e l e m e n t o s i n t e r n o s de p _ r e m o v e

  1699 1700

  ( p_remove - > pr o x i m o ) -> a n t e r i o r = p_remove - > a n t e r i o r ;

  return p _ l i s t a ;

  1758 1759

  } while ( f l a g _ t r o c a == 1) ;

  1815

  return poly ;

  1814

  }

  1813

  poly = poly - > a n t e r i o r ;

  1812

  {

  1811

  while ( poly - > a n t e r i o r != NULL )

  1810

  // r e c u p e r a r o inicio do p o l i n o m i o

  1808 1809

  1807

  1816 1817

  }

  1806

  p _ a t u a l = p_atual - > p r o x i m o ;

  1805

  else

  1804

  }

  1803

  p_atual - > a n t e r i o r = p _ t r o c a ;

  1802

  p_troca - > p r o x i m o = p _ a t u a l ;

  1801

  // ajusta os p o n t e i r o s entre p _ a t u a l e p _ t r o c a

  1799 1800

  }

  

// lexdeg funcao que c o m p a r a dois m o n o m i o s e r e t o r n a 1 caso o s e g u n d o a r g u m e n t o tenha p r e c e d e n c i a lexdeg em r e l a c a o ao

p r i m e i r o

  1798

  1827

  1835

  // p r oc u r a o p a r a m e t r o no s e g u nd o m o n o m i o

  1834

  {

  1833

  while (1)

  1832

  // loop i n f i n i t o de procura , o r e t o r n o sera e f e t u a d o dentro das c o n d i c i o n a i s

  1830 1831

  return 1;

  1829

  else if ( p r i m e i r o == NULL )

  1828

  // se o p r i m e i r o for uma constante , r e t o r n a r 1

  return 0;

  1818

  1826

  if ( s e g u n d o == NULL )

  1825

  // se o s e g u n d o m o n o m i o for uma constante , r e t o r n a r 0

  1823 1824

  int deg_1 , deg_2 ; // grau dos m o n o m i o s

  1822

  char * p_deg ; // p o n t e i r o s para c o m p a r a c a o de grau m o n o m i a l

  1821

  char p a r a m e t r o = ’A ’; // p a r a m e t r o de c o m p a r a c a o lexica

  1820

  {

  1819

  int lexdeg ( char * primeiro , char * s e g u n d o )

  p_troca - > anterior - > p r o x i m o = p _ t r o ca ;

  p_troca - > a n t e r i o r = p_atual - > a n t e r i o r ; if ( p_troca - > a n t e r i o r != NULL )

  }

  return NULL ;

  p _ a t u a l = poly ;

  1776

  // aponta para o inicio do p o l i n o m i o

  1775

  f l a g _ t r o c a = 0;

  1774

  // reseta o flag de f l a g _ t r o c a

  1773

  {

  1772

  do

  1771

  // p e r c o r r e a lista de p o l i n o m i o s e troca os e l e m e n t o s 1 a 1 quando for n e c e s s a r i o . So para quando a p e r c o r r e r o p o l i n o m i o i n t e i r o e nao fizer troca alguma

  1770

  1769

  // r e b o b i n a para o inicio do p o l i n o m i o

  if ( poly == NULL )

  1767 1768

  int f l a g _ t r o c a = 0; // flag que indica se houve alguma troca de e l e m e n t o s

  1766

  l i s t a _ e x p r * p _ t r o c a ; // p o n t e i r o a u x i l i a r para troca

  1765

  l i s t a _ e x p r * p _ a t u a l ; // p o n t e i r o para e l e m e n t o atual do p o l i n o m i o

  1764

  {

  1763

  l i s t a _ e x p r * l e x d e g b u b b l e s o r t ( l i s t a _ e x p r * poly )

  1762

  // r e o r d e n a um p o l i n o m i o na forma lexdeg

  1760 1761

  1777

  1778

  1795 1796

  {

  p_atual - > proximo - > a n t e r i o r = p _ a t ua l ;

  1794

  if ( p_atual - > p r o x i m o != NULL )

  1793

  p_atual - > p r o x i m o = p_troca - > p r o x i m o ;

  1792

  // ajusta os p o n t e i r o s de borda

  1791

  // r e a l iz a a troca

  1790

  f l a g _ t r o c a = 1;

  1789

  // s i n a l i z a que houve troca

  1788

  1787

  while ( p_atual - > a n t e r i o r != NULL )

  if ( lexdeg ( p_atual - > c o d i g o s _ n u m e r a d o r , p_troca - > c o d i g o s _ n u m e r a d o r ) )

  1786

  // c o m pa r a dois m o n o m i o s a d j a c e n t e s . Se o p r o x i m o tem p r e c e d e n c i a lexdeg , e feita uma troca entre os m o n o m i o s na lista do p o l i n o m i o

  1784 1785

  p _ t r o c a = p_atual - > p r o x i m o ;

  1783

  {

  1782

  while ( p_atual - > p ro x i m o != NULL )

  1781

  // p e r c o r r e a lista

  1780

  p _ a t u a l = p_atual - > a n t e r i o r ;

  1779

  if (( p_deg = strchr ( segundo , p a r a m e t r o ) ) != NULL )

  1836

  

// no caso do grau do s e g u n d o m o n o m i o ser menor que o primeiro , r e t o r n a r 0

  1890

  // se o a r g u m e n t o p r i o r i t a r i o foi e n c o n t r a d o apenas no s e g u n d o monomio , r e t o r n a r 1

  1889

  }

  1887 1888

  // para o p r ox i m o loop

  1886

  // caso contrario , se o grau for i d e n t i c o para a mesma v a r i a v e l em ambos monomios , nao faco mais nada e a t u a l i z o o p a r a m e t r o

  1884 1885

  }

  1883

  return 0;

  1882

  1881

  1891

  {

  1880

  else if ( deg_2 < deg_1 )

  1879

  }

  1878

  return 1;

  1877

  { // no caso do grau do s e g u n d o m o n o m i o ser maior , r e t o r n a r 1

  1875

  if ( deg_2 > deg_1 )

  1874

  // de posse dos graus dos monomios , c o m p a r a r

  1872 1873

  else

  return 1;

  1871

  1905

  1913

  if ( p a r a m e t r o > ’z ’)

  1912

  // caso nao tenha e n c o n t r a d o v a r i a v e l alguma valida , r e t o r n a r 0

  1910 1911

  p a r a m e t r o += 1;

  1909

  else

  1908

  }

  1907

  p a r a m e t r o = ’a ’;

  1906

  {

  if ( p a r a m e t r o == ’Z ’)

  1892 1893

  1904

  // se ja esta na letra Z , passar a busca para " a " m i n u s c u l o

  1901 // em ambos monomios , r ef a z e r a c o m p a r a c a o com o p r o x i m o p a r a m e t r o . 1902 1903

  // caso nao tenha e n c o n t r a d o o p a r a m e t r o p r i o r i a t a r i o em nenhum monomio , ou caso o grau da v a r i a v e l r e l a t i c a ao p a r a m e t r o atual for igual

  1899 1900

  }

  1898

  return 0;

  1896 // se e n c o n t r o u o p a r a m e t r o p r i o r i t a r i o apenas no p r i m e i r o monomio , r e t o r n a r 0. 1897

  {

  1895

  else if (( p_deg = strchr ( primeiro , p a r a m e t r o ) ) != NULL )

  1894

  }

  }

  }

  {

  deg_1 = 0;

  deg_1 += 1;

  1851

  {

  1850

  if ( p_deg != NULL )

  1849

  p_deg = strchr ( p_deg , p a r a m e t r o ) ;

  1848

  // a cada vez que e n c o n t r a o parametro , re f a z e r a busca a partir do p r o x i m o c a r a c t e r

  1847

  {

  1846

  while ( p_deg != NULL )

  1845

  1844

  // a t u a l i z a o p o n t e i r o da string

  // i n i c i a l i z a o grau

  1843

  p_deg = p r i m e i r o ; // i n i c i a l i z a o p o n t e i r o

  1842

  // e n c o n t r a r o grau dos m o n o m i o s

  1841

  // se o a r g u m e n t o p r i o r i t a r i o foi e n c o n t r a d o em ambos monomios , c o m p a r a r o grau dos m o n o m i o s para o mesmo p a r a m e t r o

  1840

  {

  1839

  if (( p_deg = strchr ( primeiro , p a r a m e t r o ) ) != NULL )

  1838

  // p r o cu r o o p a r a m e t r o no p r i m e i r o

  1837

  1852

  1853

  1870

  {

  p_deg +=1;

  1869

  // a t u a l i z a o p o n t e i r o da string

  1868

  deg_2 += 1;

  1867

  {

  1866

  if ( p_deg != NULL )

  1865

  p_deg = strchr ( p_deg , p a r a m e t r o ) ;

  1864

  // a cada vez que e n c o n t r a o parametro , re f a z e r a busca a partir do p r o x i m o c a r a c t e r

  1863

  1862

  p_deg +=1;

  while ( p_deg != NULL )

  1861

  deg_2 = 0;

  1860

  // i n i c i a l i z a o grau

  1859

  p_deg = s e gu n d o ; // i n i c i a l i z a o p o n t e i r o

  1858

  // r e p e ti r o p r o c e d i m e n t o para e n c o n t r a r o grau do s e g u n d o m o n o m i o para o p r e s e n t e p a r a m e t r o

  1856 1857

  }

  1855

  }

  1854

  {

  • q u o c i e n t e = NULL ;
  • resto = NULL ;
  • q u o c i e n t e = c o n s t r o i _ e l e m e n t o _ z e r a d o () ;
  • resto = c o n s t r o i _ e l e m e n t o _ z e r a d o () ;
  • q u o c i e n t e = c o n s t r o i _ e l e m e n t o _ z e r a d o () ;
  • resto = c o n s t r o i _ e l e m e n t o _ z e r a d o () ;

  1968

  1975

  1974

  1973

  // se der merda aqui , tenho que zerar as v a r i a v e i s de r e t o r n o

  1972

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( d i v i d e n d o _ c p y ) ;

  1971

  // limpar v a r i a v e i s

  1970

  // erro , d i v i s a o por 0

  1969

  {

  if ( r e s u l t a d o _ m o n o m i o == NULL )

  1976

  1967

  // c o n d i c a o de erro

  1965 1966

  r e s u l t a d o _ m o n o m i o = d i v i d e _ m o n o m i o ( dividendo_c py , d i v i s o r ) ;

  1964

  // divide os LT ’s do d i v i d e n d o e divisor , g u a r d a n d o o r e s u l t a d o em r e s u l t a d o _ m o n o m i o

  1963

  {

  1962

  while ( d i v i d e n d o _ c p y != NULL )

  1961

  // r e p e t i r a p r o c e d i m e n t o ate o d i v i d e n d o ficar vazio

  1959 1960

  return 0;

  }

  1958

  }

  1991

  p o l y _ p t r = poly_ptr - > p r o x i m o ;

  1990

  while ( poly_ptr - > p r o x i m o != NULL )

  1989

  p o l y _ p t r = r e s t o _ t e m p ;

  1988

  // i n s e ri r o resto no final da lista do resto

  1987

  {

  1986

  else

  1985

  1984

  1977

  p o l y _ p t r = r e s t o _ t e m p ; // manter a r e f e r e n c i a para por NULL no final

  1983

  r e s t o _ t e m p = d i v i d e n d o _ c p y ;

  1982

  {

  1981

  if ( r e s t o _ t e m p == NULL )

  1980

  // O LT do d i v i d e n d o passa a i n t e g r a r o resto

  1979

  {

  1978

  else if ( r e s u l t a d o _ m o n o m i o - > p a r a m e t r o == 0.0) // nao houve d i v i s a o

  // o r e s u l t a d o _ m o n o m i o e a string que falta no d i v i s o r para chegar ao d i v i d e n d o . Se o d i v i s or nao e s t i v e r t o t a l m e n t e c o n t i d o no dividendo , ela r e t o r n a null , ou seja , o LT do d i v i d e n d o ja comeca a i n t e g r a r o resto .

  // 2) Se a string do LT ( d i v i s o r ) esta c o n t i d a na Lt ( d i v i d e n d o ) , -> c u id a d o : A A A B B B C C C = A ^3* B ^3* C ^3 , e ABC . A s e g u n d a

divide a primeira , mas nao ha string ABC na p r i m e i r a ! e n c o n t r o a string que falta e crio um termo novo .

  poly_ptr - > p r o x i m o = d i v i d e n d o _ c p y ;

  1923

  1931

  1930

  // i n i c i a l i z a v a r i a v e i s de r e t o r n o

  1928 1929

  l i s t a _ e x p r * q u o c i e n t e _ t e m p ;

  1927

  l i s t a _ e x p r * r e s t o _ t e m p ;

  1926

  l i s t a _ e x p r * p o l y _ p t r ;

  1925

  l i s t a _ e x p r * r e s u l t a d o _ m o n o m i o = NULL ;

  1924

  l i s t a _ e x p r * d i v i d e n d o _ c p y = NULL ;

  {

  // se passar um d i v i d e n d o 0 ou inexistente , devo r e t o r n a r i m e d i a t a m e n t e

  1922

  int p o l y d i v ( l i s t a _ e x p r * dividendo , l i s t a _ e x p r * divisor , l i s t a _ e x p r ** quociente , l i s t a _ e x p r ** resto )

  1919 1920 // funcao que r e al i z a a d i v i s a o p o l i n o m i a l . 1921

  }

  1918

  }

  1917

  }

  1916

  // erro

  1915

  return (0) ;

  1914

  1932 1933

  1934

  1955 1956 // 1) Compara - se o Lt ( d i v i d e n d o ) com o Lt ( d i v i s o r ) -> L e a d i n g term . 1957

  1945 1946

  d i v i d e n d o _ c p y = c o p i a _ l i s t a _ e x p r ( d i v i d e n d o ) ; // este passo pode deixar o a l g o r i t m o bem pesado . Posso o t i m i z a r para que a lista vire um bloco de memoria , e // r e a l i z a r a copia via memcpy .

  1953

  // devo copiar o d i v i d e n d o a cada operacao , visto que ela pode falhar e eu ter que r e c o m e c a r

  1952

  r e s t o _ t e m p = NULL ;

  1951

  q u o c i e n t e _ t e m p = NULL ;

  1950

  // i n i c i a l i z a r resto e q u o c i e n t e

  1948 1949

  }

  1947

  return 1;

  1944

  if ( d i v i d e n d o == NULL )

  1943

  {

  1942

  else if ( dividendo - > p r o x i m o == NULL && dividendo - > p a r a m e t r o == 0)

  1941

  } // se o d i v i d e n d o possui apenas um m o n o m i o de valor 0

  1940

  return 1;

  1938 1939

  1937

  1936

  {

  1935

  • q u o c i e n t e = c o n s t r o i _ e l e m e n t o _ z e r a d o () ;
  • resto = c o n s t r o i _ e l e m e n t o _ z e r a d o () ;

  1992

  divide ndo_cpy - > a n t e r i o r = p o l y _ p t r ;

  1993

  

p o l y _ p t r = poly_ptr - > p r o x i m o ; // manter a r e f e r e n c i a para por NULL no final

  1994

  }

  1995

  // O LT passa a ser o p r o x i m o m o n o m i o

  1996

  d i v i d e n d o _ c p y = dividendo_c py - > p r o x i m o ;

  1997

  if ( d i v i d e n d o _ c p y != NULL )

  1998

  divide ndo_cpy - > a n t e r i o r = NULL ;

  1999

  // c o l oc a r NULL no final do resto

  2000

  poly_ptr - > p r o x i m o = NULL ;

  2001 2002

  // d e s a l o c a r o r e s u l t a d o _ m o n o m i o

  2003

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( r e s u l t a d o _ m o n o m i o ) ;

  2004 2005

  }

  2006

  else // caso houve d i v i s a o

  2007

  {

  2008 2009

  // e l i m i n a r o LT do dividendo , pois s a b e m o s que ele sera zerado na o p e r a c a o

  2010

  p o l y _ p t r = d i v i d e n d o _ c p y ;

  2011

  d i v i d e n d o _ c p y = dividendo_c py - > p r o x i m o ;

  2012

  if ( d i v i d e n d o _ c p y != NULL )

  2013

  divide ndo_cpy - > a n t e r i o r = NULL ;

  2014

  poly_ptr - > p r o x i m o = NULL ;

  2015

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( p o l y _ p t r ) ;

  2016 2017

  // m u l t i p l i c a r o m o n o m i o r e s u l t a n t e pelo d i v i s o r sem o LT ( pois este p r o d u t o ira c a n c e l a r com o LT do d i v i d e n d o ) e s u b t r a i r do d i v i d e n d o

  2018 if ( divisor - > p r o x i m o != NULL ) // se o d i v i s o r tiver apenas um monomio , pula - se esta etapa . 2019

  {

  2020

  p o l y _ p t r = m u l t i p l i c a _ e x p r ( r e s u l t a d o _ m o n o m i o , divisor - > p r o x i m o ) ;

  2021 2022

  // subtrai - se p o l y _ p t r do d i v i d e n d o

  2023

  s u b t r a i _ e x p r (& d ividendo_cpy , p o l y _ p t r ) ;

  2024

  }

  2025 2026

  // o m o n o m i o r e s u l t a n t e i n t e g r a o q u o c i e n t e

  2027

  if ( q u o c i e n t e _ t e m p == NULL )

  2028

  q u o c i e n t e _ t e m p = r e s u l t a d o _ m o n o m i o ;

  2029

  else

  2030

  {

  2031

  // i n s e ri r o m o n o m i o r e s u l t a n t e ao final do q u o c i e n t e p o l y _ p t r = q u o c i e n t e _ t e m p ;

  2033

  while ( poly_ptr - > p r o x i m o != NULL )

  2034

  p o l y _ p t r = poly_ptr - > p r o x i m o ;

  2035

  poly_ptr - > p r o x i m o = r e s u l t a d o _ m o n o m i o ;

  2036

  r e s u l t a d o _ m o n o m i o - > a n t e r i o r = p o l y _ p t r ;

  2037

  r e s u l t a d o _ m o n o m i o - > p r ox i m o = NULL ;

  2038

  }

  2039

  }

  2040

  }

  2041 2042

  // ao final da divisao , r e o r d e n a r e s i m p l i f i c a r o q u o c i e n t e e o resto

  2043

  if ( q u o c i e n t e _ t e m p != NULL )

  2044

  {

  2045

  p o l y _ p t r = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( q u o c i e n t e _ t e m p ) ;

  2046

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( q u o c i e n t e _ t e m p ) ;

  2047

  q u o c i e n t e _ t e m p = l e x d e g b u b b l e s o r t ( p o l y _ p t r ) ;

  2048 2049

  }

  2050

  else

  2051

  {

  2052

  // c o n s t r u i r um e l e m e n t o zerado

  2053

  q u o c i e n t e _ t e m p = c o n s t r o i _ e l e m e n t o _ z e r a d o () ;

  2054 2055

  }

  2056

  if ( r e s t o _ t e m p != NULL )

  2057

  {

  2058

  p o l y _ p t r = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( r e s t o _ t e m p ) ;

  2059

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( r e s t o _ t e m p ) ;

  2060

  r e s t o _ t e m p = l e x d e g b u b b l e s o r t ( p o l y _ p t r ) ;

  2061 2062

  }

  2063

  else

  2064

  {

  2065

  // c o n s t r u i r um e l e m e n t o zerado

  2066

  r e s t o _ t e m p = c o n s t r o i _ e l e m e n t o _ z e r a d o () ;

  2067

  }

  2068 2069

  • q u o c i e n t e = q u o c i e n t e _ t e m p ;

  2070

  • resto = r e s t o _ t e m p ;

  2071

  • no_esq = no_dir ; }

  // c o n c a t e n a c a o das e x p r e s s o e s

  2134

  {

  2133

  l i s t a _ e x p r * d i v i d e _ m o n o m i o ( l i s t a _ e x p r * dividendo , l i s t a _ e x p r * d i v i s o r )

  2132

  // funcao que r e al i z a a d i v i s a o entre LT ’s -> O T I M I Z A C A O

  2130 2131

  }

  2129

  no_dir - > a n t e r i o r = p o l y _ p t r ;

  2128

  poly_ptr - > p r o x i m o = no_dir ;

  2127

  2125 2126

  2135

  p o l y _ p t r = poly_ptr - > p r o x i m o ;

  2124

  while ( poly_ptr - > p r o x i m o != NULL )

  2123

  p o l y _ p t r = no_esq ;

  2122

  // aponta para o final da lista do no e s q u e r d o

  2120 2121

  l i s t a _ e x p r * p o l y _ p t r ;

  2119

  {

  2118

  void s o m a _ e x p r ( l i s t a _ e x p r * no_esq , l i s t a _ e x p r * no_dir )

  2117

  char * d i v i d e n d o _ p t r ;

  char * d i v i s o r _ p t r ;

  2115 2116

  2145

  2152

  {

  2151

  if ( dividendo - > c o d i g o s _ n u m e r a d o r == NULL )

  2150

  // teste de apenas p a r a m e t r o

  2149

  }

  2148

  return NULL ;

  2147

  // erro d i v i s a o por 0

  2146

  {

  if ( divisor - > p a r a m e t r o == 0.0)

  2136

  2144

  // teste de erro

  2143

  return NULL ;

  2142

  if ( d i v i s o r == NULL )

  2140 2141

  int t a m a n h o _ s t r i n g =0 ; // c a l c u l a o t a m a n h o da string do m o no m i o a ser a l o c a d a

  2139

  double d i v _ p a r a m e t r o s = 1.0; // g u a r d a r o p a r a m e t r o r e s u l t a n t e

  2138

  l i s t a _ e x p r * d i v _ m o n o m i o = NULL ; // g u a r d a r a e s t r u t u r do m o n o m i o r e s u l t a n t e

  2137

  char * d i v _ s t r i n g = NULL ; // g u a r d a r a string do m o n o m i o r e s u l t a n t e

  // funcao que soma duas e x p r e s s o e s

  }

  2072

  2084

  2092 2093

  poly_ptr - > p a r a m e t r o *= -1.0;

  2090 2091

  poly_ptr - > sinal = o p e r a d o r _ m a i s ; */

  2089

  else

  2088

  poly_ptr - > sinal = o p e r a d o r _ m e n o s ;

  2087

  /* if ( poly_ptr - > sinal == o p e r a d o r _ m a i s )

  2086

  {

  2085

  while ( p o l y _ p t r != NULL )

  p o l y _ p t r = no_dir ;

  2094

  2083

  // troca o sinal dos e l e m e n t o s do no d i r e i t o

  2081 2082

  l i s t a _ e x p r * p o l y _ p t r ;

  2080

  {

  2079

  void s u b t r a i _ e x p r ( l i s t a _ e x p r ** no_esq , l i s t a _ e x p r * no_dir )

  2078

  // funcao que s u bt r a i duas e x p r e s s o e s

  2075 2076 2077

  }

  2073 2074

  return 1;

  p o l y _ p t r = poly_ptr - > p r o x i m o ;

  }

  2114

  2104

  2112

  {

  2111

  else // o e l e m e n t o do no e s q u e r d o e vazio

  2110

  }

  2108 2109

  }

  2107

  no_dir - > a n t e r i o r = p o l y _ p t r ;

  2106

  {

  2105

  if ( no_dir != NULL )

  poly_ptr - > p r o x i m o = no_dir ;

  2095

  2103

  // c o n c a t e n a c a o das e x p r e s s o e s

  2101 2102

  p o l y _ p t r = poly_ptr - > p r o x i m o ;

  2100

  while ( poly_ptr - > p r o x i m o != NULL )

  2099

  p o l y _ p t r = * no_esq ;

  2098

  {

  2097

  if (* no_esq != NULL )

  2096

  // aponta para o final da lista do no e s q u e r d o

  // erro o mo n o m i o e apenas um p a r a m e t r o

  2153

  return NULL ;

  2154

  }

  2155 2156

  d i v i d e n d o _ p t r = dividendo - > c o d i g o s _ n u m e r a d o r ;

  2157

  d i v i s o r _ p t r = divisor - > c o d i g o s _ n u m e r a d o r ;

  2158 2159

  // divide os p a r a m e t r o s

  2160

  d i v _ p a r a m e t r o s = dividendo - > p a r a m e t r o / divisor - > p a r a m e t r o ;

  2161 2162

  // testar se e uma s i m p l e s d i v i s a o de p a r i a m e t r o s

  2163

  if ( dividendo - > c o d i g o s _ n u m e r a d o r == NULL && divisor - > c o d i g o s _ n u m e r a d o r == NULL )

  2164

  {

  2165

  // nao havera string de p a r a m e t r o s

  2166

  d i v _ s t r i n g = NULL ;

  2167

  }

  2168

  else // ha uma string no d i v i s o r ou no d i v i d e n d o ou em ambos TODO : aqui pode dar pau com string nula

  2169

  {

  2170

  // calcula - se o t a m a n h o da string a ser a l o c a d o

  2171

  if ( dividendo - > c o d i g o s _ n u m e r a d o r != NULL )

  2172

  t a m a n h o _ s t r i n g = ( int ) strlen ( dividendo - > c o d i g o s _ n u m e r a d o r ) ;

  2173

  if ( divisor - > c o d i g o s _ n u m e r a d o r != NULL )

  2174

  t a m a n h o _ s t r i n g -= ( int ) strlen ( divisor - > c o d i g o s _ n u m e r a d o r ) ;

  2175 2176

  // se o d i v i s o r tiver grau maior que o dividendo , deve - se r e t o r n a r 0

  2177

  if ( t a m a n h o _ s t r i n g <0)

  2178

  {

  2179

  d i v _ p a r a m e t r o s = 0.0;

  2180

  d i v _ s t r i n g = NULL ;

  2181

  }

  2182

  // caso o d i v i d e n d o e d i v i s or tenham grau s e m e l h a n t e

  2183

  else if ( t a m a n h o _ s t r i n g == 0)

  2184

  {

  2185

  // se as s t r i n g s forem diferentes , muda o r e s u l t a d o de d i v _ p a r a m e t r o s para 0

  2186

  if ( strcmp ( dividendo - > c o d i g o s _ n u m e r a d o r , divisor - > c o d i g o s _ n u m e r a d o r ) )

  2187

  d i v _ p a r a m e t r o s = 0.0;

  2188 // caso contrario , mantem - se o d i v _ p a r a m e t r o s c a l c u l a d o a n t e r i o r m e n t e . 2189

  // em q u a l q u e r hipotese , nao ha string de v a r i a v e i s aqui

  2190

  // d i v _ s t r i n g = NULL ; -> ja esta i n i c i a l i z a d o assim

  2191

  }

  2192

  // string no d i v i d e n d o maior que no d i v i s o r

  2193

  else {

  2195

  // caso o d iv i s o r seja apenas um p a r a m e t r o

  2196

  if ( divisor - > c o d i g o s _ n u m e r a d o r == NULL )

  2197

  {

  2198

  // copia a string do d i v i d e n d o na string do m on o m i o

  2199

  d i v _ s t r i n g = ( char *) malloc (( t a m a n h o _ s t r i n g +1) * sizeof ( char ) ) ; // TODO : tratar erro de a l o c a c a o de m e m o r i a

  2200

  • d i v _ s t r i n g = ’ \0 ’;

  2201

  strcpy ( div_string , dividendo - > c o d i g o s _ n u m e r a d o r ) ;

  2202

  }

  2203

// ha string no divisor , e n c o n t r a r a string que a c o m p l e t a para que fique igual ao d i v i d e n d o .

2204

  else

  2205

  {

  2206

  // aloca a string do r e s u l t a d o

  2207

  d i v _ s t r i n g = ( char *) malloc (( t a m a n h o _ s t r i n g +1) * sizeof ( char ) ) ; // TODO : tratar erro de a l o c a c a o de m e m o r i a

  2208

  • d i v _ s t r i n g = ’ \0 ’;

  2209 2210

  // busca os c a r a c t e r e s da string do d i v i s o r na string do d i v i d e n d o

  2211

  while ((* d i v i d e n d o _ p t r ) != ’ \0 ’)

  2212

  {

  2213

  // caso nao e n c o n t r e o c a r a c t e r no divisor , adiciona - lo ao r e s u l t a d o

  2214

  if (* d i v i d e n d o _ p t r != * d i v i s o r _ p t r )

  2215

  {

  2216

  s t r n c a t ( div_string , dividendo _ptr ,1) ;

  2217

  // i n c r e m e n t a p o n t e i r o apenas do d i v i d e n d o

  2218

  d i v i d e n d o _ p t r ++;

  2219

  }

  2220

  // caso os c a r a c t e r e s sejam iguais

  2221

  else

  2222

  {

  2223

  // i n c r e m e n t a ambos p o n t e i r o s

  2224

  d i v i d e n d o _ p t r ++;

  2225

  d i v i s o r _ p t r ++;

  2226

  }

  2227 2228

  }

  2229 2230

  // ao final do processo , se o d i v i s o r nao tiver sido esgotado , entao os m o n o m i o s nao d i v i d e m

  2231

  if (* d i v i s o r _ p t r != ’ \0 ’)

  2232

  {

  2233

  // l i b e r ar a m e m o r i a do r e s u l t a d o

  2313 2314 // divide - se P3 por P1 * P2 , g u a r d a n d o em lista_ptr3 , o resto que vai gerar as f r a co e s p a r c i a i s .

  2284

  2292

  2291

  2290

  // i n i c i a l i z a c a o de r e t o r n o s

  2288 2289

  double c o e f i c i e n t e = 0.0; // c o e f i c i e n t e da v a r i a v e l comum

  2287

  char c o m m o n _ v a r = 0; // v a r i a v e l em comum e n c o n t r a d a para a e x p a n s a o

  2286

  int achou = 0; // c o n t r o l e de loop de busca

  2285

  l i s t a _ e x p r * lista_ptr1 , * lista_ptr2 , * lista_ptr3 , * P3_resto , * resto ;

  {

  resto = NULL ;

  2283

  l i s t a _ e x p r ** numerador_a , l i s t a _ e x p r ** n u m e r a d o r _ b )

  2282

  int p a r t i a l _ f r a c t i o n _ e x p a n s i o n ( l i s t a _ e x p r * P3 , l i s t a _ e x p r * P1 , l i s t a _ e x p r * P2 , l i s t a _ e x p r ** quociente ,

  2281

  // r e t o rn a 0 se nao e n c o n t r a r uma e x p a n s a o certinha , ou 1 se e n c o n t r a r

  2280

  2278 2279

  etapas da e x p a n s a o em fracao p a rc i a l :

  2274 - O d e n o m i n a d o r de cada e l e m e n t o da l i s t a _ e x p r devera ser um p o n t e i r o para outra l i s t a _ e x p r . 2276 2277

  F r a c o e s parciais - > P3 /( P1 * P2 ) = Q + a / P1 + b / P2

  2272 2273

  2293

  2294 2295

  2269 2270 2271

  {

  l i s t a _ p t r 1 = l e x d e g b u b b l e s o r t ( l i s t a _ p t r 2 ) ;

  2312

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 1 ) ;

  2311

  l i s t a _ p t r 2 = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 1 ) ;

  2310

  // simplifica , r e o r d e n a e e l i m i na a lista d e s o r d e n a d a

  2308 2309

  }

  2307

  return 0;

  2306

  2305

  // i n c r e m e n t a o numero de f r a c o e s p a r c i a i s executadas , para c o m p a r a c a de p e r f o r m a n c e

  if ( l i s t a _ p t r 1 == NULL )

  2304

  // c o n d i c a o de erro

  2302 2303

  l i s t a _ p t r 1 = m u l t i p l i c a _ e x p r ( P1 , P2 ) ;

  2301

  // multiplica - se P1 e P2

  2299 2300

  // p r i m e i r o : d i v i d i r P3 por P1 * P2 e g u a r d a r o Q u o c i e n t e

  2297 2298

  g l o b a l _ n u m _ p a r f r a c ++;

  2296

  /*

  }

  2234

  2241

  2249

  div_monomio - > c o d i g o s _ d e n o m i n a d o r = NULL ;

  2248

  div_monomio - > a n t e r i o r = NULL ;

  2247

  div_monomio - > p r o x i m o = NULL ;

  2245 2246

  d i v _ m o n o m i o = ( l i s t a _ e x p r *) malloc ( sizeof ( l i s t a _ e x p r ) ) ; // TODO : tratar erro

  2244

  // com todas as p o s s i b i l i d a d e s cobertas , basta alocar a m em o r i a para o m on o m i o r e s u l t a n t e e p r e e n c h e r a e s t r u t u r a

  2242 2243

  }

  }

  2250

  2240

  }

  2239

  }

  2238

  d i v _ p a r a m e t r o s = 0.0;

  2237

  // o p a r a m e t r o r e s u l t a n t e devera ser 0

  2236

  d i v _ s t r i n g = NULL ;

  2235

  free ( d i v _ s t r i n g ) ;

  div_monomio - > c o d i g o s _ n u m e r a d o r = d i v _ s t r i n g ;

  div_monomio - > p a r a m e t r o = d i v _ p a r a m e t r o s ;

  2268

  elemento - > c o d i g o s _ n u m e r a d o r = NULL ;

  return e l e m e n t o ;

  2266 2267

  elemento - > p a r a m e t r o = 0.0;

  2265

  // (* q u o c i e n t e ) -> sinal = o p e r a d o r _ m a i s ;

  2264

  elemento - > a n t e r i o r = NULL ;

  2263

  elemento - > p r o x i m o = NULL ;

  2262

  elemento - > c o d i g o s _ d e n o m i n a d o r = NULL ;

  2261

  2260

  2251 2252

  e l e m e n t o = ( l i s t a _ e x p r *) malloc ( sizeof ( l i s t a _ e x p r ) ) ; // TODO : c o n t r o l e de erro

  2259

  // c o n s t r u i r um e l e m e n t o zerado

  2258

  l i s t a _ e x p r * e l e m e n t o ;

  2257

  {

  2256

  l i s t a _ e x p r * c o n s t r o i _ e l e m e n t o _ z e r a d o ( void )

  2254 2255

  }

  2253

  return d i v _ m o n o m i o ;

  • /
  • n u m e r a d o r _ a = NULL ;
  • n u m e r a d o r _ b = NULL ;
  • q u o c i e n t e = NULL ;

  2315

  {

  2375

  break ;

  2374

  // i n t e r r o m p o o laco

  2373

  l i s t a _ p t r 1 = r e m o v e _ l i s t a _ e x p r ( lista_ptr1 , l i s t a _ p t r 2 ) ;

  2372

  // removo o p o n t e i r o

  2371

  c o e f i c i e n t e = lista_ptr2 - > p a r a m e t r o ;

  2370

  // guardo o c o e f i c i e n t e da v a r i a v e l comumn no m o n o m i o a ser r e m o v i d o

  2369

  2368

  2376 else // do c o n t r a r i o avanco ao p r o x i m o . 2377

  if (*( lista_ptr2 - > c o d i g o s _ n u m e r a d o r ) == c o m m o n _ v a r )

  2367

  {

  2366

  while ( l i s t a _ p t r 2 != NULL )

  2364 // apenas o c a r a c t e r e do numerador , e p r o c u r a n d o apenas uma unica vez . 2365

  // novamente , P1 e P2 sao apenas c o m b i n a c o e s l i n e a r e s das variaveis , entao este passo esta optimizado , c o m p a r a n d o

  2362 2363

  l i s t a _ p t r 2 = l i s t a _ p t r 1 ;

  2361

  // salvo o inicio da lista

  2360

  l i s t a _ p t r 1 = c o p i a _ l i s t a _ e x p r ( P1 ) ;

  }

  l i s t a _ p t r 2 = lista_ptr2 - > p r o x i m o ;

  // 2) encontra - se o p o l i n o m i o que faca P1 ser zero ao s u b s t i t u i r na v a r i a v e l comum // - gero um p o l i n o m i o igual a P1 , mas sem a v a r i a v e l e com sinal t r o c ad o . Divido o r e s u l t a d o

  l i s t a _ p t r 2 = l i s t a _ p t r 1 ;

  2395

  lista_ptr2 - > p a r a m e t r o /= c o e f i c i e n t e ;

  2394

  lista_ptr2 - > p a r a m e t r o *= -1.0;

  2393

  // salvo o inicio da lista

  2392

  // agora que removi c o m m o n _ v a r dos monomios , devo i n v e r t e r o sinal dos que s o b r a r a m e d i v i d i r pelo c o e f i c i e n t e

  2391

  {

  2390

  while ( l i s t a _ p t r 2 != NULL )

  2389

  2388

  2378

  {

  2387

  else

  2386

  l i s t a _ p t r 1 = c o n s t r o i _ e l e m e n t o _ z e r a d o () ;

  2385

  if ( l i s t a _ p t r 1 == NULL )

  2384

  // se l i s t a _ p t r 1 ficar null , criar um e l e m e n t o zerado

  2381 // entretatno , se eu sempre eleger uma v a r i a v e l de P1 , este p r o b l e m a jamais o c o r r e r a . 2382 2383

  // TODO : caso l i s t a _ p t r 2 seja NULL , p r o c u r a r a v a r i a v e l em P2 , c o n d i c a o em que nao ha v a r i a v e l comum

  2379 2380

  }

  2357 // pelo c o e f i c i e n t e do m o n o m i o que contem a v a r i a v e l . 2358 2359

  2354 2355

  l i s t a _ p t r 3 = NULL ;

  2327 2328

  {

  2334

  while ( l i s t a _ p t r 2 != NULL && ! achou )

  2333

  l i s t a _ p t r 2 = P2 ;

  2332

  // r e i n i c i a l i z a l i s t a _ p t r 2

  2331

  {

  2330

  while ( l i s t a _ p t r 1 != NULL && ! achou )

  2329

  // c o m p a r a cada e l e m e n t o de P1 com todos de P2

  l i s t a _ p t r 1 = P1 ;

  // p a r t i n d o do p r i n c i p i o que os p o l i n o m i o s g e r a d o r e s so p o s s u e m m o n o m i o s de p r i m e i r o grau , devido

  2325 // c o m p a r o cada v a r i a v e l de cada m o n om i o de p1 com todas as v a r i a v e i s de P2 , ate e n c o n t r a r . 2326

  // 1) escolhe - se uma v a r i a v e l comum a P1 e P2

  2323 2324

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 1 ) ;

  2322

  // elimina - se P1 * P2 e x p a n d i d o

  2320 2321

  P 3 _ r e s t o = c o p i a _ l i s t a _ e x p r ( l i s t a _ p t r 3 ) ;

  2319

  // salva o resto para depois

  2317 2318

  p o l y d i v ( P3 , lista_ptr1 , quociente , & l i s t a _ p t r 3 ) ; // TODO : c o n t r o l e de erro

  2316

  2335

  2336

// a serem f o r m a d o por c o m b i n a c a o linear entre as variaveis , a c o m p a r a c a o sera s i m p l i f i c a d a .

2337

  }

  }

  2353

  // TODO : i m p l e m e n t a r algum tipo de c o n t a d o r para v e r i f i c a r estes casos e r e f i n a r mais tarde

  2352

  c o m m o n _ v a r = *( P1 - > c o d i g o s _ n u m e r a d o r ) ;

  2351

  // neste caso , a p r i m e i r a v a r i a v e l de P1

  2350

  // eleger uma v a r i a v e l q u a l q u e r caso nao haja v a r i a v e i s em comum

  2349

  {

  2348

  if (! achou )

  2347

  2346

  if (*( lista_ptr1 - > c o d i g o s _ n u m e r a d o r ) == *( lista_ptr2 - > c o d i g o s _ n u m e r a d o r ) )

  l i s t a _ p t r 1 = lista_ptr1 - > p r o x i mo ;

  2345

  }

  2343 2344

  l i s t a _ p t r 2 = lista_ptr2 - > p r o x i m o ;

  2342

  }

  2341

  c o m m o n _ v a r = *( lista_ptr1 - > c o d i g o s _ n u m e r a d o r ) ;

  2340

  achou = 1; // fim do loop

  2339

  {

  2338

  l i s t a _ p t r 2 = lista_ptr2 - > p r o x i m o ;

  // l i b e r a r o resto para a p r o x i m a etapa

  2448

  2456

  }

  2453 2454 2455

  return 0;

  2452

  2451

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( resto ) ;

  2450

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( P 3 _ r e s t o ) ;

  2449

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a (* q u o c i e n t e ) ;

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 2 ) ;

  2457

  2447

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 1 ) ;

  2446

  2445

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a (* n u m e r a d o r _ a ) ;

  2444

  // d i vi s a o por 0

  2443

  {

  2442

  if (! p o l y d i v ( lista_ptr2 , lista_ptr1 , numerador_a , & resto ) )

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 1 ) ;

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 2 ) ;

  resto = NULL ;

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a (* q u o c i e n t e ) ;

  2473 2474

  }

  2472

  return 0;

  2471

  2470

  2469

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( resto ) ;

  2468

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( P 3 _ r e s t o ) ;

  2467

  2466

  2458 2459

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a (* n u m e r a d o r _ a ) ;

  2465

  // limpar tudo e r e t o r n a r 0

  2464

  {

  2463

  if ( resto - > p a r a m e t r o != 0.0)

  2461 2462

  // Eu p od e r i a ter feito toda a conta e e n c o n t r a d o os n u m e r a d o r e s para depois testar o grau , mas quero que esta etapa seja e f i c i e n t e .

  2460

  // H I P O T E S E - se o resto for d i f e r e n t e de 0 , entao o b r i g a t o r i a m e n t e t e r e m o s um n u m e r a d o r em " a " de grau igual a p_3 , resto .

  2440 2441

  2439

  2396

  l i s t a _ p t r 2 = s u b s t i t u i _ v a r ( lista_ptr3 , lista_ptr1 , c o m m o n _ v a r ) ;

  2416 // BUG : 0 ,9 - 0 ,9 = 1.11 E -15 , ou seja tenho que forcar um zero no braco . 2417

  // 4) s i m p l i f i c a e r e o r d e n a P 3 _ r e s t o

  2414 2415

  l i s t a _ p t r 3 = l i s t a _ p t r 2 ;

  2413

  // atualiza - se o p o n t e i r o

  2411 2412

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 3 ) ;

  2410

  // destroi - se o p o l i n o m i o de s u b s t i t u i c a o

  2408 2409

  2404 // ja que a v a r i a v e l pode estar em um grau maior . 2405 2406 2407

  2418 2419 2420

  // l i s t a _ p t r 1 r e s u l t a n t e do passo a n t e r i o r . c o n t i n u o e s c a n e a n d o a partir do p r i m e i r o m o n o m i o modificado ,

  2403

  

// e se e n c o n t r a r a v a r i a v e l comum , eu a excluo , e m u l t i p l i c o o m o n o m i o r e s u l t a n t e por cada um dos m o n o m i o s de

  2402

  // agora e a parte mais complicada , devo s c a n e a r cada v a r i a v e l de cada m o n o mi o de lista_expr3 ,

  2401

  // 3) s u b s t i t u i o p o l i n o m i o e n c o n t r a d o na v a r i a v e l comum em l i s t a _ e x p r 3

  2399 2400

  }

  2397 2398

  }

  l i s t a _ p t r 2 = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 3 ) ;

  // destroi - se P 3 _ r e s t o sem s i m p l i f i c a c a o

  // 5) divide - se P 3 _ r e s t o por P 2 _ s u b s t e guarda o r e s u l t a d o em n u m e r a d o r _ a

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 1 ) ;

  2438

  l i s t a _ p t r 3 = NULL ;

  2436

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 3 ) ;

  2435

  l i s t a _ p t r 1 = l e x d e g b u b b l e s o r t ( l i s t a _ p t r 1 ) ;

  2434

  l i s t a _ p t r 1 = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 3 ) ;

  2433

  // s i m p l i f i c o e r e o r d e n o

  2431 2432

  2430

  2421

  // d e s t r u o o p o l i n o m i o de s u b s t i t u i c a o na v a r i a v e l comum

  2428 2429

  l i s t a _ p t r 3 = s u b s t i t u i _ v a r ( P2 , lista_ptr1 , c o m m o n _ v a r ) ;

  2427

  // s u b s t i t u o o p o l i n o m i o de s u b s t i t u i c a o em P2

  2425 2426

  l i s t a _ p t r 2 = l e x d e g b u b b l e s o r t ( l i s t a _ p t r 2 ) ;

  2424

  // ordena - se o p o l i n o m i o

  2422 2423

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 3 ) ;

  • n u m e r a d o r _ a = NULL ;
  • q u o c i e n t e = NULL ;
  • n u m e r a d o r _ a = NULL ;
  • q u o c i e n t e = NULL ;
  • n u m e r a d o r _ a = NULL ;

  • n u m e r a d o r _ b = NULL ;
  • q u o c i e n t e = NULL ;

  // p r oc u r o pela v a r i a v e l comum no m o n o m i o

  2534

  while (* s t r _ p t r != ’ \0 ’)

  2533

  // removo o c a r a c t e r da v a r i a v e l da string , d e s l o c a n d o o r e s t a n t e dela para a e s q u e r d a

  2532

  {

  2531

  

if (( s t r _ p t r = strchr ( p_dest - > c o d i g o s _ n u m e r a d o r , c o m m o n _ v a r ) ) != NULL )

  2530

  {

  2529

  if ( p_dest - > c o d i g o s _ n u m e r a d o r != NULL )

  2528

  2527

  2535

  {

  2526

  while ( TRUE )

  2525

  p_dest = c o p i a _ l i s t a _ e x p r ( p _ d e s t i n o ) ;

  2524

  l i s t a _ e x p r * lista_ptr1 , * lista_ptr2 , * lista_ptr3 , * p_de st ;

  2523

  char * s tr _ p t r ;

  2522

  {

  2521

  l i s t a _ e x p r * s u b s t i t u i _ v a r ( l i s t a _ e x p r * p_destino , l i s t a _ e x p r * p_fonte , char c o m m o n _ v a r )

  2518 2519 2520

  {

  2536

  2517

  // salvo o p r o x i m o m o n o m i o

  2555

  {

  2554

  if ( p_dest - > a n t e r i o r != NULL )

  2552 2553

  }

  2551

  p_dest - > p r o x i m o = NULL ;

  2550

  // isolo o m o n o m i o

  2548 2549

  l i s t a _ p t r 1 = p_dest - > p r o x i m o ;

  2547

  2546

  s t r _ p t r ++;

  {

  2545

  if ( p_dest - > p r o x i m o != NULL )

  2544

  // agora isolo o monomio , caso P3 tenha mais de 1

  2542 2543

  l i s t a _ p t r 2 = NULL ;

  2541

  l i s t a _ p t r 1 = NULL ;

  2540

  // i n i c i a l i z a c a o de p o n t e i r o s

  2538 2539

  }

  2537

  }

  return 1;

  // salvo o m o n o m i o a n t e r i o r

  l i s t a _ p t r 1 = m u l t i p l i c a _ e x p r (* numerador_a , P2 ) ;

  2492

  // 3) divido o r e s u l t a d o por P1

  2490 2491

  l i s t a _ p t r 2 = l e x d e g b u b b l e s o r t ( l i s t a _ p t r 3 ) ;

  2489

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 2 ) ;

  2488

  l i s t a _ p t r 3 = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 2 ) ;

  2487

  s u b t r a i _ e x p r (& lista_ptr2 , l i s t a _ p t r 1 ) ;

  2486

  // 2) s u b t r a i o l i s t a _ p t r 1 de P3_resto , e guardo o r e s u l t a d o em l i s t a _ p t r 2

  2484 2485

  2483

  2493 2494 // H I P O T E S E - igual acima . 2495

  l i s t a _ p t r 2 = c o p i a _ l i s t a _ e x p r ( P 3 _ r e s t o ) ;

  2482

  // copio P3

  2481

  // 1) m u l t i p l i c o " a " por P2

  2480

  // Para achar o s eg u n d o n u m e r a d o r da fracao p a r c i a l :

  2479

  // foi e n c o n t r a d o um n u m e r a d o r _ a d e c e n t e . E n c o n t r a r agora o n u m e r a d o r _ b

  2477 2478

  resto = NULL ;

  2476

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( resto ) ;

  2475

  p o l y d i v ( lista_ptr2 , P1 , numerador_b , & resto ) ;

  if ( resto - > p a r a m e t r o != 0.0)

  2515

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( resto ) ;

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( P 3 _ r e s t o ) ;

  2514

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( resto ) ;

  2513

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 2 ) ;

  2512

  // se chegou ate aqui , a o p e r a c a o foi um s u c e s s o

  2510 2511

  }

  2509

  return 0;

  2507 2508

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( P 3 _ r e s t o ) ;

  2506

  2505

  2496

  2504

  2503

  2502

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a (* q u o c i e n t e ) ;

  2501

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a (* n u m e r a d o r _ a ) ;

  2500

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a (* n u m e r a d o r _ b ) ;

  2499

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( l i s t a _ p t r 2 ) ;

  2498

  // limpar tudo e r e t o r n a r 0

  2497

  {

  • s t r _ p t r = *( s t r _ p t r + 1) ;

  2556

  2612

  2618

  int i ;

  2617

  v e t o r _ p o l i n o m i o s * e l e m e n t o _ a t u a l = NULL ;

  2616

  static int p o l y _ i d = 0;

  2615

  // v a r i a v e l que vai dar um i d e n t i f i c a d o r aos p o l i n o m i o s

  2614

  {

  2613

  v e t o r _ p o l i n o m i o s * g e r a _ v e t o r ( v e t o r _ p o l i n o m i o s * ultimo _ gerado , l i s t a _ e x p r * p o l i n o mi o _ b a s e , l i s t a _ e x p r * v a r i a v e l _ at u a l , int lim_inferior , int l i m _ s u p e r i o r )

  // funcao que gera um c o n j u n t o de v e t o r e s de e n t r a d a

  2619

  2607 2608 2609 2610 2611

  }

  2606

  return p_dest ;

  2605

  }

  2603 2604

  p_dest = p_dest - > p r o x i m o ;

  2602

  else

  2601

  }

  for ( i = l i m _ s u p e r i o r ; i >= l i m _ i n f e r i o r ; i - -)

  {

  break ;

  2627

  2633

  e l e m e n t o _ a t u a l - > p o l i n o m i o = ( p o l i n o m i o *) malloc ( sizeof ( p o l i n o m i o ) ) ; // TODO : c o n t r o l e de erro

  2632

  e l e m e n t o _ a t u a l = ( v e t o r _ p o l i n o m i o s *) malloc ( sizeof ( v e t o r _ p o l i n o m i o s ) ) ; // TODO : c o n t r o l e de erro

  2631

  v a r i a v e l _ a t u a l - > p a r a m e t r o = i ;

  2630

  {

  2629

  for ( i = l i m _ s u p e r i o r ; i >= l i m _ i n f e r i o r ; i - -)

  2628

  // ao chegar na ultima variavel , gerar v e t o r e s v a r i a n d o o p a r a m e t r o da ultima v a r i a v e l de l i m _ i n f e r i o r a l i m _ s u p e r i o r

  {

  2620

  2626

  else // chegou na ultima v a r i a v e l

  2625

  u l t i m o _ g e r a d o = g e r a _ v e t o r ( ult imo_gerado , p o l i n o m i o _ b a s e , v a r i a v e l _ a t u a l - > proximo , lim_inferior , l i m _ s u p e r i o r ) ;

  2624

  if ( v a r i a v e l _ a t u a l - > p r o x i m o != NULL )

  2623

  // p e r c o r r e o p o l i n o m i o base ate chegar na ultima v a r i a v e l

  2622

  v a r i a v e l _ a t u a l - > p a r a m e t r o = i ;

  2621

  // a t ri b u o a v a r i a v e l atual o valor de i ;

  2600

  2598 2599

  l i s t a _ p t r 2 = p_dest - > a n t e r i o r ;

  // d e s a l o c o o m on o m i o o r i g i n a l

  lista_ptr3 - > a n t e r i o r = l i s t a _ p t r 2 ;

  2575

  // c o n e ct o o p o l i n o m i o r e s u l t a n t e da m u l t i p l i c a c a o

  2573 2574

  p_dest = l i s t a _ p t r 3 ;

  2572

  

// do r e s u l t a d o da multip licacao , para que esgote - se todos os graus da v a r i a v e l comum

  2571

  // r e a p r o v e i t o o p o n t e i r o para a p o n t a r para o p r o x i m o m o n o m i o a ser avaliado , que e o p r i m e i r o

  2569 2570

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( p_dest ) ;

  2568

  2566 2567

  if ( l i s t a _ p t r 2 != NULL )

  l i s t a _ p t r 3 = m u l t i p l i c a _ e x p r ( p_fonte , p_dest ) ;

  2565

  // r e a l iz o a m u l t i p l i c a c a o

  2563 // mas se der bug , devo c o m e c ar por aqui . 2564

  // a principio , a string conter apenas um \0 nao impede a m u l t i p l i c a c a o de f u n c i o n a r c o r r e t a m e n t e

  2561 2562

  }

  2560

  p_dest - > a n t e r i o r = NULL ;

  2559

  // pode ser que isso seja d e s n e c e s s a r i o se eu for o p t i m i z a r

  2557 2558

  2576

  2577

  while ( p_dest - > a n t e r i o r != NULL ) p_dest = p_dest - > a n t e r i o r ;

  2587 2588

  2596

  {

  2595

  if ( p_dest - > p r o x i m o == NULL )

  2594

  // c o n t i n u o a busca ou t e r m i n o o laco , " r e b o b i n a n d o " o p o n t e i r o para o inicio da lista

  2591 } // else : TODO eu s i m p l e s m e n t e pulo o m o n o m i o se for so um p a r a m e t r o . 2592 2593

  }

  2590

  c o n t i n u e ;

  2589

  // como ja d e t e r m i n e i qual m o n o m i o sera a v a l i a d o no p ro x i m o passo , posso pular para o inicio do laco

  lista_ptr1 - > a n t e r i o r = l i s t a _ p t r 3 ;

  lista_ptr2 - > p r o x i m o = l i s t a _ p t r 3 ;

  2586

  if ( l i s t a _ p t r 1 != NULL )

  2585

  lista_ptr3 - > p r o x i m o = l i s t a _ p t r 1 ;

  2584

  // e o c o n e c t o com o resto de P3

  2582 2583

  l i s t a _ p t r 3 = lista_ptr3 - > p r o x i m o ;

  2581

  while ( lista_ptr3 - > p r o x i m o != NULL )

  2580

  // e n c o n t r o o ultimo m o n o m i o r e u l t a n t e da m u l t i p l i c a c a o

  2578 2579

  // copio o p o l i n o m i o base com os p a r a m e t r o s do jeito que estao

  2634

  2684

  2691

  {

  2690

  v e t o r _ p o l i n o m i o s * r e m o v e _ p o l i n o m i o ( v e t o r _ p o l i n o m i o s * e l e m e n t o )

  2689

  // r e t o rn a o e l e m e n t o a n t e r i o r ao removido , ou o inico da lista

  2688

  }

  2687

  return lista ;

  2686

  // se nada encontrou , r e t o r n a o inicio da lista

  2685

  }

  p _ l i s t a = p_lista - > p r o x i m o _ p o l i n o m i o ;

  2692 2693

  2683

  // i n c r e m e n t a a busca

  2681 2682

  }

  2680

  return p _ l i s t a ;

  2678 2679

  p _ l i s t a = p_lista - > p o l i n o m i o _ a n t e r i o r ;

  2677

  while ( p_lista - > p o l i n o m i o _ a n t e r i o r != NULL )

  2676

  // r e b o b i n a r a lista

  2674

  p _ l i s t a = r e m o v e _ p o l i n o m i o ( p _ l i s t a ) ;

  v e t o r _ p o l i n o m i o s * esq , * dir ;

  // gravo as bordas

  {

  2704 2705

  2713 2714

  return NULL ;

  2712

  if ( dir == NULL && esq == NULL )

  2711

  // caso tenha e s v a z i a d o a lista

  2709 2710

  free ( e l e m e n t o ) ;

  2708

  free ( elemento - > p o l i n o m i o ) ;

  2707

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( elemento - > polinomio - > P ) ;

  2706

  // e l i m i n a r o e l e m e n t o

  dir - > p o l i n o m i o _ a n t e r i o r = esq ;

  2694

  2703

  if ( dir != NULL )

  2702

  // ajusto os p o n t e i r o s Ĺ d i r e i t a

  2700 2701

  esq - > p r o x i m o _ p o l i n o m i o = dir ;

  2699

  if ( esq != NULL )

  2698

  // ajusto os p o n t e i r o s Ĺ e s q u e r d a

  2696 2697

  dir = elemento - > p r o x i m o _ p o l i n o m i o ;

  2695

  esq = elemento - > p o l i n o m i o _ a n t e r i o r ;

  2673

  2672

  // e l i m in o os e l e m e n t o s zero

  if ( u l t i m o _ g e r a d o != NULL )

  else

  2652

  }

  2651

  ultimo _gerado - > p r o x i m o _ p o l i n o m i o = NULL ;

  2650

  u l t i m o _ g e r a d o = e l e m e n t o _ a t u a l ;

  2649

  e l e m e n t o _ a t u a l - > p o l i n o m i o _ a n t e r i o r = u l t i m o _ g e r a d o ;

  2648

  ultimo _gerado - > p r o x i m o _ p o l i n o m i o = e l e m e n t o _ a t u a l ;

  2647

  {

  2646

  2645

  {

  // c o n c a t e n o na lista de p o l i n o m i o s

  2643 2644

  e l e m e n t o _ a t u a l - > polinomio - > f l a g _ a p p r o v e d = 0;

  2642

  // i n i t i a l i z e the a p p r o v a l flag for f u r t h e r BP set r e d u c t i o n p u r p o s e s

  2640 2641

  p o l y _ i d ++;

  2639

  e l e m e n t o _ a t u a l - > polinomio - > id = p o l y _ i d ;

  2638

  // a t r i bu o um i d e n t i f i c a d o r e i n c r e m e n t o

  2636 2637

  e l e m e n t o _ a t u a l - > polinomio - > P = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( p o l i n o m i o _ b a s e ) ;

  2635

  2653

  2654

  if ( p_lista - > polinomio - >P - > p a r a m e t r o == 0.0)

  2663

  2671

  // apenas no p o l i n o m i o nulo , o p r i m e i r o m o n o m i o e zero

  2670

  {

  2669

  while ( p _ l i s t a != NULL )

  2668

  v e t o r _ p o l i n o m i o s * p _ l i s t a = lista ;

  2667

  {

  2666

  v e t o r _ p o l i n o m i o s * e l i m i n a _ z e r o ( v e t o r _ p o l i n o m i o s * list a )

  2664 2665

  }

  return u l t i m o _ g e r a d o ;

  u l t i m o _ g e r a d o = e l e m e n t o _ a t u a l ;

  2658

  2655

  e l e m e n t o _ a t u a l - > p r o x i m o _ p o l i n o m i o = NULL ;

  2656

  

e l e m e n t o _ a t u a l - > p o l i n o m i o _ a n t e r i o r = NULL ;

  2657

  }

  }

  2662

  2659

  return u l t i m o _ g e r a d o ;

  2660

  }

  2661

  }

  // se apeans o e s q u e r d o for nulo , ja s a b e m o s que o inicio da lista e o da d i r e i t a

  2715

  2769

  p o l i n o m i o _ b a s e = m o n o m i o _ a t u a l ;

  2775

  {

  2774

  if ( p o l i n o m i o _ b a s e == NULL )

  2773

  monomio _atual - > c o d i g o s _ d e n o m i n a d o r = NULL ;

  2772

  monomio _atual - > p a r a m e t r o = 1.0;

  2771

  monomio _atual - > c o d i g o s _ n u m e r a d o r [1] = ’ \0 ’;

  2770

  monomio _atual - > c o d i g o s _ n u m e r a d o r [0] = p e r c o r r e _ t a b e l a _ l i t e r a i s - > codigo ;

  monomio _atual - > c o d i g o s _ n u m e r a d o r = ( char *) malloc (2* sizeof ( char ) ) ;

  p o l i n o m i o _ b a s e - > a n t e r i o r = NULL ;

  2768

  m o n o m i o _ a t u a l = c o n s t r o i _ e l e m e n t o _ z e r a d o () ;

  2767

  {

  2766

  while ( p e r c o r r e _ t a b e l a _ l i t e r a i s != NULL )

  2763 2764 // p e r c o r r e as v a r i a v e i s g r a v a d a s na tabela de literais , g e r a n d o um p o l i n o m i o que e a c o m b i n a c a o linear delas . 2765

  p o l i n o m i o _ b a s e = NULL ;

  2761 2762

  l i s t a _ e x p r * p o l i n o m i o _ b a s e , * m o n o m i o _ a t u a l ;

  2760

  t a b e l a _ l i t e r a i s * p e r c o r r e _ t a b e l a _ l i t e r a i s = l i s t a _ l i t e r a i s ;

  2759

  {

  2776

  2777

  l i s t a _ e x p r * g e r a _ p o l i n o m i o _ b a s e ( t a b e l a _ l i t e r a i s * l i s t a _ l i t e r a i s )

  p e r c o r r e _ t a b e l a _ l i t e r a i s = p e r c o r r e _ t a b e l a _ l i t e r a i s - > p r o x i m o _ c o d i g o ;

  return p o l i n o m i o _ b a s e ;

  2793 2794

  }

  2792

  p o l i n o m i o _ b a s e = p o l i n o m i o _ b a s e - > a n t e r i o r ;

  2791

  {

  2790

  while ( p o l i n o m i o _ b a s e - > a n t e r i o r != NULL )

  2789

  // r e b o b i n a o p o l i n o m i o base

  2788

  }

  2786 2787

  2785

  p o l i n o m i o _ b a s e - > p r o x i m o = NULL ;

  }

  2784

  p o l i n o m i o _ b a s e = p o l i n o m i o _ b a s e - > p r o x i m o ;

  2783

  monomio _atual - > a n t e r i o r = p o l i n o m i o _ b a s e ;

  2782

  p o l i n o m i o _ b a s e - > p r o x i m o = m o n o m i o _ a t u a l ;

  2781

  {

  2780

  else

  2779

  }

  2778

  2758

  2757

  if ( esq == NULL )

  }

  2732

  esq = elemento - > p o l i n o m i o _ a n t e r i o r ;

  2731

  // gravo as bordas

  2729 2730

  v e t o r _ p o l i n o m i o s * esq , * dir ;

  2728

  {

  2727

  v e t o r _ p o l i n o m i o s * r e m o v e _ p o l i n o m i o _ r e t o r n a _ a n t e r i o r ( v e t o r _ p o l i n o m i o s * e l e m e n t o )

  2726

  // r e t o rn a o anterior , pois pode ser que remova o p r i m e i r o e l e m e n t o

  2724 2725

  2723

  2733 2734

  }

  2722

  return esq ;

  2721

  {

  2720

  else // r e t o r n a r o e s q u e r d o

  2719

  }

  2718

  return dir ;

  2717

  {

  2716

  dir = elemento - > p r o x i m o _ p o l i n o m i o ;

  // ajusto os p o n t e i r o s Ĺ e s q u e r d a

  // gera o p o l i n o m i o base

  2745

  2754 2755

  }

  2753

  return esq ;

  2752

  // r e t o r n a r o p r o xi m o p o l i n o m i o

  2750 2751

  return NULL ;

  2749

  if ( dir == NULL && esq == NULL )

  2748

  // caso tenha e s v a z i a d o a lista

  2746 2747

  free ( e l e m e n t o ) ;

  free ( elemento - > p o l i n o m i o ) ;

  2735

  2744

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( elemento - > polinomio - > P ) ;

  2743

  // e l i m i n a r o e l e m e n t o

  2741 2742

  dir - > p o l i n o m i o _ a n t e r i o r = esq ;

  2740

  if ( dir != NULL )

  2739

  // ajusto os p o n t e i r o s Ĺ d i r e i t a

  2737 2738

  esq - > p r o x i m o _ p o l i n o m i o = dir ;

  2736

  if ( esq != NULL )

  2795

  2796

  }

  2854

  return p e r c o r r e _ v e t o r ;

  2852 2853

  }

  2851

  p e r c o r r e _ v e t o r = p e r c o r r e _ v e t o r - > p o l i n o m i o _ a n t e r i o r ;

  2850

  {

  2849

  while ( p e r c o r r e _ v e t o r - > p o l i n o m i o _ a n t e r i o r != NULL )

  2848

  // r e b o b i n a o vetor r e d u i z d o

  2846 2847

  2844 2845

  2855 2856

  break ;

  2843

  else

  2842

  p e r c o r r e _ v e t o r = p e r c o r r e _ v e t o r - > p r o x i m o _ p o l i n o m i o ;

  2841

  else if ( p e r c o r r e _ v e t o r - > p r o x i m o _ p o l i n o m i o != NULL )

  2840

  // se nao for o ultimo e l e m e n t o incrementa , caso c o n t r a r i o sai do loop

  2839

  }

  2838

  p e r c o r r e _ v e t o r = r e m o v e _ p o l i n o m i o _ r e t o r n a _ a n t e r i o r ( p e r c o r r e _ v e t o r ) ;

  }

  v e t o r _ p o l i n o m i o s * r e m o v e _ p o l i n o m i o s _ r e d u n d a n t e s ( v e t o r _ p o l i n o m i o s * v e t o r _ e n t r a d a )

  

// a v a r i a v e l de r e t o r n o guarda o p o l i n o m i o anterior , para que o final da lista seja m a n t i d o

  if ( p _ v e t o r 1 == NULL )

  2875

  p _ v e t o r 2 = p_vetor1 - > p r o x i m o _ p o l i n o m i o ;

  2873 2874

  flag = 0;

  2872

  {

  2871

  while ( p_vetor1 - > p r o x i m o _ p o l i n o m i o != NULL )

  2870

  // para cada vetor , eu divido ele por todos os outros p o l i n o m o i o s . se o resto da zero , e porque um e c o m b i n a c a o linear do outro

  2869

  return NULL ;

  2868

  2867

  2857

  // c o n d i c a o de erro

  2865 2866

  p _ v e t o r 1 = v e t o r _ e n t r a d a ;

  2864

  // i n i c i a l i z o o p o n t e i r o de v a r r e d u r a

  2862 2863

  int flag = 0;

  2860 2861

  l i s t a _ e x p r * expr1 , * expr2 , *Q , * R ;

  2859

  v e t o r _ p o l i n o m i o s * p_vetor1 , * p _ v e t o r 2 ;

  2858

  {

  2836

  2835

  }

  2806 2807

  // aponta para o p o l i n o m i o

  2813

  {

  2812

  while ( p e r c o r r e _ v e t o r != NULL )

  2811

  // v a r r e d u r a de todas as e n t r a d a s g e r a d a s r e m o v e n d o t o d o d o s os p o l i n o m i o s onde todos os c o e f i c i e n t e s sao n e g a t i v o s

  2810

  return NULL ;

  2809

  if ( p e r c o r r e _ v e t o r == NULL )

  2808

  // c o n d i c a o de erro

  p e r c o r r e _ v e t o r = v e t o r _ e n t r a d a ;

  p e r c o r r e _ e x p r = p e r c o r r e _ v e t o r - > polinomio - > P ;

  2805

  // i n i c i a l i z o o p o n t e i r o de v a r r e d u r a

  2803 2804

  int teste ;

  2802

  l i s t a _ e x p r * p e r c o r r e _ e x p r ;

  2801

  v e t o r _ p o l i n o m i o s * p e r c o r r e _ v e t o r ;

  2800

  {

  2799

  v e t o r _ p o l i n o m i o s * r e m o v e _ p o l i n o m i o s _ n e g a t i v o s ( v e t o r _ p o l i n o m i o s * v e t o r _ e n t r a d a )

  2797 2798

  2814

  2815 2816

  {

  break ;

  2834

  if (! teste )

  2833

  // se teste for 0 , o p o l i n o m i o e todo negativo , e deve ser r e m o v i d o do vetor

  2831 2832

  }

  2830

  p e r c o r r e _ e x p r = percorre_ex pr - > p r o x i m o ;

  2829

  // i n c r e m e n t o o p o n t e i r o

  2827 2828

  }

  2826

  2825

  // i n i c i a l i z o a v a r i a v e l de teste

  teste = 1;

  2824

  {

  2823

  if ( per corre_expr - > p a r a m e t r o > 0.0)

  2822

  {

  2821

  while ( p e r c o r r e _ e x p r != NULL )

  2820

  // p e r c o r r o o p o l i n o m i o p r o c u r a n d o c o e f i c i e n t e s p o s i t i v o s . Se achar algum mudo o estado da v a r i a v e l de teste

  2818 2819

  teste = 0;

  2817

  while ( p _ v e t o r 2 != NULL )

  2876

  {

  2877

  // pula caso os p o l i n o m i o s forem os mesmos

  2878

  if ( p _ v e t o r 2 == p _ v e t o r 1 )

  2879

  {

  2880

  p _ v e t o r 2 = p_vetor2 - > p r o x i m o _ p o l i n o m i o ;

  2881

  c o n t i n u e ;

  2882

  }

  2883

  // copio a e x p r e s s a o de vetor1

  2884

  expr1 = c o p i a _ l i s t a _ e x p r ( p_vetor1 - > polinomio - > P ) ;

  2885

  // copio a e x p r e s s a o de vetor2

  2886

  expr2 = c o p i a _ l i s t a _ e x p r ( p_vetor2 - > polinomio - > P ) ;

  2887 2888

  // divido os dois

  2889

  p o l y d i v ( expr1 , expr2 , &Q , & R ) ;

  2890 2891

  // seo resto for 0 , e o q u o c i e n t e for uma constante , devo r e m o v e r p _ v e t o r _ 1

  2892

  // bogus = ( int ) (R - > p a r a m e t r o ) ;

  2893

  if (( R - > p a r a m e t r o == 0.0) && Q - > c o d i g o s _ n u m e r a d o r == NULL )

  2894

  {

  2895

  // devide se remove vetor1 ou vetor2

  2896

  if ( fabs (Q - > p a r a m e t r o ) >= 1.0)

  2897

  {

  2898

  // p _ v e t o r 1 a p o n t a r a para o p r o x i m o da lista apos ser r e m o v i d o

  2899

  p _ v e t o r 1 = r e m o v e _ p o l i n o m i o ( p _ v e t o r 1 ) ;

  2900

  // retoma a busca a partir do p r o x i m o p o l i n o m i o p r i n c i p a l

  2901

  p _ v e t o r 2 = NULL ;

  2902 2903

  // seta flag de r e i n i c i o

  2904

  flag = 1;

  2905

  }

  2906

  else

  2907

  {

  2908

  // p _ v e t o r 1 a p o n t a r a para o p r o x i m o da lista apos ser r e m o v i d o

  2909

  p _ v e t o r 2 = r e m o v e _ p o l i n o m i o ( p _ v e t o r 2 ) ;

  2910

  }

  2911

  }

  2912 2913

  // d e s tr u o expr

  2914

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( expr1 ) ;

  2915

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( expr2 ) ;

  2916

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ; d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R ) ;

  2918

  Q = NULL ;

  2919

  R = NULL ;

  2920 2921

  // i n c r e m e n t o o p o n t e i r o

  2922

  if ( p _ v e t o r 2 != NULL )

  2923

  p _ v e t o r 2 = p_vetor2 - > p r o x i m o _ p o l i n o m i o ;

  2924

  }

  2925 2926

  // testa flag de r e i n i c i o

  2927

  if (! flag )

  2928

  {

  2929

  // i n c r e m e n t o a busca p r i n c i p a l

  2930

  if ( p_vetor1 - > p r o x i m o _ p o l i n o m i o != NULL )

  2931

  p _ v e t o r 1 = p_vetor1 - > p r o x i m o _ p o l i n o m i o ;

  2932

  else

  2933

  break ;

  2934

  }

  2935

  }

  2936 2937

  // r e b o b i n a o vetor r e d u i z d o

  2938

  while ( p_vetor1 - > p o l i n o m i o _ a n t e r i o r != NULL )

  2939

  {

  2940

  p _ v e t o r 1 = p_vetor1 - > p o l i n o m i o _ a n t e r i o r ;

  2941

  }

  2942 2943

  return p _ v e t o r 1 ;

  2944

  }

  2945 2946

  // funcao que r e to r n a o grau de um p o l i n o m i o

  2947

  int deg ( l i s t a _ e x p r * p o l y _ i n )

  2948

  {

  2949

  int grau = 0;

  2950

  int g r a u _ m a x = 0;

  2951

  l i s t a _ e x p r * p t r _ p o l y = p o l y _ i n ;

  2952 2953

  // p e r c o r r e m o n o m i o a m o n o m io v e r i f i c a n d o o grau , que nada mais e senao o t a m a n h o da string de c o d i g o s do n u m e r a d o r

  2954

  while ( p t r _ p o l y != NULL )

  2955

  {

  2956

  if ( ptr_poly - > c o d i g o s _ n u m e r a d o r == NULL )

  2957

  grau = 0;

  2958

  else

  2959

  grau = ( int ) strlen ( ptr_poly - > c o d i g o s _ n u m e r a d o r ) ;

  2960 2961

  if ( grau > g r a u _ m a x )

  2962

  g r a u _ m a x = grau ;

  2963 2964

  p t r _ p o l y = ptr_poly - > p r o x i m o ;

  2965 2966

  }

  2967 2968

  return g r a u _ m a x ;

  2969

  }

  2970 2971

  v e t o r _ s e m e n t e s * g e r a _ v e t o r _ s e m e n t e ( v e t o r _ p o l i n o m i o s * vetor_in , l i s t a _ e x p r * e q _ e n t r a d a )

  2972

  {

  2973

  v e t o r _ p o l i n o m i o s * p t r _ v e t o r _ i n ;

  2974

  v e t o r _ p o l i n o m i o s * p t r _ v e t o r _ b a s e = v e t o r _ i n ;

  2975

  v e t o r _ s e m e n t e s * v e t o r _ g e r a d o = NULL ;

  2976 2977

  // r e s u l t a d o s

  2978

  l i s t a _ e x p r * R1 ;

  2979

  l i s t a _ e x p r * R2 ;

  2980

  l i s t a _ e x p r * Q ;

  2981 2982

  // se por um acaso passar apenas um elemento , r e t o r n a r nulo

  2983

  if ( v e t o r _ i n == NULL )

  2984

  {

  2985

  return NULL ;

  2986

  }

  2987

  if ( vetor_in - > p r o x i m o _ p o l i n o m i o == NULL )

  2988

  {

  2989

  return NULL ;

  2990

  }

  2991 2992

  p t r _ v e t o r _ i n = vetor_in - > p r o x i m o _ p o l i n o m i o ;

  2993 2994

  

// p e r c o r r e o vetor de entrada , t e n t a n d o todas as c o m b i n a c o e s p o s s i v e i s . Como a ordem nao importa , vou sempre

i n c r e m e n t a n d o v e t o r _ i n tambem

  2995

  while ( p t r _ v e t o r _ b a s e - > p r o x i m o _ p o l i n o m i o != NULL )

  2996

  { // p t r _ v e t o r _ i n = vetor_in - > p r o x i m o _ p o l i n o m i o ;

  2998

  // nao r e s t r i c a o n e n h u m a em poder c o m b i n a r c o n s i g o mesmo

  2999

  p t r _ v e t o r _ i n = p t r _ v e t o r _ b a s e ;

  3000 3001

  while ( p t r _ v e t o r _ i n != NULL )

  3002

  {

  3003

  // tentar r e a l i z a r a e x p a n s a o em fr a c o e s p a r c i a i s

  3004

  if ( p a r t i a l _ f r a c t i o n _ e x p a n s i o n ( eq_entrada , p tr _ v e t o r _ b a s e - > polinomio - >P , ptr_vetor_in - > polinomio - >P , &Q ,& R1 , & R2 ) )

  3005

  {

  3006

  // c o n s e g u i uma e x p a n s a o em f r a c o e s p a r c i a i s adequada , p r e p a r a r vetor de semente , ao final ele sera r e b o b i n a d o

  3007

  if ( v e t o r _ g e r a d o == NULL )

  3008

  v e t o r _ g e r a d o = n o v o _ v e t o r _ s e m e n t e () ;

  3009

  else

  3010

  {

  3011

  // crio um novo e l e m e n t o ja ligado ao a n t e r i o r

  3012

  vetor_gerado - > c o n j u n t o _ p r o x = n o v o _ v e t o r _ s e m e n t e () ;

  3013

  // r e a l i zo o duplo e n c a d e a m e n t o

  3014

  vetor_gerado - > conjunto_pro x - > c o n j u n t o _ a n t = v e t o r _ g e r a d o ;

  3015

  // a t u a l i z o o p o n t e i r o

  3016

  v e t o r _ g e r a d o = vetor_gerado - > c o n j u n t o _ p r o x ;

  3017

  }

  3018 3019

  // p r e e n c h o os campos da semente , P1 e P2 devem ser copiados , pois ainda serao u t i l i z a d o s

  3020

  vetor_gerado - > P1 . P = c o p i a _ l i s t a _ e x p r ( p t r _ v e t o r _ b a s e - > polinomio - > P ) ;

  3021

  vetor_gerado - > P1 . id = p tr _ v e t o r _ b a s e - > polinomio - > id ;

  3022

  vetor_gerado - > P2 . P = c o p i a _ l i s t a _ e x p r ( ptr_vetor_in - > p olinomio - > P ) ;

  3023

  vetor_gerado - > P2 . id = ptr_vetor_in - > polinomio - > id ;

  3024

  // estes outros 3 nao p r e c i s a m de copia , pois serao u t i l i z a d o s apenas dentro do v e t o r d e s e m e n t e s

  3025

  vetor_gerado - > q u o c i e n t e = Q ;

  3026

  vetor_gerado - > R1 = R1 ;

  3027

  vetor_gerado - > R2 = R2 ;

  3028 3029

  }

  3030 3031

  // reseta as v a r i a v e i s

  3032

  R1 = NULL ;

  3033

  R2 = NULL ;

  3034

  Q = NULL ;

  3035 3036

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( entrada - > R1 ) ;

  3094

  {

  3093

  v e t o r _ p o l i n o m i o s * n o v o _ v e t o r _ p o l i n o m i o s ( void )

  3092

  // cria um novo e l e m e n t o de vetor de p o l i n o m i o s

  3089 3090 3091

  }

  3088

  free ( e n t r a d a ) ;

  3087

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( entrada - > R2 ) ;

  3086

  3085

  3095 3096

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( entrada - > q u o c i e n t e ) ;

  3084

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( entrada - > P2 . P ) ;

  3083

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( entrada - > P1 . P ) ;

  3081 3082

  return ;

  3080

  else

  3079

  d e s t r o i _ l i s t a _ s e m e n t e s ( entrada - > c o n j u n t o _ p r o x ) ;

  3078

  if ( e n t r a d a != NULL )

  v e t o r _ p o l i n o m i o s * novo ;

  novo = ( v e t o r _ p o l i n o m i o s *) malloc ( sizeof ( v e t o r _ p o l i n o m i o s ) ) ;

  void d e s t r o i _ l i s t a _ s e m e n t e s ( v e t o r _ s e m e n t e s * e n t r a d a ) {

  {

  3114 3115

  novo - > r e s t o _ p a r = NULL ;

  3113

  novo - > r e s t o _ i m p a r = NULL ;

  3112

  novo - > p o l y _ i m p a r e s = NULL ;

  3111

  novo - > p o l y _ p a r e s = NULL ;

  3110

  novo = ( v e t o r _ d e c o m p *) malloc ( sizeof ( v e t o r _ d e c o m p ) ) ;

  3109

  v e t o r _ d e c o m p * novo ;

  3108

  3107

  3097 3098

  v e t o r _ d e c o m p * n o v o _ v e t o r _ d e c o m p ( void )

  3106

  // cria e l e m e n t o de vetor de d e c o m p o s i c a o

  3104 3105

  }

  3103

  return ( novo ) ;

  3101 3102

  novo - > p r o x i m o _ p o l i n o m i o = NULL ;

  3100

  novo - > p o l i n o m i o _ a n t e r i o r = NULL ;

  3099

  novo - > p o l i n o m i o = NULL ;

  3077

  3075

  // i n c r e m e n t o p o n t e i r o para p r o x i m o teste

  3045

  }

  3052

  return v e t o r _ g e r a d o ;

  3051

  // r e t o r n a o vetor gerado

  3049 3050

  v e t o r _ g e r a d o = vetor_gerado - > c o n j u n t o _ a n t ;

  3048

  while ( vetor_gerado - > c o n j u n t o _ a n t != NULL )

  3047

  // r e b o b i n a o vetor de s e m e n t e s

  3046

  return NULL ;

  if ( v e t o r _ g e r a d o == NULL )

  // cria e l e m e n t o de vetor de s e m e n t e s

  3044

  // nao e n c o n t r o u n e n h u m a s e m e n t e

  3043

  }

  3042

  p t r _ v e t o r _ b a s e = p t r _ v e t o r _ b a s e - > p r o x i m o _ p o l i n o m i o ;

  3041

  // i n c r e m e n t o o p o n t e i r o para a p r o x i m a b a t e r i a de testes

  3039 3040

  }

  3038

  p t r _ v e t o r _ i n = ptr_vetor_in - > p r o x i m o _ p o l i n o m i o ;

  3037

  3053 3054

  3055

  // d e s t ro i toda a lista de s e m e n t e s

  novo - > q u o c i e n t e = NULL ;

  3073 3074

  }

  3072

  return novo ;

  3070 3071

  novo - > c o n j u n t o _ p r o x = NULL ;

  3069

  novo - > c o n j u n t o _ a n t = NULL ;

  3068

  novo - > R2 = NULL ;

  3067

  novo - > R1 = NULL ;

  3066

  3065

  v e t o r _ s e m e n t e s * n o v o _ v e t o r _ s e m e n t e ( void )

  novo - > P2 . id = 0;

  3064

  novo - > P2 . P = NULL ;

  3063

  novo - > P1 . id = 0;

  3062

  novo - > P1 . P = NULL ;

  3060 3061

  novo = ( v e t o r _ s e m e n t e s *) malloc ( sizeof ( v e t o r _ s e m e n t e s ) ) ; // TODO : c o n f e r i r erro de a l o c a c a o de m e m o r i a

  3058 3059

  v e t o r _ s e m e n t e s * novo ;

  3057

  {

  3056

  novo - > p r o x _ d e c o m p = NULL ;

  • vetor = n o v o _ p o l y ;

  3169

  void d e s t r o i _ v e t o r _ d e c o m p ( v e t o r _ d e c o m p * e n t r a d a )

  3176 3177

  }

  3175

  free ( e n t r a d a ) ;

  3174

  

// o vetor de p o l i n o m i o s apenas pode r e f e r e n c i a r p o l i n o m i o s e nao copia - los

  3172 3173

  }

  3171

  d e s t r o i _ v e t o r _ p o l i n o m i o s ( entrada - > p r o x i m o _ p o l i n o m i o ) ;

  3170

  {

  if ( entrada - > p r o x i m o _ p o l i n o m i o != NULL )

  {

  3168

  {

  3167

  void d e s t r o i _ v e t o r _ p o l i n o m i o s ( v e t o r _ p o l i n o m i o s * e n t r a d a )

  3165 3166

  }

  3164

  free ( e n t r a d a ) ;

  3162 3163

  d e s t r o i _ v e t o r _ p o l i n o m i o s ( entrada - > p o l y _ i m p a r e s ) ;

  3161

  if ( entrada - > p o l y _ i m p a r e s != NULL )

  3160

  d e s t r o i _ v e t o r _ p o l i n o m i o s ( entrada - > p o l y _ p a r e s ) ;

  3178

  3179

  if ( entrada - > p o l y _ p a r e s != NULL )

  // tirar a prova real entre a d e c o m p o s i c a o e n c o n t r a d a e a e q u a c a o de e n t r a d a

  3195 3196

  int f l a g _ t e s t e ;

  3194

  v e t o r _ p o l i n o m i o s * p o l y _ i m p a r _ p t r = decomp - > p o l y _ i m p a r e s ;

  3193

  v e t o r _ p o l i n o m i o s * p o l y _ p a r _ p t r = decomp - > p o l y _ p a r e s ;

  3192

  l i s t a _ e x p r * acum_par , * acum_impar , * acum , * acum2 , *Q , * R ;

  3191

  {

  3190

  int p r o v a _ r e a l ( v e t o r _ d e c o m p * decomp , l i s t a _ e x p r * e q _ e n t r a d a )

  3189

  3188

  if ( e n t r a d a == NULL )

  }

  3187

  d e s t r o i _ d e c o m p ( e n t r a d a ) ;

  3185 3186

  }

  3184

  d e s t r o i _ v e t o r _ d e c o m p ( entrada - > p r o x _ d e c o m p ) ;

  3183

  {

  3182

  if ( entrada - > p r o x _ d e c o m p != NULL )

  3181

  return ;

  3180

  3159

  3158

  3116

  3127

  {

  3135

  if ( p _ v e t o r == NULL )

  3134

  // caso a lista esteja vazia , tornar o novo e l e m e n t o o p r i m e i r o e l e m e n t o da lista

  3132 3133

  p _ v e t o r = * vetor ;

  3131

  // i n i c i a l i z a a lista

  3129 3130

  novo_poly - > p o l i n o m i o = e l e m e n t o ;

  3128

  n o v o _ p o l y = n o v o _ v e t o r _ p o l i n o m i o s () ;

  // cria - se o novo e l e m e n t o

  3137

  3125 3126

  v e t o r _ p o l i n o m i o s * p_vetor , * n o v o _ p o l y ;

  3124

  {

  3123

  void i n s e r e _ p o l i n o m i o ( v e t o r _ p o l i n o m i o s ** vetor , p o l i n o m i o * e l e m e n t o )

  3122

  // insere um p o l i n o m i o na lista de p o l i n o m i o s

  3120 3121

  }

  3119

  return novo ;

  3117 3118

  novo - > a n t _ d e c o m p = NULL ;

  3136

  }

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( entrada - > r e s t o _ p a r ) ; // d e s t ro i os v e to r e s de p o l i n o m i o s

  3147

  3156

  if ( entrada - > r e s t o _ p a r != NULL )

  3155

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( entrada - > r e s t o _ i m p a r ) ;

  3154

  if ( entrada - > r e s t o _ i m p a r != NULL )

  3153

  {

  3152

  void d e s t r o i _ d e c o m p ( v e t o r _ d e c o m p * en t r a d a )

  3149 3150 3151

  }

  3148

  }

  novo_poly - > p o l i n o m i o _ a n t e r i o r = p _ v e t o r ;

  3138

  3146

  p_vetor - > p r o x i m o _ p o l i n o m i o = n o v o _ p o l y ;

  3145

  // insere o e l e m e n t o

  3143 3144

  p _ v e t o r = p_vetor - > p r o x i m o _ p o l i n o m i o ;

  3142

  while ( p_vetor - > p r o x i m o _ p o l i n o m i o != NULL )

  3141

  // p r oc u r a o fim da fila

  3140

  {

  3139

  else

  a c u m _ p a r = c o p i a _ l i s t a _ e x p r ( poly_par_ptr - > polinomio - > P ) ; d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R ) ;

  3273

  {

  3255

  if (Q - > p a r a m e t r o != 0.0 && ! isnan (Q - > p a r a m e t r o ) && ! isinf (Q - > p a r a m e t r o ) && Q - > c o d i g o s _ n u m e r a d o r == NULL && Q

  3254

  // v e r i f i c a r se Q e uma c o n s t a n t e

  3253

  p o l y d i v ( acum2 , acum_par , &Q , & R ) ;

  3252

  // D i v id i r o resto ( acum2 ) por acum_par , se Q for uma constante , e R = 0 , entao decomp - > r e s t o _ i m p a r = Q , decomp

  3251

  R = NULL ;

  3250

  Q = NULL ;

  3249

  3248

  3256

  if (Q - > p a r a m e t r o != 0.0 && ! isnan (Q - > p a r a m e t r o ) && ! isinf (Q - > p a r a m e t r o ) && Q - > c o d i g o s _ n u m e r a d o r == NULL && Q - > p r o x i m o == NULL )

  3247

  // v e r i f i c a r se Q e uma c o n s t a n t e

  3246

  f l a g _ t e s t e = 0;

  3245

  // setar um flag para saber se o p r i m e i r o teste falhou

  3243 3244

  acum2 = R ;

  3242

  acum = Q ;

  3241

  p o l y d i v ( eq_entrada , acum_impar , &Q , & R ) ;

  {

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( decomp - > r e s t o _ i m p a r ) ;

  // Divido Er por polys impares , e Acum = R e acum2 = Q

  3266

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3272

  f l a g _ t e s t e = 1;

  3271

  {

  3270

  else

  3269

  }

  3268

  }

  3267

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R ) ;

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3257

  3265

  f l a g _ t e s t e = 1;

  3264

  {

  3263

  else

  3262

  }

  3260 3261

  decomp - > r e s t o _ i m p a r = Q ;

  3259

  decomp - > r e s t o _ p a r = acum ;

  3258

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( decomp - > r e s t o _ p a r ) ;

  3240

  3239

  3197

  3208 3209

  p o l y _ i m p a r _ p t r = p o l y _ i m p a r _ p t r - > p r o x i m o _ p o l i n o m i o ;

  3215 3216

  a c u m _ i m p a r = acum ;

  3214

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( a c u m _ i m p a r ) ;

  3213

  acum = m u l t i p l i c a _ e x p r ( acum_impar , p o l y _ i m p a r _ p t r - > p r o x i m o _ p o l i n o m i o - > polinomio - > P ) ;

  3212

  {

  3211

  while ( p o l y _ i m p a r _ p t r - > p r o x i m o _ p o l i n o m i o != NULL )

  3210

  // repito o mesmo para a parte impar

  }

  }

  3207

  p o l y _ p a r _ p t r = poly_par_ptr - > p r o x i m o _ p o l i n o m i o ;

  3205 3206

  a c u m _ p a r = acum ;

  3204

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( a c u m _ p a r ) ;

  3203

  acum = m u l t i p l i c a _ e x p r ( acum_par , poly_par_ptr - > p r o x i m o _ p o l i n o m i o - > polinomio - > P ) ;

  3202

  {

  3201

  while ( poly_par_ptr - > p r o x i m o _ p o l i n o m i o != NULL )

  3198 3199 3200

  a c u m _ i m p a r = c o p i a _ l i s t a _ e x p r ( p o l y _ i m p a r _ p t r - > polinom io - > P ) ;

  3217

  3218 3219

  {

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( a c u m _ i m p a r ) ;

  3238

  decomp - > resto_impar - > p a r a m e t r o == NAN || decomp - > resto_ par - > p a r a m e t r o == NAN || decomp - > resto_impar - > p a r a m e t r o == I N F I N I T Y || decomp - > r esto_par - > p a r a m e t r o == I N F I N I T Y )

  3236

  if ( decomp - > resto_impar - > p a r a m e t r o == 0.0 || decomp - > resto _par - > p a r a m e t r o == 0.0 ||

  3235

  // m u l t i p l i c o o r e s u l t a d o pelo lambda , se for d i f e r e n t e de zero . Caso contrario , temos que d i v i d i r a e q _ e n t r a d a pelo a c u m u l a d o

  3232 3233 3234

  acum = NULL ;

  3231

  a c u m _ i m p a r = acum ;

  3230

  acum = l e x d e g b u b b l e s o r t ( acum ) ;

  3229

  3228

  // s i m p l i f i c a a parte par

  acum = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( a c u m _ i m p a r ) ;

  3227

  // s i m p l i f i c a a parte impar

  3225 3226

  acum = NULL ;

  3224

  a c u m _ p a r = acum ;

  3223

  acum = l e x d e g b u b b l e s o r t ( acum ) ;

  3222

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( a c u m _ p a r ) ;

  3221

  acum = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( a c u m _ p a r ) ;

  3220

  • > r e s t o _ p a r = acum
  • > p r o x i m o == NULL && R - > p a r a m e t r o == 0.0)
  • > p r o x i m o == NULL )

  3274 3275

  if ( decomp - > resto_impar - > p a r a m e t r o == 0.0 || decomp - > resto _par - > p a r a m e t r o == 0.0 ||

  3331

  return FALSE ;

  3330

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( a c u m _ p a r ) ;

  3329

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( a c u m _ i m p a r ) ;

  3328

  {

  3327

  decomp - > resto_impar - > p a r a m e t r o == I N F I N I T Y || decomp - > r esto_par - > p a r a m e t r o == I N F I N I T Y )

  3326

  decomp - > resto_impar - > p a r a m e t r o == NAN || decomp - > resto_ par - > p a r a m e t r o == NAN ||

  3325

  3324

  3332 3333

  

// se mesmo apos esta t e n t a t i v a de e n c o n t r a r c o e f i c i e n t e s reais ainda tiver alguma i n c on s i s t e n c i a , r e t o r n a r 0

  3323

  }

  3320 3321 3322

  acum = NULL ;

  3319

  R = NULL ;

  3318

  Q = NULL ;

  3317

  }

  3316

  }

  3315

  }

  // m u l t i p l i c o a parte par pelo lambda impar

  3314

  3343

  3351

  acum = c o p i a _ l i s t a _ e x p r ( a c u m _ i m p a r ) ;

  3350

  // somo a parte impar com a parte par

  3348 3349

  acum = NULL ;

  3347

  a c u m _ i m p a r = l e x d e g b u b b l e s o r t ( a c u m _ i m p a r ) ;

  3346

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( acum ) ;

  3345

  a c u m _ i m p a r = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( acum ) ;

  3344

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( a c u m _ i m p a r ) ;

  acum = m u l t i p l i c a _ e x p r ( acum_impar , decomp - > r e s t o _ p a r ) ;

  3334

  3342

  // m u l t i p l i c o a parte impar pelo lambda par

  3340 3341

  acum = NULL ;

  3339

  a c u m _ p a r = l e x d e g b u b b l e s o r t ( a c u m _ p a r ) ;

  3338

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( acum ) ;

  3337

  a c u m _ p a r = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( acum ) ;

  3336

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( a c u m _ p a r ) ;

  3335

  acum = m u l t i p l i c a _ e x p r ( acum_par , decomp - > r e s t o _ i m p a r ) ;

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R ) ;

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  }

  p o l y d i v ( eq_entrada , acum_par , &Q , & R ) ;

  R = NULL ;

  3293

  Q = NULL ;

  3292

  {

  3291

  if (Q - > p a r a m e t r o != 0.0 && ! isnan (Q - > p a r a m e t r o ) && ! isinf (Q - > p a r a m e t r o ) && Q - > c o d i g o s _ n u m e r a d o r == NULL && Q

  3290

  // v e r i f i c a r se Q e uma c o n s t a n t e

  3288 3289

  acum2 = R ;

  3287

  acum = Q ;

  3286

  3285

  // D i v i di r o resto ( acum2 ) por acum_impar , se Q for uma constante , e R = 0 , entao decomp - > r e s t o _ p a r = Q , decomp - > r e s t o _ i m p a r = acum

  // Divido Er por polys pares , e Acum = R e acum2 = Q

  3284

  {

  3283

  if ( f l a g _ t e s t e )

  3282

  // se a p r i m e i r a t e n t a t i v a nao funcionar , fazer ao c o n t r a r i o

  3279 3280 3281

  acum = NULL ;

  3278

  R = NULL ;

  3277

  Q = NULL ;

  3276

  3294

  3295

  3313

  }

  else {

  3311

  }

  3309 3310

  }

  3308

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R ) ;

  3307

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3306

  {

  3305

  else

  3304

  3303

  p o l y d i v ( acum2 , acum_impar , &Q , & R ) ;

  decomp - > r e s t o _ p a r = Q ;

  3302

  decomp - > r e s t o _ i m p a r = acum ;

  3301

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( decomp - > r e s t o _ p a r ) ;

  3300

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( decomp - > r e s t o _ i m p a r ) ;

  3299

  {

  3298

  if (Q - > p a r a m e t r o != 0.0 && ! isnan (Q - > p a r a m e t r o ) && ! isinf (Q - > p a r a m e t r o ) && Q - > c o d i g o s _ n u m e r a d o r == NULL && Q - > p r o x i m o == NULL && R - > p a r a m e t r o == 0.0)

  3297

  // v e r i f i c a r se Q e uma c o n s t a n t e

  3296

  acum2 = c o p i a _ l i s t a _ e x p r ( a c u m _ p a r ) ;

  3352

  // a v an c a r o p o n t e i r o para fim da lista d e s t i n o

  3410

  // ligar as 2

  3408 3409

  p t r _ l i s t a _ o r i g e m = p t r _ l i s t a _ o r i g e m - > a n t _ d e c o m p ;

  3407

  while ( p t r _ l i s t a _ o r i g e m - > a n t _ d e c o m p != NULL )

  3406

  // r e b o b i n a r o p o n t e i r o da lista de origem

  3404 3405

  p t r _ l i s t a _ d e s t i n o = p t r _ l i s t a _ d e s t i n o - > p r o x _ d e c o m p ;

  3403

  while ( p t r _ l i s t a _ d e s t i n o - > p r o x _ d e c o m p != NULL )

  3402

  3401

  3411

  p t r _ l i s t a _ d e s t i n o = l i s t a _ d e s t i n o ;

  3400

  {

  3399

  else

  3398

  }

  3396 3397

  return p t r _ l i s t a _ o r i g e m ;

  3395

  // r e to r n o o fim da lista d e s t i n o como o fim da lista de origem

  3393 3394

  while ( p t r _ l i s t a _ o r i g e m - > p r o x _ d e c o m p != NULL ) p t r _ l i s t a _ o r i g e m = p t r _ l i s t a _ o r i g e m - > p r o x _ d e c o m p ;

  3391

  p t r _ l i s t a _ d e s t i n o - > p r o x _ d e c o m p = p t r _ l i s t a _ o r i g e m ;

  p t r _ l i s t a _ o r i g e m - > a n t _ d e c o m p = p t r _ l i s t a _ d e s t i n o ;

  3390

  3423

  3431

  return NULL ;

  3430

  {

  3429

  if ( e n t r a d a == NULL )

  3427 3428

  v e t o r _ d e c o m p * l i s t a _ d e c o m p = NULL ;

  3426

  v e t o r _ d e c o m p * p t r _ d e c o m p = NULL ;

  3425

  v e t o r _ s e m e n t e s * p t r _ s e m e n t e s ;

  3424

  {

  v e t o r _ d e c o m p * c o p i a _ v e t o r _ s e m e n t e ( v e t o r _ s e m e n t e s * e n t r a d a )

  3412 3413

  3422

  // funcao que pega os dados de um vetor s e me n t e e os t r a n s f e r e para um vetor decomp

  3420 3421

  }

  3419

  }

  3418

  return p t r _ l i s t a _ d e s t i n o ;

  3416 3417

  p t r _ l i s t a _ d e s t i n o = p t r _ l i s t a _ d e s t i n o - > p r o x _ d e c o m p ;

  3415

  while ( p t r _ l i s t a _ d e s t i n o - > p r o x _ d e c o m p != NULL )

  3414

  // a v an c a r o p o n t e i r o ate o final

  // aponto para o final da lista a ser i n s e r i d a

  {

  s o m a _ e x p r ( acum , acum2 ) ;

  if (Q - > c o d i g o s _ n u m e r a d o r == NULL && R - > c o d i g o s _ n u m e r a d o r == NULL && R - > p a r a m e t r o == 0.0 && ! isnan (Q - > p a r a m e t r o ) && ! isinf (Q - > p a r a m e t r o ) && Q - > p a r a m e t r o != 0.0)

  return TRUE ;

  3369

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( acum ) ;

  3368

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( a c u m _ p a r ) ;

  3367

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( a c u m _ i m p a r ) ;

  3366

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R ) ;

  3365

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3364

  {

  3363

  3362

  }

  p o l y d i v ( eq_entrada , acum , &Q , & R ) ;

  3361

  // divido o r e s u l t a d o pela e q u a c a o de entrada , e o resto deve dar 0 e o q u o c i e n t e ser uma c o n s t a n t e

  3359 3360

  acum2 = NULL ;

  3358

  acum = l e x d e g b u b b l e s o r t ( acum2 ) ;

  3357

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( acum ) ;

  3356

  acum2 = s i m p l i f i c a _ e x p r _ e x p a n d i d a ( acum ) ;

  3355

  // s i m p l i f i c a

  3353 3354

  3370

  3371

  3389

  }

  if ( l i s t a _ d e s t i n o == NULL )

  3388

  p t r _ l i s t a _ o r i g e m = l i s t a _ o r i g e m ;

  3386 3387

  v e t o r _ d e c o m p * p t r _ l i s t a _ o r i g e m , * p t r _ l i s t a _ d e s t i n o ;

  3385

  {

  3384

  v e t o r _ d e c o m p * i n s e r e _ l i s t a _ d e c o m p ( v e t o r _ d e c o m p * lista _ destino , v e t o r _ d e c o m p * l i s t a _ o r i g e m )

  3383

  // insere uma lista de d e c o m p o s i c o e s dentro de outra , r e t o r n a n d o um p o n t e i r o para o final dela

  3381 3382

  }

  3380

  3379

  else

  return FALSE ;

  3378

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( acum ) ;

  3377

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( a c u m _ p a r ) ;

  3376

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( a c u m _ i m p a r ) ;

  3375

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R ) ;

  3374

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3373

  {

  3372

  }

  3432 3433

  3482

  d e s t r o i _ d e c o m p ( d e c o m p _ r e f e r e n c i a ) ;

  3488

  d e c o m p _ a t u a l = d e c o m p _ r e f e r e n c i a - > p r o x _ d e c o m p ;

  3487

  // apagar o e l e m e n t o t e s t a d o e a t u a l i z a r o p o n t e i r o de r e f e r e n c i a

  3485 3486

  

e n c o n t r a _ d e c o m p _ r e c u r s i v a ( d e c o m p _ r e f e r e n c i a , d e c o m p _ r e f e r e n c i a , & lista_decomp , grau , e x p r _ s i m p l i f i c a d a ,

l i s t a _ l i t e r a i s , & t o t a l _ d e c o m p ) ;

  3484

  // para cada vetor incial de decomp referencia , e n c o n t r o todas as d e c o m p o s i c o e s que possam ser g e r a d as a partir dele

  3483

  {

  while ( d e c o m p _ r e f e r e n c i a != NULL )

  d e c o m p _ r e f e r e n c i a = d e c o m p _ a t u a l ;

  3481

  // loop de c o n s t r u c a o das d e c o m p o s i c o e s

  3479 3480

  s e c u n d a r i o _ p t r = e n t r a d a ;

  3478

  // i n i c i a l i z a c a o do p o n t e i r o de busca secundario , pode ser que o par de p o l i n o m i o s i n i c i a l possa c o m b i n a r com si mesmo

  3476 3477

  d e c o m p _ a t u a l = NULL ;

  3475

  d e c o m p _ a t u a l = d e c o m p _ r e f e r e n c i a ;

  3474

  3489

  3490

  3473

  // i m p r i m i r numero de d e c o m p o s i c o e s

  3507 3508 3509

  }

  3506

  return l i s t a _ d e c o m p ;

  3505

  // r e t o r n a r

  3503 3504

  printf ( " \ n Number of p a r t i a l f r a c t i o n o p e r a t i o n s p e r f o r m e d is : % d \ n " , g l o b a l _ n u m _ p a r f r a c ) ;

  3502

  printf ( " \ n \ nThe number of valid T r a n s l i n e a r d e c o m p o s i t i o n s found is : % d " , t o t a l _ d e c o m p ) ;

  3501

  3499 3500

  if ( d e c o m p _ r e f e r e n c i a != NULL )

  l i s t a _ d e c o m p = lista_decomp - > a n t _ d e c o m p ;

  3498

  while ( lista_decomp - > a n t _ d e c o m p != NULL )

  3497

  if ( l i s t a _ d e c o m p != NULL )

  3496

  // r e b o b i n a r a lista de d e c o m p o s i c o e s

  3493 3494 3495

  }

  3492

  d e c o m p _ r e f e r e n c i a - > a n t _ d e c o m p = NULL ;

  3491

  d e c o m p _ r e f e r e n c i a = c o p i a _ v e t o r _ s e m e n t e ( e n t r a da ) ;

  // i n i c i a l i z a c a o da lista de r e f e r e n c i a

  p t r _ s e m e n t e s = e n t r a d a ;

  ptr_decomp - > poly_impares - > p o l i n o m i o = &( ptr_sementes - > P1 ) ;

  3448

  // i n c r e m e n t a o p o n t e i r o

  3446 3447

  l i s t a _ d e c o m p = i n s e r e _ l i s t a _ d e c o m p ( lista_decomp , p t r _ d e c o m p ) ;

  3445

  // insere o e l e m e n t o criado na lista

  3443 3444

  ptr_decomp - > r e s t o _ i m p a r = c o p i a _ l i s t a _ e x p r ( ptr_sement es - > R1 ) ;

  3442

  ptr_decomp - > r e s t o _ p a r = c o p i a _ l i s t a _ e x p r ( ptr_sementes - > R2 ) ;

  3441

  3440

  3449 3450

  ptr_decomp - > p o l y _ i m p a r e s = n o v o _ v e t o r _ p o l i n o m i o s () ;

  3439

  ptr_decomp - > poly_pares - > p o l i n o m i o = &( ptr_sementes - > P2 ) ;

  3438

  ptr_decomp - > p o l y _ p a r e s = n o v o _ v e t o r _ p o l i n o m i o s () ;

  3437

  p t r _ d e c o m p = n o v o _ v e t o r _ d e c o m p () ;

  3436

  {

  3435

  while ( p t r _ s e m e n t e s != NULL )

  3434

  p t r _ s e m e n t e s = ptr_sementes - > c o n j u n t o _ p r o x ;

  }

  3470 3471

  3462

  int t o t a l _ d e c o m p = 0;

  3468 3469

  v e t o r _ d e c o m p * l i s t a _ d e c o m p = NULL ; // e l e m e n t o m a n i p u l a d o dentro do loop

  3467

  v e t o r _ d e c o m p * d e c o m p _ r e f e r e n c i a ; // lista de r e f r e n c i a para o loop atual

  3466

  v e t o r _ d e c o m p * d e c o m p _ a t u a l ; // lista que sera gerada dentro do loop atual

  3464 3465

  v e t o r _ s e m e n t e s * s e c u n d a r i o _ p t r ; // p o n t e i r o para os loops i n t e r n o s

  3463

  {

  v e t o r _ d e c o m p * e n c o n t r a _ d e c o m p ( v e t o r _ s e m e n t e s * entrada , int grau , l i s t a _ e x p r * e x p r _ s i m p l i f i c a d a , t a b e l a _ l i t e r a i s * l i s t a _ l i t e r a i s )

  3451 3452

  3461

  // funcao que i m p l e m e n t a a d e c o m p o s i c a o em si - versao r e c u r s i v a

  3458 3459 3460

  }

  3457

  return l i s t a _ d e c o m p ;

  3455 3456

  l i s t a _ d e c o m p = lista_decomp - > a n t _ d e c o m p ;

  3454

  while ( lista_decomp - > a n t _ d e c o m p != NULL )

  3453

  // r e b o b i n a r a l i s t a _ d e c o m p

  // funcao que pega os dados de um vetor s e me n t e e os t r a n s f e r e para um vetor decomp

  3510

  int d e c o m p _ s i z e ( v e t o r _ d e c o m p * e n t r a d a )

  3567 3568

  count += p o l y _ s i z e ( entrada - > p o l y _ p a r e s ) ;

  3566

  // soma os p o l i n o m i o s pares

  3564 3565

  count = sizeof ( v e t o r _ d e c o m p ) ;

  3563

  // inicia com o e s q u e l e t o da e s t r u t u r a

  3561 3562

  int count = 0;

  3560

  {

  3559

  3557 3558

  3569

  }

  3556

  return n o v a _ d e c o m p ;

  3554 3555

  nova_decomp - > p r o x _ d e c o m p = NULL ;

  3553

  nova_decomp - > a n t _ d e c o m p = NULL ;

  3552

  nova_decomp - > r e s t o _ p a r = NULL ; // c o p i a _ l i s t a _ e x p r ( entrada - > r e s t o _ p a r ) ;

  3551

  nova_decomp - > r e s t o _ i m p a r = NULL ; // c o p i a _ l i s t a _ e x p r ( entrada - > r e s t o _ i m p a r ) ; estes p a r a m e t r o s serao i n s e r i d o s dentro da funcao r e c u r s i v a

  3550

  // copia os outros p a r a m e t r o s

  // soma os p o l i n o m i o s i m p a r es

  count += p o l y _ s i z e ( entrada - > p o l y _ i m p a r e s ) ;

  }

  3581 3582

  count += sizeof ( v e t o r _ p o l i n o m i o s ) ;

  3588

  // soma o p r op r i o t a m a n ho

  3587

  }

  3586

  count += p o l y _ s i z e ( entrada - > p r o x i m o _ p o l i n o m i o ) ;

  3585

  {

  3584

  if ( entrada - > p r o x i m o _ p o l i n o m i o != NULL )

  3583

  // soma o t a m an h o em m em o r i a de todos os p o l i n o m i o s a f r e n te

  int count = 0;

  3570 3571

  3580

  {

  3579

  int p o l y _ s i z e ( v e t o r _ p o l i n o m i o s * e n t r a d a )

  3577 3578

  }

  3576

  return count ;

  3574 3575

  count += e x p r _ s i z e ( entrada - > r e s t o _ i m p a r ) ;

  3573

  count += e x p r _ s i z e ( entrada - > r e s t o _ p a r ) ;

  3572

  // soma os restos

  3548 3549

  3547

  v e t o r _ d e c o m p * c o p i a _ s e m e n t e ( v e t o r _ s e m e n t e s * e n t r a d a )

  3519

  v e t o r _ d e c o m p * c o p i a _ d e c o m p ( v e t o r _ d e c o m p * e n t r a d a )

  3526 3527

  }

  3525

  return p t r _ d e c o m p ;

  3523 3524

  ptr_decomp - > p r o x _ d e c o m p = NULL ;

  3522

  ptr_decomp - > a n t _ d e c o m p = NULL ;

  3521

  ptr_decomp - > r e s t o _ i m p a r = c o p i a _ l i s t a _ e x p r ( entrada - > R1 ) ;

  3520

  ptr_decomp - > r e s t o _ p a r = c o p i a _ l i s t a _ e x p r ( entrada - > R2 ) ;

  ptr_decomp - > poly_impares - > p o l i n o m i o = & entrada - > P1 ;

  {

  3518

  ptr_decomp - > p o l y _ i m p a r e s = n o v o _ v e t o r _ p o l i n o m i o s () ;

  3517

  ptr_decomp - > poly_pares - > p o l i n o m i o = & entrada - > P2 ;

  3516

  ptr_decomp - > p o l y _ p a r e s = n o v o _ v e t o r _ p o l i n o m i o s () ;

  3515

  p t r _ d e c o m p = n o v o _ v e t o r _ d e c o m p () ;

  3513 3514

  v e t o r _ d e c o m p * p t r _ d e c o m p = NULL ;

  3512

  {

  3511

  3528

  3529

  p o l y _ p t r = poly_ptr - > p r o x i m o _ p o l i n o m i o ;

  p o l y _ p t r = poly_ptr - > p r o x i m o _ p o l i n o m i o ;

  3546

  i n s e r e _ p o l i n o m i o (& nova_decomp - > poly_impares , poly_ptr - > p o l i n o m i o ) ;

  3545

  {

  3544

  while ( p o l y _ p t r != NULL )

  3543

  p o l y _ p t r = entrada - > p o l y _ i m p a r e s ;

  3542

  // copio os p o l i n o m i o s do p r i m a r i o em nova_decomp , depois a parte impar

  3540 3541

  }

  3539

  3538

  v e t o r _ d e c o m p * n o v a _ d e c o m p ;

  i n s e r e _ p o l i n o m i o (&( nova_decomp - > p o l y _ p a r e s ) , poly_ptr - > p o l i n o m i o ) ;

  3537

  {

  3536

  while ( p o l y _ p t r != NULL )

  3535

  p o l y _ p t r = entrada - > p o l y _ p a r e s ;

  3534

  // copio os p o l i n o m i o s do p r i m a r i o em nova_decomp , p r i m e i r o a parte par

  3533

  n o v a _ d e c o m p = n o v o _ v e t o r _ d e c o m p () ;

  3531 3532

  v e t o r _ p o l i n o m i o s * p o l y _ p t r ;

  3530

  3589

  3590

  // vou tentar c o m b i n a r o p r i m a r i o com TODOS os e l e m e n t o s do s e c u n d a r i o

  3649

  R _ d u m m y = NULL ;

  3648

  {

  3647

  if (! f l a g _ f i r s t )

  3646

  // pula este bloco na p r i m e i r a p a s s a d a

  3645

  {

  3644

  while ( p t r _ s e m e n t e s != NULL )

  3643

  3642

  3650

  f l a g _ f i r s t = 1;

  3641

  // i n i c i a l i z o a flag para pular a p r i m e i r a decomposicao , que e de uma s e m e n t e c o n s i g o mesma

  3639 3640

  p t r _ s e m e n t e s = s e c u n d a r i o ;

  3638

  // aponto para o inicio do vetor s e m e n t e s

  3636 3637

  int f l a g _ c o n t i n u e = 0;

  3635

  int f l a g _ f i r s t = 0;

  3634

  int flag = 0;

  Q = NULL ;

  R1 = NULL ;

  int c o n t a d o r = 0;

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3666

  // limpar o R _ d u m m y e o & Q

  3665

  {

  3664

  if ( p a r t i a l _ f r a c t i o n _ e x p a n s i o n ( primario - > resto_par , primario - > poly_pares - > polinomio - >P , ptr_sementes - > poly_pares - > polinomio - >P , &Q ,& R2 , & R _ d u m m y ) )

  3663

  // testar P2 p r i n c i p a l com P2 atual

  3661 3662

  Q = NULL ;

  3660

  R _ d u m m y = NULL ;

  3659

  3658

  3651

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R_ d u m m y ) ;

  3657

  // limpar o R _ d u m m y e o & Q

  3656

  {

  3655

  if ( p a r t i a l _ f r a c t i o n _ e x p a n s i o n ( primario - > resto_impar , primario - > poly_impares - > polinomio - >P , ptr_sementes - > poly_impares - > polinomio - >P , &Q ,& R1 , & R _ d u m m y ) )

  3654

  // testar P1 p r i n c i p a l com P1 atual

  3653

  f l a g _ c o n t i n u e = 0;

  3652

  R2 = NULL ;

  3633

  3632

  return count ;

  3601

  count += ( strlen ( entrada - > c o d i g o s _ n u m e r a d o r ) + 1) * sizeof ( char ) ;

  3609

  {

  3608

  if ( entrada - > c o d i g o s _ n u m e r a d o r != NULL )

  3606 3607

  count += sizeof ( l i s t a _ e x p r ) ;

  3605

  // soma os p r o p r i o s campos

  3603 3604

  }

  3602

  count += e x p r _ s i z e ( entrada - > p r o x i m o ) ;

  {

  }

  3600

  if ( entrada - > p r o x i m o != NULL )

  3599

  // soma a m e m or i a dos p r o x i m o s m o n o m i o s

  3597 3598

  int count = 0;

  3596

  {

  3595

  int e x p r _ s i z e ( l i s t a _ e x p r * e n t r a d a )

  3593 3594

  }

  3591 3592

  3610

  3611 3612

  v e t o r _ d e c o m p * p t r _ d e c o m p = NULL ;

  {

  3631

  v e t o r _ d e c o m p * p t r _ s e m e n t e s = NULL ;

  3630

  v e t o r _ d e c o m p * d e c o m p _ a t u a l = NULL ; v e t o r _ p o l i n o m i o s * p o l y _ p t r = NULL ;

  3628

  l i s t a _ e x p r * R _ d u m m y = NULL ;

  3627

  l i s t a _ e x p r * R2 = NULL ;

  3626

  l i s t a _ e x p r * R1 = NULL ;

  3625

  l i s t a _ e x p r * Q = NULL ;

  3624

  3623

  if ( entrada - > c o d i g o s _ d e n o m i n a d o r != NULL )

  

void e n c o n t r a _ d e c o m p _ r e c u r s i v a ( v e t o r _ d e c o m p * primario , v e t o r _ d e c o m p * secundario , v e t o r _ d e c o m p ** retorno , int grau ,

l i s t a _ e x p r * e x p r _ s i m p l i f i c a d a , t a b e l a _ l i t e r a i s * l i s ta _ l i t e r a i s , int * t o t a l _ d e c o m p )

  3622

  

// Funcao que testa se um par de p o l i n o m i o s pode ser c o m b i n a d o com outro para formar uma decomposicao , r e t o r n a n d o a

d e c o m p o s i c a o p a r c i a l

  3619 3620 3621

  }

  3618

  return count ;

  3616 3617

  }

  3615

  count += e x p r _ s i z e ( entrada - > c o d i g o s _ d e n o m i n a d o r ) ;

  3614

  {

  3613

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R _d u m m y ) ;

  3667

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3668 3669

  // copio o primario , pois pode ser s e m e n t e para outras d e c o m p o s i c o e s

  3670

  d e c o m p _ a t u a l = c o p i a _ d e c o m p ( p r i m a r i o ) ;

  3671 3672

  // insiro os p o l i n o m i o s que fazem parte da d e c o m p o s i c a o

  3673

  // s i g n i f i c a que secundario - > P1 e o p r o x i m o p o l i n o m i o Par , e seconudario - > P2 o pr o x i m o p o l i n o m i o impar , e e i n v e r t i d o mesmo

  3674

  i n s e r e _ p o l i n o m i o (& decomp_atual - > poly_pares , ptr_seme ntes - > poly_impares - > p o l i n o m i o ) ;

  3675

  i n s e r e _ p o l i n o m i o (& decomp_atual - > poly_impares , ptr_se mentes - > poly_pares - > p o l i n o m i o ) ;

  3676 3677

  // a t u a l i z a Resto par e Resto impar

  3678

  decomp_atual - > r e s t o _ i m p a r = R1 ;

  3679

  decomp_atual - > r e s t o _ p a r = R2 ;

  3680 3681

  // quando o numero de p o l i n o m i o s pares e i m p a r e s for igual ao grau da eq u a c a o de e n t r a d a pode ser que ja tenha t e r m i n a d o

  3682

  c o n t a d o r = 0;

  3683

  p o l y _ p t r = decomp_atual - > p o l y _ p a r e s ;

  3684

  while ( p o l y _ p t r != NULL )

  3685

  {

  3686

  • c o n t a d o r ;

  3687

  p o l y _ p t r = poly_ptr - > p r o x i m o _ p o l i n o m i o ;

  3688

  }

  3689

  if ( c o n t a d o r == grau )

  3690

  {

  3691

  // testo se a d e c o m p o s i c a O e n c o n t r a d a e valida

  3692

  // tirar a prova real

  3693

  if ( p r o v a _ r e a l ( decomp_atual , e x p r _ s i m p l i f i c a d a ) )

  3694

  {

  3695

  // o r d en a r os p o l i n o m i o s antes de i n s e r i r a d e c o m p o s i c a o

  3696

  decomp_atual - > p o l y _ p a r e s = o r d e n a _ p o l i n o m i o s ( decomp_a tual - > p o l y _ p a r e s ) ;

  3697

  decomp_atual - > p o l y _ i m p a r e s = o r d e n a _ p o l i n o m i o s ( decomp _atual - > p o l y _ i m p a r e s ) ;

  3698 3699

  // n o r m a l i z a r os restos - > para

  3700

  if ( fabs ( decomp_atual - > resto_par - > p a r a m e t r o ) >= fabs ( dec omp_atual - > resto_impar - > p a r a m e t r o ) )

  3701

  {

  3702

  decomp_atual - > resto_par - > p a r a m e t r o = decomp_atual - > re sto_par - > p a r a m e t r o / decomp_atual - > resto_impar - > p a r a m e t r o ;

  3703

  decomp_atual - > resto_impar - > p a r a m e t r o = 1.0;

  3704

  }

  3706

  else

  3707

  {

  3708

  decomp_atual - > resto_impar - > p a r a m e t r o = decomp_atual - > resto_impar - > p a r a m e t r o / decomp_atual

  • > resto_par - > p a r a m e t r o ;

  3709

  decomp_atual - > resto_par - > p a r a m e t r o = 1.0;

  3710

  }

  3711 3712

  // a l t er a r sinais para melhor i m p r e s s a o de resultados , p r i o r i z a n d o resto par ser p o s i t i v o :

  3713

  if ( decomp_atual - > resto_par - > p a r a m e t r o < 0.0)

  3714

  {

  3715

  decomp_atual - > resto_par - > p a r a m e t r o *= -1.0;

  3716

  decomp_atual - > resto_impar - > p a r a m e t r o *= -1.0;

  3717

  }

  3718 3719

  

// p r o cu r o por uma d e c o m p o s i c a o e q u i v a l e n t e no vetor de r e t o r n o

  3720

  p t r _ d e c o m p = * r e t o r n o ;

  3721 3722

  // i n i c i a l i z o uma flag de busca

  3723

  flag = 0;

  3724

  while ( p t r _ d e c o m p != NULL )

  3725

  {

  3726

  // se eu e n c o n t r o uma d e c o m p o s i c a o equivalente , i n t e r r o m p o a busca e nao insiro decomp atual no vetro de r e t o r n o

  3727

  if ( c o m p a r a _ d e c o m p ( decomp_atual , p t r _ d e c o m p ) )

  3728

  {

  3729

  flag = 1;

  3730

  break ;

  3731

  }

  3732

  p t r _ d e c o m p = ptr_decomp - > a n t _ d e c o m p ;

  3733

  }

  3734

  // se nao e n c o n t r o u n e n h u m a d e c o m p o s i c a o equivalente , i n s e r i r decomp autal no vetor

  3735

  if (! flag )

  3736

  {

  3737

  • r e t o r n o = i n s e r e _ l i s t a _ d e c o m p (* retorno , d e c o m p _ a t u a l ) ;

  3738

  // ja i m p r i m o a d e c o m p o s i c a o e n c o n t r a d a

  3739

  

i m p r i m e _ d e c o m p o s i c a o ( decomp_atual , l i s t a _ l i t e r a i s ) ;

  3740

  // i m c r e m e n t o as decomp v a l i d a s

  3741

  (* t o t a l _ d e c o m p ) ++;

  3742

  // s i n a l i z o o flag de que nao e n e c e s s a r i o fazer o teste i n v e r t i d o

  3743

  f l a g _ c o n t i n u e = 1;

  3744

  }

  3745

  else

  3746

  d e s t r o i _ d e c o m p ( d e c o m p _ a t u a l ) ;

  3747 3748

  // limpa o p o n t e i r o para o p r o x i m o teste

  3749

  d e c o m p _ a t u a l = NULL ;

  3750 3751

  }

  3752

  else

  3753

  {

  3754

  d e s t r o i _ d e c o m p ( d e c o m p _ a t u a l ) ;

  3755

  d e c o m p _ a t u a l = NULL ;

  3756

  }

  3757

  }

  3758

  else

  3759

  {

  3760

  

// caso contrario , deve - se p r o c e d e r com a d e c o m p o s i c a o r e c u r s i v a m e n t e

  3761

  e n c o n t r a _ d e c o m p _ r e c u r s i v a ( decomp_atual , ptr_sementes , retorno , grau , e x p r _ s i m p l i f i c a d a , l i s t a _ l i t e r a i s , t o t a l _ d e c o m p ) ;

  3762

  // como as d e c o m p o s i c o e s v a l i d a s serao a d i c i o n a d a s no if acima , quando o p r o g r a m a chegar aqui , s i g n i f i c a

  3763

  // que nao p r e c i s o mais de d e c o m p _ a t u a l ;

  3764

  d e s t r o i _ d e c o m p ( d e c o m p _ a t u a l ) ;

  3765

  d e c o m p _ a t u a l = NULL ;

  3766

  }

  3767 3768

  // se chegou aqui

  3769 3770

  // se ja tiver e n c o n t r a d o uma d e c o m p o s i c a o valida neste passo , , s i g n i g i c a que o s e g u n d o teste , com os p o l i n o m i o s invertidos , nao e n e c e s s a r i o

  3771

  if ( f l a g _ c o n t i n u e )

  3772

  {

  3773

  // a t u a l i z a o p o n t e i r o

  3774

  p t r _ s e m e n t e s = ptr_sementes - > p r o x _ d e c o m p ;

  3775

  c o n t i n u e ;

  3776

  }

  3777

  }

  3778

  else

  3779

  {

  3780

  // limpar tudo d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R _d u m m y ) ;

  3782

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3783

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R1 ) ;

  3784

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R2 ) ;

  3785

  }

  3786

  }

  3787

  else

  3788

  {

  3789

  // limpar tudo

  3790

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R_ d u m m y ) ;

  3791

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3792

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R1 ) ;

  3793 3794

  }

  3795

  }

  3796

  else

  3797

  {

  3798

  // reseta o flag de p r i m e i r a pa s s a d a

  3799

  f l a g _ f i r s t = 0;

  3800

  }

  3801 3802

  // limpar as v a r i a v e i s de r e t o r no

  3803

  Q = NULL ;

  3804

  R1 = NULL ;

  3805

  R2 = NULL ;

  3806

  R _ d u m m y = NULL ;

  3807

  // testar tambem P1 p r i n c i p a l com P2 atual

  3808

  if ( p a r t i a l _ f r a c t i o n _ e x p a n s i o n ( primario - > resto_impar , primario - > poly_impares - > polinomio - >P , ptr_sementes - > poly_pares - > polinomio - >P , &Q ,& R1 , & R _ d u m m y ) )

  3809

  {

  3810

  // if dummie para por um b r e a k p o i n t e x a t a m e n t e onde esta dando pau no w i n d o w s

  3811

  // limpar o R _ d u m m y e o & Q

  3812

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R _ d u m m y ) ;

  3813

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3814

  R _ d u m m y = NULL ;

  3815

  Q = NULL ;

  3816 3817

  // testar P2 p r i n c i p a l com P1 atual

  3818

  if ( p a r t i a l _ f r a c t i o n _ e x p a n s i o n ( primario - > resto_par , primario - > poly_pares - > polinomio - >P , ptr_sementes - > poly_impares - > polinomio - >P , &Q ,& R2 , & R _ d u m m y ) )

  • c o n t a d o r ;

  decomp_atual - > resto_impar - > p a r a m e t r o = decomp_atual - > resto_impar - > p a r a m e t r o / decomp_atual - > resto_par - > p a r a m e t r o ;

  3875

  decomp_atual - > resto_par - > p a r a m e t r o *= -1.0;

  3874

  {

  3873

  if ( decomp_atual - > resto_par - > p a r a m e t r o < 0.0)

  3872

  // a l te r a r sinais para melhor i m p r e s s a o de resultados , p r i o r i z a n d o resto par ser p o s i t i v o :

  3870 3871

  }

  3869

  decomp_atual - > resto_par - > p a r a m e t r o = 1.0;

  3868

  3867

  3876

  {

  3866

  else

  3865

  }

  3863 3864

  decomp_atual - > resto_impar - > p a r a m e t r o = 1.0;

  3862

  decomp_atual - > resto_par - > p a r a m e t r o = decomp_atual - > re sto_par - > p a r a m e t r o / decomp_atual - > resto_impar - > p a r a m e t r o ;

  3861

  {

  3860

  if ( fabs ( decomp_atual - > resto_par - > p a r a m e t r o ) >= fabs ( dec omp_atual - > resto_impar - > p a r a m e t r o ) )

  decomp_atual - > resto_impar - > p a r a m e t r o *= -1.0;

  }

  // n o r m a l i z a r os restos - > para

  if ( c o m p a r a _ d e c o m p ( decomp_atual , p t r _ d e c o m p ) )

  3893 3894

  }

  3892

  p t r _ d e c o m p = ptr_decomp - > a n t _ d e c o m p ;

  3891

  }

  3890

  break ;

  3889

  flag = 1;

  3888

  {

  3887

  3886

  3877 3878

  // se eu e n c o n t r o uma d e c o m p o s i c a o equivalente , i n t e r r o m p o a busca e nao insiro decomp atual no vetro de r e t o r n o

  3885

  {

  3884

  while ( p t r _ d e c o m p != NULL )

  3883

  flag = 0;

  3882

  // i n i c i a l i z o uma flag de busca

  3880 3881

  p t r _ d e c o m p = * r e t o r n o ;

  3879

  // p r oc u r o por uma d e c o m p o s i c a o e q u i v a l e n t e no vetor de r e t o r n o

  3859

  3856 3857

  3819

  d e c o m p _ a t u a l = c o p i a _ d e c o m p ( p r i m a r i o ) ;

  3836

  decomp_atual - > r e s t o _ i m p a r = R1 ;

  3835

  // a t u a l i z a Resto par e Resto impar

  3833 3834

  

i n s e r e _ p o l i n o m i o (& decomp_atual - > poly_impares , ptr_se mentes - > poly_impares - > p o l i n o m i o ) ;

  3832

  i n s e r e _ p o l i n o m i o (& decomp_atual - > poly_pares , ptr_seme ntes - > poly_pares - > p o l i n o m i o ) ;

  3831

  // s i g n i f i c a que secundario - > P1 e o p r o x i m o p o l i n o m i o Par , e seconudario - > P2 o p r o x i m o p o l i n o m i o impar , e e i n v e r t i d o mesmo

  3830

  // insiro os p o l i n o m i o s que fazem parte da d e c o m p o s i c a o

  3828 3829

  3827

  3837 3838

  // copio o primario , pois pode ser s e m e n t e para outras d e c o m p o s i c o e s

  3825 3826

  Q = NULL ;

  3824

  R _ d u m m y = NULL ;

  3823

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3822

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R_ d u m m y ) ;

  3821

  // limpar o R _ d u m m y e o & Q

  3820

  {

  decomp_atual - > r e s t o _ p a r = R2 ;

  // quando o numero de p o l i n o m i o s pares e i m p a r e s for igual ao grau da e q u a c a o de e n t r a d a pode ser que ja tenha t e r m i n a d o

  decomp_atual - > p o l y _ i m p a r e s = o r d e n a _ p o l i n o m i o s ( decomp _atual - > p o l y _ i m p a r e s ) ;

  {

  3855

  decomp_atual - > p o l y _ p a r e s = o r d e n a _ p o l i n o m i o s ( decomp_a tual - > p o l y _ p a r e s ) ;

  3854

  // ordeno o p o l i n o m i o antes de i n s e r i r

  3853

  {

  3852

  if ( p r o v a _ r e a l ( decomp_atual , e x p r _ s i m p l i f i c a d a ) )

  3851

  // tirar a prova real

  3849 3850

  // testo se a d e c o m p o s i c a p e n c o n t r a d a e valida

  3848

  3847

  3839

  if ( c o n t a d o r == grau )

  3846

  }

  3845

  p o l y _ p t r = poly_ptr - > p r o x i m o _ p o l i n o m i o ;

  3844

  3843

  {

  3842

  while ( p o l y _ p t r != NULL )

  3841

  p o l y _ p t r = decomp_atual - > p o l y _ p a r e s ;

  3840

  c o n t a d o r = 0;

  // se nao e n c o n t r o u n e n h u m a d e c o m p o s i c a o equivalente , i n s e r i r decomp autal no vetor

  3895

  if (! flag )

  3896

  {

  3897

  • r e t o r n o = i n s e r e _ l i s t a _ d e c o m p (* retorno , d e c o m p _ a t u a l ) ;

  3898

  // ja i m p r i m o a d e c o m p o s i c a o e n c o n t r a d a

  3899

  i m p r i m e _ d e c o m p o s i c a o ( decomp_atual , l i s t a _ l i t e r a i s ) ;

  3900

  // i m c r e m e n t o as decomp v a l i d a s

  3901

  (* t o t a l _ d e c o m p ) ++;

  3902 3903

  }

  3904

  else

  3905

  d e s t r o i _ d e c o m p ( d e c o m p _ a t u a l ) ;

  3906 3907

  // limpa o p o n t e i r o para o p r o x i m o teste

  3908

  d e c o m p _ a t u a l = NULL ;

  3909

  }

  3910

  else

  3911

  {

  3912

  d e s t r o i _ d e c o m p ( d e c o m p _ a t u a l ) ;

  3913

  d e c o m p _ a t u a l = NULL ;

  3914

  }

  3915

  }

  3916

  else

  3917

  {

  3918

  // caso contrario , deve - se p r o c e d e r com a d e c o m p o s i c a o r e c u r s i v a m e n t e

  3919

  e n c o n t r a _ d e c o m p _ r e c u r s i v a ( decomp_atual , ptr_sementes , retorno , grau , e x p r _ s i m p l i f i c a d a , l i s ta _ l i t e r a i s , t o t a l _ d e c o m p ) ;

  3920 3921

  // como as d e c o m p o s i c o e s v a l i d a s serao a d i c i o n a d a s no if acima , quando o p r o g r a m a chegar aqui , s i g n i f i c a

  3922

  // que nao p r e c i s o mais de d e c o m p _ a t u a l ;

  3923

  d e s t r o i _ d e c o m p ( d e c o m p _ a t u a l ) ;

  3924

  d e c o m p _ a t u a l = NULL ;

  3925

  }

  3926 3927

  }

  3928

  else

  3929

  {

  3930

  // limpar tudo

  3931

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R_ d u m m y ) ;

  3932

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R2 ) ;

  3933

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R1 ) ; d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3935 3936

  }

  3937

  }

  3938

  else

  3939

  {

  3940

  // limpar tudo

  3941

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R _ d u m m y ) ;

  3942

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  3943

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R1 ) ;

  3944

  }

  3945

  // return d e c o m p _ a t u a l ;

  3946

  Q = NULL ;

  3947

  R1 = NULL ;

  3948

  R2 = NULL ;

  3949

  R _ d u m m y = NULL ;

  3950 3951

  // a t u a l i z a o p o n t e i r o

  3952

  p t r _ s e m e n t e s = ptr_sementes - > p r o x _ d e c o m p ;

  3953

  }

  3954

  }

  3955 3956

  // funcao que e l im i n a as decomp r e d u n d a n t e s nao p r e v i s i v e i s

  3957

  void e l i m i n a _ d e c o m p _ r e d u n d a n t e s ( v e t o r _ d e c o m p * e n t r a d a )

  3958

  {

  3959

  v e t o r _ d e c o m p * p t r _ e n t r a d a = e n t r a d a ;

  3960

  v e t o r _ d e c o m p * ptr_aux , * p t r _ r e m o v e ;

  3961

  int flag ;

  3962 3963

  // p r i m e i r o r e o r d e n o os p o l i n o m i o s pares e i m p a r e s de cada decomp

  3964

  while ( p t r _ e n t r a d a != NULL )

  3965

  {

  3966

  // r e o r d e n o os p o l i n o m i o s pares e i m p a r e s

  3967

  ptr_entrada - > p o l y _ p a r e s = o r d e n a _ p o l i n o m i o s ( ptr_entra da - > p o l y _ p a r e s ) ;

  3968

  ptr_entrada - > p o l y _ i m p a r e s = o r d e n a _ p o l i n o m i o s ( ptr_ent rada - > p o l y _ i m p a r e s ) ;

  3969 3970

  p t r _ e n t r a d a = ptr_entrada - > p r o x _ d e c o m p ;

  3971

  }

  3972 3973

  p t r _ e n t r a d a = e n t r a d a ;

  3974

  // p e r c o r r o toda a lista de d ecomposicoes , c o m p a r a n d o com todas abaixo

  3975

  while ( p t r _ e n t r a d a != NULL )

  3976

  {

  3977

  p t r _ a u x = ptr_entrada - > p r o x _ d e c o m p ;

  3978

  while ( p t r _ a u x != NULL )

  3979

  {

  3980

  flag = c o m p a r a _ d e c o m p ( ptr_entrada , p t r _ a u x ) ;

  3981 3982

  // finalmente , se a falg for 1 , e porque os p o l i n o m i o s sao redundantes , entao posso e x c l u i r o p o l i n o m i o a u x i l i a r

  3983

  if ( flag )

  3984

  {

  3985

  // marco o p o n t e i r o a ser r e m o v i d o

  3986

  p t r _ r e m o v e = p t r _ a u x ;

  3987 3988

  // ja i n c r e m e n t o o p o n t e i r o a u x i l i a r para a p r o x i m a i t e r a c a o

  3989

  p t r _ a u x = ptr_aux - > p r o x _ d e c o m p ;

  3990 3991

  // removo p _ r e m o v e

  3992

  ptr_remove - > ant_decomp - > p r o x _ d e c o m p = ptr_remove - > p r o x _ d e c o m p ;

  3993

  if ( ptr_remove - > p r o x _ d e c o m p != NULL )

  3994

  ptr_remove - > prox_decomp - > a n t _ d e c o m p = ptr_remove - > a n t _ d e c o m p ;

  3995

  d e s t r o i _ d e c o m p ( p t r _ r e m o v e ) ;

  3996

  }

  3997

  else

  3998

  p t r _ a u x = ptr_aux - > p r o x _ d e c o m p ;

  3999

  }

  4000 4001

  p t r _ e n t r a d a = ptr_entrada - > p r o x _ d e c o m p ;

  4002 4003

  }

  4004

  }

  4005

  // ordena uma lista de p o l i n o m i o s e m ordem c r e s c e n t e

  4006

  v e t o r _ p o l i n o m i o s * o r d e n a _ p o l i n o m i o s ( v e t o r _ p o l i n o m i o s * e nt r a d a )

  4007

  {

  4008

  v e t o r _ p o l i n o m i o s * ptr , * aux ;

  4009 4010

  ptr = e n t r a d a ;

  4011

  while ( ptr - > p r o x i m o _ p o l i n o m i o != NULL )

  4012

  {

  4013

  aux = ptr - > p r o x i m o _ p o l i n o m i o ; if ( aux - > polinomio - > id < ptr - > polinomio - > id )

  4015

  {

  4016

  // r e a li z o a troca entre ptr e aux

  4017

  ptr - > p r o x i m o _ p o l i n o m i o = aux - > p r o x i m o _ p o l i n o m i o ;

  4018

  aux - > p o l i n o m i o _ a n t e r i o r = ptr - > p o l i n o m i o _ a n t e r i o r ;

  4019 4020

  if ( ptr - > p o l i n o m i o _ a n t e r i o r != NULL )

  4021

  ptr - > p o l i n o m i o _ a n t e r i o r - > p r o x i m o _ p o l i n o m i o = aux ;

  4022

  if ( aux - > p r o x i m o _ p o l i n o m i o != NULL )

  4023

  aux - > p r o x i m o _ p o l i n o m i o - > p o l i n o m i o _ a n t e r i o r = ptr ;

  4024

  aux - > p r o x i m o _ p o l i n o m i o = ptr ;

  4025

  ptr - > p o l i n o m i o _ a n t e r i o r = aux ;

  4026 4027

  // como e um bubblesort , devo voltar ao inicio da lista

  4028

  while ( ptr - > p o l i n o m i o _ a n t e r i o r != NULL )

  4029

  ptr = ptr - > p o l i n o m i o _ a n t e r i o r ;

  4030

  }

  4031

  else

  4032

  ptr = ptr - > p r o x i m o _ p o l i n o m i o ;

  4033 4034

  }

  4035

  // ao final do processo , basta r e b o b i n a r o p o l i n o m i o

  4036

  while ( ptr - > p o l i n o m i o _ a n t e r i o r != NULL )

  4037

  ptr = ptr - > p o l i n o m i o _ a n t e r i o r ;

  4038 4039

  return ptr ;

  4040

  }

  4041 4042

  // funcao que i m pr i m e uma d e c o m p o s i c a o

  4043

  void i m p r i m e _ d e c o m p o s i c a o ( v e t o r _ d e c o m p * decomposicao , t a b e l a _ l i t e r a i s * l i s t a _ l i t e r a i s )

  4044

  {

  4045

  v e t o r _ p o l i n o m i o s * p e r c o r r e _ p o l i n o m i o s ;

  4046 4047

  printf ( " \ n %+3.2 f * " , decomposicao - > resto_par - > p a r a m e t r o ) ;

  4048

  p e r c o r r e _ p o l i n o m i o s = decomposicao - > p o l y _ i m p a r e s ;

  4049

  while ( p e r c o r r e _ p o l i n o m i o s != NULL )

  4050

  {

  4051

  printf ( " ( " ) ;

  4052

  i m p r i m e _ l i s t a _ e x p r _ e x p a n d i d a ( p e r c o r r e _ p o l i n o m i o s - > p olinomio - >P , l i s t a _ l i t e r a i s ) ;

  4053

  printf ( " ) " ) ;

  4054

  4105

  while ( p t r _ p a r 1 != NULL )

  4112 4113

  flag = 1;

  4111

  // i n i c i a l i z o minha flag

  4109 4110

  p t r _ p a r 2 = decomp2 - > p o l y _ p a r e s ;

  4108

  p t r _ p a r 1 = decomp1 - > p o l y _ p a r e s ;

  4107

  p t r _ i m p a r 2 = decomp2 - > p o l y _ i m p a r e s ;

  4106

  p t r _ i m p a r 1 = decomp1 - > p o l y _ i m p a r e s ;

  

// c o mp a r o e l e m e n t o a e l e m e n t o de cada c o n j u n t o de p o l i n o m i o s para ver se sao iguais

  {

  4104

  {

  4103

  if (! flag )

  4102

  // se a flag for 0 , testar com os v e t o r e s t r o c a d o s

  4100 4101

  }

  4099

  p t r _ i m p a r 2 = ptr_impar2 - > p r o x i m o _ p o l i n o m i o ;

  4098

  p t r _ i m p a r 1 = ptr_impar1 - > p r o x i m o _ p o l i n o m i o ;

  4097

  4114

  4115

  4096

  p t r _ i m p a r 1 = ptr_impar1 - > p r o x i m o _ p o l i n o m i o ;

  4134

  v e t o r _ p o l i n o m i o s * r e c o n t a _ p o l i n o m i o s ( v e t o r _ s e m e n t e s * l i s t a _ s e m e n t e s , v e t o r _ p o l i n o m i o s * l i s t a _ p o l i n o m i o s )

  4132 4133

  }

  4130 4131

  return flag ;

  4128 4129

  }

  4127

  }

  4126

  p t r _ i m p a r 2 = ptr_impar2 - > p r o x i m o _ p o l i n o m i o ;

  4125

  4124

  // se algum for diferente , limpa a flag

  p t r _ p a r 2 = ptr_par2 - > p r o x i m o _ p o l i n o m i o ;

  4123

  p t r _ p a r 1 = ptr_par1 - > p r o x i m o _ p o l i n o m i o ;

  4122

  // a t u a l i z a os dois p o n t e i r o s

  4120 4121

  flag = 0;

  4119

  if ( ptr_impar1 - > polinomio - > id != ptr_par2 - > polinomio - > id )

  4118

  flag = 0;

  4117

  if ( ptr_par1 - > polinomio - > id != ptr_impar2 - > polinomio - > id )

  4116

  p t r _ p a r 2 = ptr_par2 - > p r o x i m o _ p o l i n o m i o ;

  // a t u a l i z a os dois p o n t e i r o s p t r _ p a r 1 = ptr_par1 - > p r o x i m o _ p o l i n o m i o ;

  p e r c o r r e _ p o l i n o m i o s = p e r c o r r e _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  printf ( " ) " ) ;

  4071 4072

  {

  4070

  int c o m p a r a _ d e c o m p ( v e t o r _ d e c o m p * decomp1 , v e t o r _ d e c o m p * de c o m p 2 )

  4069

  // funcao que r e to r n a 1 caso as d e c o m p o s i c o e s sejam e q u i v a l e n t e s e 0 caso nao sejam

  4067 4068

  }

  4066

  }

  4065

  p e r c o r r e _ p o l i n o m i o s = p e r c o r r e _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  4064

  4063

  4073

  

i m p r i m e _ l i s t a _ e x p r _ e x p a n d i d a ( p e r c o r r e _ p o l i n o m i o s - > p olinomio - >P , l i s t a _ l i t e r a i s ) ;

  4062

  printf ( " ( " ) ;

  4061

  {

  4060

  while ( p e r c o r r e _ p o l i n o m i o s != NULL )

  4059

  p e r c o r r e _ p o l i n o m i o s = decomposicao - > p o l y _ p a r e s ;

  4058

  printf ( " %+3.2 f * " , decomposicao - > resto_impar - > p a r a m e t r o ) ;

  4056 4057

  }

  4055

  v e t o r _ p o l i n o m i o s * ptr_impar1 , * p t r _ i m p a r 2 ;

  v e t o r _ p o l i n o m i o s * ptr_par1 , * p t r _ p a r 2 ;

  4093 4094

  4085 4086

  flag = 0;

  4092

  if ( ptr_impar1 - > polinomio - > id != ptr_impar2 - > polinomio - > id )

  4091

  flag = 0;

  4090

  if ( ptr_par1 - > polinomio - > id != ptr_par2 - > polinomio - > id )

  4089

  // se algum for diferente , limpa a flag

  4088

  {

  4087

  while ( p t r _ p a r 1 != NULL )

  flag = 1;

  4074 4075

  4084

  // i n i c i a l i z o minha flag

  4082 4083

  p t r _ p a r 2 = decomp2 - > p o l y _ p a r e s ;

  4081

  p t r _ p a r 1 = decomp1 - > p o l y _ p a r e s ;

  4080

  p t r _ i m p a r 2 = decomp2 - > p o l y _ i m p a r e s ;

  4079

  p t r _ i m p a r 1 = decomp1 - > p o l y _ i m p a r e s ;

  4078

  // c o m p a r o e l e m e n t o a e l e m e n t o de cada c o n j u n t o de p o l i n o m i o s para ver se sao iguais

  4076 4077

  int flag ;

  {

  4135

  4184

  int i d _ i m p a r = 0;

  4192

  v e t o r _ p o l i n o m i o s * p _ l i s t a _ p o l i n o m i o s ;

  4191

  {

  4190

  

v e t o r _ p o l i n o m i o s * r e m o v e _ p o l i n o m i o s _ n a o _ p e r t e n c e n t e s ( v e t o r _ d e c o m p * lista_decomp , v e t o r _ p o l i n o m i o s * l i s t a _ p o l i n o m i o s )

  4188 4189

  }

  4187

  return p _ l i s t a _ p o l i n o m i o s ;

  4185 4186

  }

  p _ l i s t a _ p o l i n o m i o s = p _ l i s t a _ p o l i n o m i o s - > p o l i n o m i o _ a n t e r i o r ;

  int id_par = 0;

  4183

  {

  4182

  while ( p _ l i s t a _ p o l i n o m i o s - > p o l i n o m i o _ a n t e r i o r != NULL )

  4181

  // r e b o b o i n a a lista

  4179 4180

  }

  4178

  break ;

  4177

  else

  4176

  p _ l i s t a _ p o l i n o m i o s = p _ l i s t a _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ; }

  4193

  4194

  {

  }

  4211 4212

  p _ p a r e s = p _ l i s ta _ d e c o m p - > p o l y _ p a r e s ;

  4210

  p _ i m p a r e s = p _ l i s t a _ d e c o m p - > p o l y _ i m p a r e s ;

  4209

  // p r oc u r a cada p o l i n o m i o do lado par e do lado impar na lista de polinomios , e os que forem sendo encontrados , mudar o flag de 1 para 0

  4208

  {

  4207

  while ( p _ l i s t a _ d e c o m p != NULL )

  4206

  // p e r c o r r e r todo o vetor de d e c o m p o s i c o e s

  4204 4205

  4203

  int ok_par = 0;

  return NULL ;

  4202

  {

  4201

  if ( l i s t a _ d e c o m p == NULL )

  4200

  // If a null list is given , return NULL

  4198 4199

  v e t o r _ p o l i n o m i o s * p_pares , * p _ i m p a r e s ;

  4197

  v e t o r _ d e c o m p * p _ l i s t a _ d e c o m p = l i s t a _ d e c o m p ;

  4196

  int o k _ i m p a r = 0;

  4195

  4174

  4173

  v e t o r _ p o l i n o m i o s * p _ l i s t a _ p o l i n o m i o s ;

  id_par = p _ l i s t a _ s e m e n t e s - > P1 . id ;

  4152

  // a cada p o l i n o m i o da lista , se o id for igual a P1 ou P2 , seta a flag de a p r o v a d o

  4151

  {

  4150

  while ( p _ l i s t a _ p o l i n o m i o s != NULL )

  4149

  p _ l i s t a _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  4148

  // i n i c i a l i z a a lista de p o l i n o m i o s

  4146 4147

  i d _ i m p a r = p _ l i s t a _ s e m e n t e s - > P2 . id ;

  4145

  4144

  4153

  

// p r oc u r a cada p o l i n o m i o da s e m e n t e na lista de p o l i n o m i o s e seta a flag de a p r o v a d o se o e n c o n t r a r ;

  4143

  {

  4142

  while ( p _ l i s t a _ s e m e n t e s != NULL )

  4141

  // p e r c o r r e r todo o vetor s e m e n t e s

  4139 4140

  v e t o r _ s e m e n t e s * p _ l i s t a _ s e m e n t e s = l i s t a _ s e m e n t e s ;

  4138

  int id_par = 0;

  4137

  int i d _ i m p a r = 0;

  4136

  if ( p _ l i s t a _ p o l i n o m i o s - > polinomio - > id == i d _ i m p a r || p _ l i s t a _ p o l i n o m i o s - > polinomio - > id == id_par )

  {

  else if ( p _ l i s t a _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o != NULL )

  4165

  4172

  }

  4171

  p _ l i s t a _ p o l i n o m i o s = r e m o v e _ p o l i n o m i o ( p _ l i s t a _ p o l i n o m i o s ) ;

  4170

  {

  4169

  if (! p _ l i s t a _ p o l i n o m i o s - > polinomio - > f l a g _ a p p r o v e d )

  4168

  {

  4167

  while (1)

  4166

  p _ l i s t a _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  // apos setar flag todos os p o l i n o m i o s que podem fazer parte de alguma decomposicao , r e m o v e r a q u e l e s que nao tem a flag setada

  4154

  4163 4164

  }

  4162

  p _ l i s t a _ s e m e n t e s = p _ l i s t a _ s e m e n t e s - > c o n j u n t o _ p r o x ;

  4161

  // i n c r e m e n t a p o n t e i r o

  4159 4160

  }

  4158

  p _ l i s t a _ p o l i n o m i o s = p _ l i s t a _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  4156 4157

  }

  4155

  p _ l i s t a _ p o l i n o m i o s - > polinomio - > f l a g _ a p p r o v e d = 1;

  // como o numero de p o l i n o i m o s do lado par e igual ao do lado impar em uma d e c o m p o s i c a o encontrada , pode - se p e r c o r r e r apenas um e n q u a n t o testa - se ambos

  4213

  while ( p _ i m p a r e s != NULL )

  4214

  {

  4215

  id_par = p_pares - > polinomio - > id ;

  4216

  i d _ i m p a r = p_impares - > polinomio - > id ;

  4217 4218

  // p r o cu r o ambos na lista de p o l i n o m i o s

  4219

  // i n i c i a l i z a a lista de p o l i n o m i o s

  4220

  p _ l i s t a _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  4221

  ok_par = 0;

  4222

  o k _ i m p a r = 0;

  4223

  while ( p _ l i s t a _ p o l i n o m i o s != NULL )

  4224

  {

  4225

  // a cada p o l i n o m i o da lista , se o id for igual ao p o l i n o m i o par , re - seta a flag de a p r o v a d o

  4226

  if ( p _ l i s t a _ p o l i n o m i o s - > polinomio - > id == id_par )

  4227

  {

  4228

  p _ l i s t a _ p o l i n o m i o s - > polinomio - > f l a g _ a p p r o v e d = 0;

  4229

  ok_par = 1;

  4230

  }

  4231 4232

  // a cada p o l i n o m i o da lista , se o id for igual ao p o l i n o m i o impar re - seta a flag de a p r o v a d o

  4233

  if ( p _ l i s t a _ p o l i n o m i o s - > polinomio - > id == i d _ i m p a r )

  4234

  {

  4235

  p _ l i s t a _ p o l i n o m i o s - > polinomio - > f l a g _ a p p r o v e d = 0;

  4236

  o k _ i m p a r = 1;

  4237

  }

  4238 4239

  // se ja e n c o n t r o u os dois , nao p r e c i s a mais c o n t i n u a r

  4240

  if ( o k _ i m p a r && ok_par )

  4241

  {

  4242

  break ;

  4243

  }

  4244 4245

  p _ l i s t a _ p o l i n o m i o s = p _ l i s t a _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  4246

  }

  4247 4248

  // i n c r e m e n t a os p o n t e i r o s

  4249

  p _ i m p a r e s = p_impares - > p r o x i m o _ p o l i n o m i o ;

  4250

  p _ p a r e s = p_pares - > p r o x i m o _ p o l i n o m i o ;

  4251

  }

  4252 4253

  // i n c r e m e n t a p o n t e i r o

  4255

  p _ l i s t a _ d e c o m p = p _ l i s t a _ d e c o m p - > p r o x _ d e c o m p ;

  4256

  }

  4257 4258

  // apos re - setar flag todos os p o l i n o m i o s que f i z e r a m parte de alguma decomposicao , r e m o v e r a q u e l e s que tem a flag setada

  4259

  p _ l i s t a _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  4260

  while (1)

  4261

  {

  4262

  if ( p _ l i s t a _ p o l i n o m i o s - > polinomio - > f l a g _ a p p r o v e d )

  4263

  {

  4264

  p _ l i s t a _ p o l i n o m i o s = r e m o v e _ p o l i n o m i o ( p _ l i s t a _ p o l i n o m i o s ) ;

  4265

  }

  4266

  else if ( p _ l i s t a _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o != NULL )

  4267

  {

  4268

  p _ l i s t a _ p o l i n o m i o s = p _ l i s t a _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  4269

  }

  4270

  else

  4271

  break ;

  4272

  }

  4273 4274

  // r e b o b o i n a a lista

  4275

  if ( p _ l i s t a _ p o l i n o m i o s != NULL )

  4276

  {

  4277

  while ( p _ l i s t a _ p o l i n o m i o s - > p o l i n o m i o _ a n t e r i o r != NULL )

  4278

  {

  4279

  p _ l i s t a _ p o l i n o m i o s = p _ l i s t a _ p o l i n o m i o s - > p o l i n o m i o _ a n t e r i o r ;

  4280

  }

  4281

  }

  4282 4283 4284

  return p _ l i s t a _ p o l i n o m i o s ;

  4285

  }

  4286 4287

  // funcao que i m p l e m e n t a a d e c o m p o s i c a o em si - versao r e c u r s i v a

  4288

  v e t o r _ d e c o m p * e n c o n t r a _ d e c o m p _ m u l d e r ( v e t o r _ p o l i n o m i o s * entrada , int grau , l i s t a _ e x p r * e x p r _ s i m p l i f i c a d a , t a b e l a _ l i t e r a i s

  • l i s t a _ l i t e r a i s )

  4289

  {

  4290

  v e t o r _ p o l i n o m i o s * primario_ptr , * s e c u n d a r i o _ p t r ; // p o n t e i r o para os loops i n t e r n o s

  4291

  4292

  v e t o r _ d e c o m p * d e c o m p _ a t u a l ; // lista que sera gerada dentro do loop atual

  4293

  v e t o r _ d e c o m p * l i s t a _ d e c o m p = NULL ; // e l e m e n t o m a n i p u l a d o dentro do loop

  4294

  v e t o r _ d e c o m p _ s i m p l e * p o l y _ p a r e s = NULL , * p o l y _ i m p a r e s = NULL ;

  4295

  l i s t a _ e x p r * Q = NULL , * num_a = NULL , * num_b = NULL ;

  4296 4297

  int t o t a l _ d e c o m p = 0;

  4298 4299

  // i n i c i a l i z a c a o da lista de r e f e r e n c i a

  4300

  p r i m a r i o _ p t r = e n t r a d a ;

  4301

  d e c o m p _ a t u a l = NULL ;

  4302 4303

  // loop de c o n s t r u c a o das d e c o m p o s i c o e s

  4304

  while ( p r i m a r i o _ p t r != NULL )

  4305

  {

  4306

  // i n i c i a l i z a o p r o x i m o p o n t e i r o de busca

  4307

  s e c u n d a r i o _ p t r = entrada - > p r o x i m o _ p o l i n o m i o ;

  4308

  while ( s e c u n d a r i o _ p t r != NULL )

  4309

  {

  4310

  // i n i c i a l i z a v a r i a v e i s

  4311

  Q = NULL ;

  4312

  num_a = NULL ;

  4313

  num_b = NULL ;

  4314

  // tenta r e a l i z a r uma e x p a n s a o em fracao p a r c i a l e n t r e p r i m a r i o e s e c u n d a r i o

  4315

  if ( p a r t i a l _ f r a c t i o n _ e x p a n s i o n ( e x p r _ s i m p l i f i c a d a , prima rio_ptr - > polinomio - >P , s e c u n da r i o _ p t r - > polinomio - >P , & Q , & num_a , & num_b ) )

  4316

  {

  4317

  // d i s p ar o a d i v i s a o r e c u r s i v a por 2 BP , s aqui

  4318

  e n c o n t r a _ d e c o m p _ p a r c i a l ( NULL , primario_ptr - > polinomi o , num_a , entrada , grau , & p o l y _ p a r e s ) ;

  4319 4320 4321

  // se a rotina de e n c o n t r a r d e c o m p o s i c o e s p a r c i a i s nao e n c o n t r a r nada , o p r o c e d i m e n t o falhou

  4322

  if ( p o l y _ p a r e s != NULL )

  4323

  {

  4324

  // r e b o b i n a os p o l i n o m i o s pares

  4325

  while ( poly_pares - > a n t _ d e c o m p != NULL )

  4326

  {

  4327

  p o l y _ p a r e s = poly_pares - > a n t _ d e c o m p ;

  4328

  }

  4329 4330

  e n c o n t r a _ d e c o m p _ p a r c i a l ( NULL , s e c u n d a r i o _ p t r - > polino mio , num_b , entrada , grau , & p o l y _ i m p a r e s ) ;

  4331

  // de posse dos lados pares e dos lados impares , e n c o n t r a r quais c o m b i n a c o e s geram uma d e c o m p o s i c a o valida

  4333

  if ( p o l y _ i m p a r e s != NULL )

  4334

  {

  4335

  // r e b o b i n a os p o l i n o m i o s i mp a r e s

  4336

  while ( poly_impares - > a n t _ d e c o m p != NULL )

  4337

  {

  4338

  p o l y _ i m p a r e s = poly_impares - > a n t _ d e c o m p ;

  4339

  }

  4340 4341

  c o m b i n a _ d e c o m p _ m u l d e r ( poly_impares , poly_pares , s e c u n da r i o _ p t r - > polinomio , primario_ptr - > polinomio , e x p r _ s i m p l i f i c a d a , & lista_decomp , & total_de comp , l i s t a _ l i t e r a i s ) ;

  4342 4343

  }

  4344

  }

  4345 4346

  d e s t r o i _ v e t o r _ d e c o m p _ s i m p l e s ( p o l y _ p a r e s ) ;

  4347

  d e s t r o i _ v e t o r _ d e c o m p _ s i m p l e s ( p o l y _ i m p a r e s ) ;

  4348 4349

  p o l y _ p a r e s = NULL ;

  4350

  p o l y _ i m p a r e s = NULL ;

  4351

  }

  4352 4353

  // limpa as v a r i a v e i s para a pr o x i m a p a s s a g e m

  4354

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  4355

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( num_a ) ;

  4356

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( num_b ) ;

  4357 4358

  // a t u a l i z o p o n t e i r o

  4359

  s e c u n d a r i o _ p t r = s e c u n d a r i o _ p t r - > p r o x i m o _ p o l i n o m i o ;

  4360

  }

  4361 4362

  // a t u a l i z o p o n t e i r o

  4363

  p r i m a r i o _ p t r = primario_ptr - > p r o x i m o _ p o l i n o m i o ;

  4364

  }

  4365 4366

  // r e b o b i n a r a lista de d e c o m p o s i c o e s

  4367

  if ( l i s t a _ d e c o m p != NULL )

  4368

  while ( lista_decomp - > a n t _ d e c o m p != NULL )

  4369

  l i s t a _ d e c o m p = lista_decomp - > a n t _ d e c o m p ;

  4370 4371

  // i m p r i m i r numero de d e c o m p o s i c o e s

  4372

  printf ( " \ n \ nThe number of valid T r a n s l i n e a r d e c o m p o s i t i o n s found is : % d " , t o t a l _ d e c o m p ) ;

  4373

  printf ( " \ n Number of p a r t i a l f r a c t i o n o p e r a t i o n s p e r f o r m e d is : % d \ n " , g l o b a l _ n u m _ p a r f r a c ) ;

  4374 4375

  // r e t o r n a r

  4376

  return l i s t a _ d e c o m p ;

  4377

  }

  4378 4379

  void c o m b i n a _ d e c o m p _ m u l d e r ( v e t o r _ d e c o m p _ s i m p l e * d e c o m p _ i m p a r e s , v e t o r _ d e c o m p _ s i m p l e * decomp_pares , p o l i n o m i o * base_par , p o l i n o m i o * base_impar , l i s t a _ e x p r * e x p r _ s i m p l i f i c a d a , v e t o r _ d e c o m p ** lista_decomp , int * total_decomp , t a b e l a _ l i t e r a i s * l i s t a _ l i t e r a i s )

  4380

  {

  4381

  v e t o r _ d e c o m p * decomp_atual , * p t r _ d e c o m p ;

  4382

  v e t o r _ d e c o m p _ s i m p l e * p _ d e c o m p _ p a r e s = NULL ;

  4383

  v e t o r _ d e c o m p _ s i m p l e * p _ d e c o m p _ i m p a r e s = NULL ;

  4384

  v e t o r _ p o l i n o m i o s * p o l y _ p t r ;

  4385 4386

  int flag ;

  4387 4388 4389

  // para cada decomp_par , p e r c o r r e r todas as d e c o m p _ i m p a r e s

  4390

  p _ d e c o m p _ p a r e s = d e c o m p _ p a r e s ;

  4391

  while ( p _ d e c o m p _ p a r e s != NULL )

  4392

  {

  4393

  // i n i c i a l i z a c a o de v a r i a v e i s

  4394

  p _ d e c o m p _ i m p a r e s = d e c o m p _ i m p a r e s ;

  4395

  while ( p _ d e c o m p _ i m p a r e s != NULL )

  4396

  {

  4397

  // r e e s c r i t a do p r o c e d i m e n t o

  4398

  // crio uma decomp com os polys pares e com polys i m p p a r e s

  4399

  // copio o primario , pois pode ser s e m e n t e para outras d e c o m p o s i c o e s

  4400

  d e c o m p _ a t u a l = n o v o _ v e t o r _ d e c o m p () ;

  4401 4402

  // copio a base par

  4403

  i n s e r e _ p o l i n o m i o (&( decomp_atual - > p o l y _ p a r e s ) , b a s e _ p a r ) ;

  4404 4405

  // copio o resto dos p o l i n o i o s pares

  4406

  p o l y _ p t r = p _ d e c o m p _ p a r e s - > p o l i n o m i o s ;

  4407

  while ( p o l y _ p t r != NULL )

  4408

  { i n s e r e _ p o l i n o m i o (&( decomp_atual - > p o l y _ p a r e s ) , poly_ptr - > p o l i n o m i o ) ;

  4410

  p o l y _ p t r = poly_ptr - > p r o x i m o _ p o l i n o m i o ;

  4411

  }

  4412 4413

  // copio a base impar

  4414

  i n s e r e _ p o l i n o m i o (&( decomp_atual - > p o l y _ i m p a r e s ) , b a s e _ i m p a r ) ;

  4415 4416

  // copio o resto dos p o l i n o i o s i m p a r e s

  4417

  p o l y _ p t r = p _ d e c o m p _ i m p a r e s - > p o l i n o m i o s ;

  4418

  while ( p o l y _ p t r != NULL )

  4419

  {

  4420

  i n s e r e _ p o l i n o m i o (&( decomp_atual - > p o l y _ i m p a r e s ) , poly_ptr - > p o l i n o m i o ) ;

  4421

  p o l y _ p t r = poly_ptr - > p r o x i m o _ p o l i n o m i o ;

  4422

  }

  4423 4424

  // copia os outros p a r a m e t r o s

  4425

  decomp_atual - > r e s t o _ i m p a r = c o p i a _ l i s t a _ e x p r ( p _ d e c o m p _ p a r e s - > resto ) ;

  4426

  decomp_atual - > r e s t o _ p a r = c o p i a _ l i s t a _ e x p r ( p _ d e c o m p _ i m p a r e s - > resto ) ;

  4427 4428

  decomp_atual - > a n t _ d e c o m p = NULL ;

  4429

  decomp_atual - > p r o x _ d e c o m p = NULL ;

  4430 4431

  // tiro a prova real

  4432

  if ( p r o v a _ r e a l ( decomp_atual , e x p r _ s i m p l i f i c a d a ) )

  4433

  {

  4434

  // ordeno o p o l i n o m i o antes de i n s e r i r

  4435

  decomp_atual - > p o l y _ p a r e s = o r d e n a _ p o l i n o m i o s ( decomp_a tual - > p o l y _ p a r e s ) ;

  4436

  decomp_atual - > p o l y _ i m p a r e s = o r d e n a _ p o l i n o m i o s ( decomp _atual - > p o l y _ i m p a r e s ) ;

  4437 4438

  // testo se esta d e c o m p o s i c a o e n c o n t r a d a ja nao existe

  4439

  // p r o c ur o por uma d e c o m p o s i c a o e q u i v a l e n t e no vetor de re t o r n o

  4440

  p t r _ d e c o m p = * l i s t a _ d e c o m p ;

  4441 4442

  // i n i c i a l i z o uma flag de busca

  4443

  flag = 0;

  4444

  while ( p t r _ d e c o m p != NULL )

  4445

  {

  4446

  // se eu e n c o n t r o uma d e c o m p o s i c a o equivalente , i n t e r r o m p o a busca e nao insiro decomp atual no vetro de r e t o r n o

  4447

  if ( c o m p a r a _ d e c o m p ( decomp_atual , p t r _ d e c o m p ) )

  • > p a r a m e t r o ;
    • l i s t a _ d e c o m p = i n s e r e _ l i s t a _ d e c o m p (* lista_decomp , d e c o m p _ a t u a l ) ;

  else

  4505

  // a t u a l i z o o p o n t e i r o

  4503 4504

  }

  4502

  d e c o m p _ a t u a l = NULL ;

  4501

  d e s t r o i _ d e c o m p ( d e c o m p _ a t u a l ) ;

  4500

  // limppo as v a r i a v e i s

  4499

  {

  4498

  4497

  4506

  }

  4494 4495 4496

  }

  4493

  d e c o m p _ a t u a l = NULL ;

  4492

  // limpa o p o n t e i r o para o p r o x i m o teste

  4491

  d e s t r o i _ d e c o m p ( d e c o m p _ a t u a l ) ;

  4490

  {

  4489

  else

  p _ d e c o m p _ i m p a r e s = p _ d e c o m p _ i m p a r e s - > p r o x _ d e c o m p ;

  }

  }

  l i s t a _ e x p r *Q , *R , * R _ d u m my ;

  4525

  {

  4524

  while ( p t r _ p o l i n o m i o s != NULL )

  4523

  // testa a base com todos os polinomios , excluindo - se a p r o p r ia base

  4521 4522

  v e t o r _ p o l i n o m i o s * p o l y _ p t r ;

  4520

  int c o n t a d o r ;

  4519

  v e t o r _ d e c o m p _ s i m p l e * d e c o m p _ a t u a l ;

  4518

  4517

  4507 4508

  v e t o r _ p o l i n o m i o s * p t r _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  4516

  {

  4515

  void e n c o n t r a _ d e c o m p _ p a r c i a l ( v e t o r _ d e c o m p _ s i m p l e * p o l y _ a c u m u l a d o s , p o l i n o m i o * base , l i s t a _ e x p r * resto , v e t o r _ p o l i n o m i o s * l i s t a _ p o l i n o m i o s , int grau , v e t o r _ d e c o m p _ s i m p l e ** r e t o r n o )

  4513 4514

  }

  4511 4512

  }

  4510

  p _ d e c o m p _ p a r e s = p _ d e c o m p _ p a r e s - > p r o x _ d e c o m p ;

  4509

  // a t u a l i z o o p o n t e i r o

  4488

  4486

  4448

  if (! flag )

  4464 4465

  decomp_atual - > resto_impar - > p a r a m e t r o = 1.0;

  4463

  decomp_atual - > resto_par - > p a r a m e t r o = decomp_atual - > resto_par - > p a r a m e t r o / decomp_atual - > resto_impar

  4462

  {

  4461

  if ( fabs ( decomp_atual - > resto_par - > p a r a m e t r o ) >= fabs ( dec omp_atual - > resto_impar - > p a r a m e t r o ) )

  4460

  // p r i m e i r o n o r m a l i z a r os restos

  4458 4459

  {

  4457

  4456

  4466

  

// se nao e n c o n t r o u n e n h u m a d e c o m p o s i c a o equivalente , i n s e r i r decomp autal no vetor

  4454 4455

  }

  4453

  p t r _ d e c o m p = ptr_decomp - > a n t _ d e c o m p ;

  4452

  }

  4451

  break ;

  4450

  flag = 1;

  4449

  {

  }

  else

  (* t o t a l _ d e c o m p ) ++;

  4476

  4485

  // i m c r e m e n t o as decomp v a l i d a s

  4483 4484

  d e c o m p _ a t u a l = NULL ;

  4482

  4481

  i m p r i m e _ d e c o m p o s i c a o ( decomp_atual , l i s t a _ l i t e r a i s ) ;

  4480

  // ja im p r i m o a d e c o m p o s i c a o e n c o n t r a d a

  4478 4479

  }

  4477

  decomp_atual - > resto_impar - > p a r a m e t r o *= -1.0;

  decomp_atual - > resto_par - > p a r a m e t r o *= -1.0;

  4467

  4475

  {

  4474

  if ( decomp_atual - > resto_par - > p a r a m e t r o < 0.0)

  4473

  // a l t e r ar sinais para melhor i m p r e s s a o de resultados , p r i o r i z a n d o resto par ser p o s i t i v o :

  4471 4472

  }

  4470

  decomp_atual - > resto_par - > p a r a m e t r o = 1.0;

  4469

  decomp_atual - > resto_impar - > p a r a m e t r o = decomp_atual - > resto_impar - > p a r a m e t r o / decomp_atual - > resto_par - > p a r a m e t r o ;

  4468

  {

  // testa p r i m e i r o se o p o l i n o m i o nao e igual a base

  • c o n t a d o r ;
    • r e t o r n o = i n s e r e _ d e c o m p _ s i m p l e s (* retorno , d e c o m p _ a t u a l ) ;

  }

  {

  4585

  v e t o r _ d e c o m p _ s i m p l e * c o p i a _ d e c o m p _ s i m p l e s ( v e t o r _ d e c o m p _ s i m p l e * e n t r a d a )

  4583 4584

  }

  4582

  }

  4581

  p t r _ p o l i n o m i o s = p t r _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  4580

  // i n c r e m e n t a o p o n t e i r o

  4578 4579

  }

  4577

  4576

  v e t o r _ d e c o m p _ s i m p l e * n o v a _ d e c o m p ;

  }

  4575

  d e c o m p _ a t u a l = NULL ;

  4574

  d e s t r o i _ d e c o m p _ s i m p l e s ( d e c o m p _ a t u a l ) ;

  4573

  // que nao p r e c i s o mais de d e c o m p _ a t u a l ;

  4572

  // como as d e c o m p o s i c o e s v a l i d a s serao a d i c i o n a d a s no if acima , quando o p r o g r a m a chegar aqui , s i g n i f i c a

  4571

  

e n c o n t r a _ d e c o m p _ p a r c i a l ( decomp_atual , base , R , p t r _ p o l i n o m i o s , grau , r e t o r n o ) ;

  4570

  // caso contrario , deve - se p r o c e d e r com a d e c o m p o s i c a o r e c u r s i v a m e n t e

  4569

  4586

  4587

  4568

  i n s e r e _ p o l i n o m i o (&( nova_decomp - > p o l i n o m i o s ) , poly_ptr - > p o l i n o m i o ) ;

  }

  4603

  nova_decomp - > p o l i n o m i o s = NULL ;

  4602

  {

  4601

  else

  4600

  }

  4599

  }

  4598

  p o l y _ p t r = poly_ptr - > p r o x i m o _ p o l i n o m i o ;

  4597

  4596

  v e t o r _ p o l i n o m i o s * p o l y _ p t r ;

  {

  4595

  while ( p o l y _ p t r != NULL )

  4594

  p o l y _ p t r = entrada - > p o l i n o m i o s ;

  4593

  // copio os p o l i n o m i o s do p r i m a r i o em n o v a _ d e c o m p

  4592

  {

  4591

  if ( e n t r a d a != NULL )

  4590

  n o v a _ d e c o m p = n o v o _ v e t o r _ d e c o m p _ s i m p l e s () ;

  4588 4589

  {

  else

  4526

  4534

  4543

  // insiro os p o l i n o m i o s que fazem parte da d e c o m p o s i c a o

  4541 4542

  d e c o m p _ a t u a l = c o p i a _ d e c o m p _ s i m p l e s ( p o l y _ a c u m u l a d o s ) ;

  4540

  // copio o primario , pois pode ser s e m e n t e para outras d e c o m p o s i c o e s

  4538 4539

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  4537

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R_ d u m m y ) ;

  4536

  // limpar o R _ d u m m y e o & Q

  4535

  {

  

if ( p a r t i a l _ f r a c t i o n _ e x p a n s i o n ( resto , base - >P , p t r _ po l i n o m i o s - > polinomio - >P , &Q ,& R , & R _ d u m m y ) )

  4544 4545

  4533

  // testar a base p r i n c i p a l com o p o l i n o m i o atual

  4532

  R _ d u m m y = NULL ;

  4531

  R = NULL ;

  4530

  Q = NULL ;

  4529

  // limpar as v a r i a v e i s

  4528

  {

  4527

  if ( base - > id != p t r _ p o l i n o m i o s - > polinomio - > id )

  i n s e r e _ p o l i n o m i o (& decomp_atual - > polinomios , p t r _ po l i n o m i o s - > p o l i n o m i o ) ;

  // a t u a l i z a Resto par e Resto impar

  4567

  4556 4557

  } // caso contrario , p r o s s e g u i r com as d e c o m p o s i c o e s p a r c i a i s de forma r e c u r s i v a

  4564 4565

  4563

  // t e r m i n o u de fazer uma d e c o m p o s i c a o parcial , inseri - la no vetor de d e c o m p o s i c o e s totais

  4562

  {

  4561

  if ( c o n t a d o r == grau )

  4560

  // vejo se ja t e r m i n o u

  4559

  c o n t a d o r ++;

  4558

  // somo um ao c o n t a d o r

  }

  4546

  p o l y _ p t r = decomp_atual - > p o l i n o m i o s ;

  decomp_atual - > resto = R ;

  4547 4548

  // quando o numero de p o l i n o m i o s a c u m u l a d o s for igual ao grau menos 1 da e q u a c a o de e n t r a d a pode ser que ja tenha t e r m i n a d o

  4549

  c o n t a d o r = 0;

  4550

  4551

  4555

  while ( p o l y _ p t r != NULL )

  4552

  {

  4553

  4554

  p o l y _ p t r = poly_ptr - > p r o x i m o _ p o l i n o m i o ;

  4604

  4605

  4657

  {

  4665

  v e t o r _ d e c o m p _ s i m p l e * n o v o _ v e t o r _ d e c o m p _ s i m p l e s ( void )

  4663 4664

  }

  4662

  free ( e n t r a d a ) ;

  4660 4661

  d e s t r o i _ v e t o r _ p o l i n o m i o s ( entrada - > p o l i n o m i o s ) ;

  4659

  if ( entrada - > p o l i n o m i o s != NULL )

  4658

  // d e s t r o i os v e t or e s de p o l i n o m i o s

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( entrada - > resto ) ;

  v e t o r _ d e c o m p _ s i m p l e * novo ;

  4656

  if ( entrada - > resto != NULL )

  4655

  {

  4654

  void d e s t r o i _ d e c o m p _ s i m p l e s ( v e t o r _ d e c o m p _ s i m p l e * e n t r a d a )

  4652 4653

  }

  4651

  }

  4650

  return p t r _ l i s t a _ d e s t i n o ;

  4648 4649

  4666

  4667

  4647

  4678

  }

  4684

  d e s t r o i _ v e t o r _ d e c o m p _ s i m p l e s ( entrada - > p r o x _ d e c o m p ) ;

  4683

  {

  4682

  if ( entrada - > p r o x _ d e c o m p != NULL )

  4681

  return ;

  4680

  if ( e n t r a d a == NULL )

  4679

  {

  void d e s t r o i _ v e t o r _ d e c o m p _ s i m p l e s ( v e t o r _ d e c o m p _ s i m p l e * e n t r a d a )

  novo = ( v e t o r _ d e c o m p _ s i m p l e *) malloc ( sizeof ( v e t o r _ d e c o m p _ s i m p l e ) ) ;

  4676 4677

  }

  4675

  return novo ;

  4673 4674

  novo - > a n t _ d e c o m p = NULL ;

  4672

  novo - > p r o x _ d e c o m p = NULL ;

  4670 4671

  novo - > resto = NULL ;

  4669

  novo - > p o l i n o m i o s = NULL ;

  4668

  p t r _ l i s t a _ d e s t i n o = p t r _ l i s t a _ d e s t i n o - > p r o x _ d e c o m p ;

  // a v an c a r o p o n t e i r o ate o final while ( p t r _ l i s t a _ d e s t i n o - > p r o x _ d e c o m p != NULL )

  // copia os outros p a r a m e t r o s

  4616

  while ( p t r _ l i s t a _ o r i g e m - > p r o x _ d e c o m p != NULL )

  4623

  // aponto para o final da lista a ser i n s e r i d a

  4622

  {

  4621

  if ( l i s t a _ d e s t i n o == NULL )

  4620

  p t r _ l i s t a _ o r i g e m = l i s t a _ o r i g e m ;

  4618 4619

  v e t o r _ d e c o m p _ s i m p l e * p t r _ l i s t a _ o r i g e m , * p t r _ l i s t a _ d e s t i n o ;

  4617

  {

  v e t o r _ d e c o m p _ s i m p l e * i n s e r e _ d e c o m p _ s i m p l e s ( v e t o r _ d e c o m p _ s i m p l e * list a_destino , v e t o r _ d e c o m p _ s i m p l e * l i s t a _ o r i g e m )

  p t r _ l i s t a _ o r i g e m = p t r _ l i s t a _ o r i g e m - > p r o x _ d e c o m p ;

  4615

  // insere uma lista de d e c o m p o s i c o e s dentro de outra , r e t o r n a n d o um p o n t e i r o para o final dela

  4613 4614

  }

  4611 4612

  return n o v a _ d e c o m p ;

  4609 4610

  nova_decomp - > p r o x _ d e c o m p = NULL ;

  4608

  nova_decomp - > a n t _ d e c o m p = NULL ;

  4607

  nova_decomp - > resto = NULL ;

  4606

  4624

  4625 4626

  4644 4645

  4635

  p t r _ l i s t a _ o r i g e m - > a n t _ d e c o m p = p t r _ l i s t a _ d e s t i n o ;

  4643

  p t r _ l i s t a _ d e s t i n o - > p r o x _ d e c o m p = p t r _ l i s t a _ o r i g e m ;

  4642

  // ligar as 2

  4640 4641

  p t r _ l i s t a _ o r i g e m = p t r _ l i s t a _ o r i g e m - > a n t _ d e c o m p ;

  4639

  while ( p t r _ l i s t a _ o r i g e m - > a n t _ d e c o m p != NULL )

  4638

  // r e b o b i n a r o p o n t e i r o da lista de origem

  4636 4637

  p t r _ l i s t a _ d e s t i n o = p t r _ l i s t a _ d e s t i n o - > p r o x _ d e c o m p ;

  while ( p t r _ l i s t a _ d e s t i n o - > p r o x _ d e c o m p != NULL )

  // r e to r n o o fim da lista d e s t i n o como o fim da lista de origem

  4634

  // a v an c a r o p o n t e i r o para fim da lista d e s t i n o

  4633

  p t r _ l i s t a _ d e s t i n o = l i s t a _ d e s t i n o ;

  4632

  {

  4631

  else

  4630

  }

  4628 4629

  return p t r _ l i s t a _ o r i g e m ;

  4627

  4685

  • m e d i d o r = time ( NULL ) ;

  4738

  4744

  // tenta r e a l i z a r uma e x p a n s a o em fracao p a r c i a l e n t r e p r i m a r i o e s e c u n d a r i o

  4743

  num_b = NULL ;

  4742

  num_a = NULL ;

  4741

  Q = NULL ;

  4740

  // i n i c i a l i z a v a r i a v e i s

  4739

  {

  while ( s e c u n d a r i o _ p t r != NULL )

  4745

  4737

  s e c u n d a r i o _ p t r = entrada - > p r o x i m o _ p o l i n o m i o ;

  4736

  // i n i c i a l i z a o p r o x i m o p o n t e i r o de busca

  4735

  {

  4734

  while ( p r i m a r i o _ p t r != NULL )

  4733

  // loop de c o n s t r u c a o das d e c o m p o s i c o e s

  4731 4732

  d e c o m p _ a t u a l = NULL ;

  if ( p a r t i a l _ f r a c t i o n _ e x p a n s i o n ( e x p r _ s i m p l i f i c a d a , prima rio_ptr - > polinomio - >P , s e c u n da r i o _ p t r - > polinomio - >P , & Q , & num_a , & num_b ) )

  {

  p r i m a r i o _ p t r = e n t r a d a ;

  4754 4755 4756

  4763

  s e c u n d a r i o _ p t r = s e c u n d a r i o _ p t r - > p r o x i m o _ p o l i n o m i o ;

  4762

  // a t u a l i z o p o n t e i r o

  4760 4761

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( num_b ) ;

  4759

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( num_a ) ;

  4758

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  4757

  // limpa as v a r i a v e i s para a pr o x i m a p a s s a g e m

  p o l y _ i m p a r e s = NULL ;

  4746

  4753

  p o l y _ p a r e s = NULL ;

  4752

  d e s t r o i _ v e t o r _ d e c o m p _ s i m p l e s ( p o l y _ p a r e s ) ;

  4751

  d e s t r o i _ v e t o r _ d e c o m p _ s i m p l e s ( p o l y _ i m p a r e s ) ;

  4750

  }

  4748 4749

  e n c o n t r a _ d e c o m p _ p a r c i a l _ p r i m a r i a ( NULL , primario_ptr - > polinomio , num_a , s e c u n d a r i o _ p t r - > polinomio , num_b , entrada , grau , & lista_decomp , & total_decomp , l i s t a _ l i t e ra i s , e x p r _ s i m p l i f i c a d a ) ;

  4747

  // d i s p ar o a d i v i s a o r e c u r s i v a por 2 BP , s aqui

  4730

  4729

  4686

  void p a r a _ c r o n o m e t r o ( time_t * m e d i d o r )

  m i n u t o s = ( s e g u n d o s /60) ;

  4703 4704

  s e g u n d o s = ( u n s i g n e d long int ) d i f f t i m e ( tms , * m e d i d o r ) ;

  4701 4702

  tms = time ( NULL ) ;

  4699 4700

  u n s i g n e d long int horas , minutos , segundos , dias ;

  4698

  time_t tms ;

  4697

  {

  4696

  4694 4695

  s e g u n d o s =( u n s i g n e d long int ) ( s e g u n d o s %60) ;

  }

  4693

  4692

  {

  4691

  void i n i c i a _ c r o n o m e t r o ( time_t * m e d i d o r )

  4690

  // f u n c oe s para m e d i c a o de tempo

  4688 4689

  }

  4687

  d e s t r o i _ d e c o m p _ s i m p l e s ( e n t r a d a ) ;

  4705

  4706 4707

  // i n i c i a l i z a c a o da lista de r e f e r e n c i a

  4718

  4727 4728

  int t o t a l _ d e c o m p = 0;

  4724 4725

  l i s t a _ e x p r * Q = NULL , * num_a = NULL , * num_b = NULL ;

  4723

  v e t o r _ d e c o m p _ s i m p l e * p o l y _ p a r e s = NULL , * p o l y _ i m p a r e s = NULL ;

  4722

  v e t o r _ d e c o m p * l i s t a _ d e c o m p = NULL ; // e l e m e n t o m a n i p u l a d o dentro do loop

  4721

  v e t o r _ d e c o m p * d e c o m p _ a t u a l ; // lista que sera gerada dentro do loop atual

  4719 4720

  v e t o r _ p o l i n o m i o s * primario_ptr , * s e c u n d a r i o _ p t r ; // p o n t e i r o para os loops i n t e r n o s

  {

  horas = m i n u to s /60;

  4717

  v e t o r _ d e c o m p * e n c o n t r a _ d e c o m p _ m u l d e r _ s a f e ( v e t o r _ p o l i n o m i o s * entrada , int grau , l i s t a _ e x p r * e x p r _ s i m p l i f i c a d a , t a b e l a _ l i t e r a i s * l i s t a _ l i t e r a i s )

  4715 4716

  }

  4714

  printf ( " \ ntime e l a p s e d : % lu days , % lu hours , % lu minutes , % lu s e c o n d s " , dias , horas , minutos , s e g u n d o s ) ;

  4712 4713

  horas = ( u n s i g n e d long int ) ( horas %24) ;

  4711

  dias = horas /24;

  4709 4710

  m i n u t o s = ( u n s i g n e d long int ) ( m i n u t o s %60) ;

  4708

  }

  }

  4811 4812

  4820

  c o n t a d o r = 0;

  4819

  // quando o numero de p o l i n o m i o s a c u m u l a d o s for igual ao grau menos 1 da e q u a c a o de e n t r a d a pode ser que ja tenha t e r m i n a d o

  4817 4818

  decomp_atual - > resto = R ;

  4816

  // a t u a l i z a r e s t o _ p r i m a r i o par e r e s t o _ p r i m a r i o impar

  4814 4815

  i n s e r e _ p o l i n o m i o (& decomp_atual - > polinomios , p t r _ po l i n o m i o s - > p o l i n o m i o ) ;

  4813

  // insiro os p o l i n o m i o s que fazem parte da d e c o m p o s i c a o

  d e c o m p _ a t u a l = c o p i a _ d e c o m p _ s i m p l e s ( p o l y _ a c u m u l a d o s ) ;

  4821

  4810

  // copio o primario , pois pode ser s e m e n t e para outras d e c o m p o s i c o e s

  4808 4809

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  4807

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R_ d u m m y ) ;

  4806

  // limpar o R _ d u m m y e o & Q

  4805

  {

  4804

  ) )

  // testar a b a s e _ p r i m a r i o p r i n c i p a l com o p o l i n o m i o atual if ( p a r t i a l _ f r a c t i o n _ e x p a n s i o n ( r e s t o _ p r i m a r i o , base_pri mar io - >P , p t r _ p o l i n o m i o s - > polinomio - >P , &Q ,& R , & R _ d u m m y

  p o l y _ p t r = decomp_atual - > p o l i n o m i o s ;

  while ( p o l y _ p t r != NULL )

  R _ d u m m y = NULL ;

  4831

  4837 4838

  d e s t r o i _ d e c o m p _ s i m p l e s ( d e c o m p _ a t u a l ) ;

  4836

  // d e s t r oi o vetor simple p r i m a r i o

  4835

  // aqui todas as d e c o m p o s i c o e s terao sido i n s e r i d a s dentro sda rotina da s e c u n d a r i a

  4834

  e n c o n t r a _ d e c o m p _ p a r c i a l _ s e c u n d a r i a ( NULL , b a s e _ s e c u n d a r i o , r e s t o _ s e c u n d a r i o , l i s t a _ p o l i n o m i o s , grau , retorno , decomp_atual , bas e_primario , total_decomp , l i s t a _ l i t e r a i s , e q _ e n t r a d a ) ;

  4833

  // t e r m i n o u de fazer uma d e c o m p o s i c a o parcial , c o m e c a r a p r o c u r a r d e c o m p o s i c o e s p a r c i a i s no outro vetor

  4832

  {

  if ( c o n t a d o r == grau )

  4822

  4830

  // vejo se ja t e r m i n o u

  4829

  c o n t a d o r ++;

  4828

  // somo um ao c o n t a d o r

  4826 4827

  }

  4825

  p o l y _ p t r = poly_ptr - > p r o x i m o _ p o l i n o m i o ;

  4824

  4823

  {

  4802

  4801

  4764 4765

  // i m p r i m i r numero de d e c o m p o s i c o e s

  

void e n c o n t r a _ d e c o m p _ p a r c i a l _ p r i m a r i a ( v e t o r _ d e c o m p _ s i m p l e * p o l y _ a c u m u l a d o s , p o l i n o m i o * base_pr imario , l i s t a _ e x p r *

r e s t o _ p r i m a r i o , p o l i n o m i o * b a s e _ s e c u n d a r i o , l i s t a _ e x p r * r e s t o _ s e c u n d a r i o , v e t o r _ p o l i n o m i o s * l i s t a _ p o l i n o m i o s , int grau , v e t o r _ d e c o m p ** retorno , int * total_decomp , t a b e l a _ l i t e r a i s * l i s t a _ l it e r a i s , l i s t a _ e x p r * e q _ e n t r a d a )

  4782

  }

  4781

  return l i s t a _ d e c o m p ;

  4780

  // r e t o r n a r

  4778 4779

  printf ( " \ n Number of p a r t i a l f r a c t i o n o p e r a t i o n s p e r f o r m e d is : % d \ n " , g l o b a l _ n u m _ p a r f r a c ) ;

  4777

  printf ( " \ n \ nThe number of valid T r a n s l i n e a r d e c o m p o s i t i o n s found is : % d " , t o t a l _ d e c o m p ) ;

  4776

  4774 4775

  {

  l i s t a _ d e c o m p = lista_decomp - > a n t _ d e c o m p ;

  4773

  while ( lista_decomp - > a n t _ d e c o m p != NULL )

  4772

  if ( l i s t a _ d e c o m p != NULL )

  4771

  // r e b o b i n a r a lista de d e c o m p o s i c o e s

  4768 4769 4770

  }

  4767

  p r i m a r i o _ p t r = primario_ptr - > p r o x i m o _ p o l i n o m i o ;

  4766

  // a t u a l i z o p o n t e i r o

  4783

  4784

  R = NULL ;

  4794

  4800

  Q = NULL ;

  4799

  // limpar as v a r i a v e i s

  4798

  {

  4797

  if ( bas e_primario - > id != p tr _ p o l i n o m i o s - > polinomio - > id )

  4796

  // testa p r i m e i r o se o p o l i n o m i o nao e igual a b a s e _ p r i m a r i o

  4795

  {

  while ( p t r _ p o l i n o m i o s != NULL )

  v e t o r _ p o l i n o m i o s * p t r _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  4793

  // testa a b a s e _ p r i m a r i o com todos os polinomios , excluindo - se a p r o p r i a b a s e _ p r i m a r i o

  4791 4792

  // sai i m e d i a t a m e n t e se tiver e n c o n t r a d o uma decomp

  4789 4790

  v e t o r _ p o l i n o m i o s * p o l y _ p t r ;

  4788

  int c o n t a d o r ;

  4787

  v e t o r _ d e c o m p _ s i m p l e * d e c o m p _ a t u a l ;

  4786

  l i s t a _ e x p r *Q , *R , * R _ d u m my ;

  4785

  • c o n t a d o r ;

  }

  d e c o m p _ a t u a l = c o p i a _ d e c o m p _ s i m p l e s ( p o l y _ a c u m u l a d o s ) ;

  c o n t a d o r = 0;

  4895

  // quando o numero de p o l i n o m i o s a c u m u l a d o s for igual ao grau menos 1 da e q u a c a o de e n t r a d a pode ser que ja tenha t e r m i n a d o

  4893 4894

  decomp_atual - > resto = R ;

  4892

  // a t u a l i z a Resto par e Resto impar

  4890 4891

  i n s e r e _ p o l i n o m i o (& decomp_atual - > polinomios , p t r _ po l i n o m i o s - > p o l i n o m i o ) ;

  4889

  // insiro os p o l i n o m i o s que fazem parte da d e c o m p o s i c a o

  4887 4888

  4886

  p o l y _ p t r = decomp_atual - > p o l i n o m i o s ;

  // copio o primario , pois pode ser s e m e n t e para outras d e c o m p o s i c o e s

  4884 4885

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( Q ) ;

  4883

  d e s t r o i _ l i s t a _ e x p r _ e x p a n d i d a ( R_ d u m m y ) ;

  4882

  // limpar o R _ d u m m y e o & Q

  4881

  {

  4880

  

if ( p a r t i a l _ f r a c t i o n _ e x p a n s i o n ( resto , base - >P , p t r _ po l i n o m i o s - > polinomio - >P , &Q ,& R , & R _ d u m m y ) )

  4879

  // testar a base p r i n c i p a l com o p o l i n o m i o atual

  4896

  4897

  R _ d u m m y = NULL ;

  if ( c o n t a d o r == grau )

  4913

  d e s t r o i _ d e c o m p _ s i m p l e s ( d e c o m p _ a t u a l ) ;

  4912

  // apagar os v e t o r e s d e c o m p _ s i m p l e s e c u n d a r i o

  4911

  // * r e t o r n o = i n s e r e _ d e c o m p _ s i m p l e s (* retorno , d e c o m p _ a t u a l ) ;

  4910

  c o m b i n a _ d e c o m p _ m u l d e r ( decomp_atual , d e c o m p _ s i m p l e s _ p r i m a r i o , base , base_primari o , eq_entrada , retorno , total_decomp , l i s t a _ l i t e r a i s ) ;

  4909

  // t e r m i n o u de fazer uma d e c o m p o s i c a o parcial , chamar a c o m p a r a _ D e c o m p

  4908

  {

  4907

  4906

  while ( p o l y _ p t r != NULL )

  // vejo se ja t e r m i n o u

  4905

  c o n t a d o r ++;

  4904

  // somo um ao c o n t a d o r

  4902 4903

  }

  4901

  p o l y _ p t r = poly_ptr - > p r o x i m o _ p o l i n o m i o ;

  4900

  4899

  {

  4898

  4878

  4877

  4839

  d e s t r o i _ d e c o m p _ s i m p l e s ( d e c o m p _ a t u a l ) ;

  4857

  p t r _ p o l i n o m i o s = p t r _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  4856

  // i n c r e m e n t a o p o n t e i r o

  4854 4855

  }

  4852 4853

  }

  4850 4851

  }

  4849

  d e c o m p _ a t u a l = NULL ;

  4848

  4847

  4858

  // que nao p r e c i s o mais de d e c o m p _ a t u a l ;

  4846

  // como as d e c o m p o s i c o e s v a l i d a s serao a d i c i o n a d a s no if acima , quando o p r o g r a m a chegar aqui , s i g n i f i c a

  4844 4845

  e n c o n t r a _ d e c o m p _ p a r c i a l _ p r i m a r i a ( decomp_atual , base_ prima rio , R , b a s e _ s e c u n d a r i o , r e s t o _ s e c u n d a r i o , p t r _ p o l i n o m i o s , grau , retorno , total_decomp , l i s t a _ l i te r a i s , e q _ e n t r a d a ) ;

  4843

  // caso contrario , deve - se p r o c e d e r com a d e c o m p o s i c a o r e c u r s i v a m e n t e

  4842

  {

  4841

  else

  4840

  // caso contrario , p r o s s e g u i r com as d e c o m p o s i c o e s p a r c i a i s de forma r e c u r s i v a

  }

  }

  Q = NULL ; R = NULL ;

  // testa a base com todos os polinomios , excluindo - se a p r o p r ia base

  4875

  // limpar as v a r i a v e i s

  4874

  {

  4873

  if ( base - > id != p t r _ p o l i n o m i o s - > polinomio - > id )

  4872

  // testa p r i m e i r o se o p o l i n o m i o nao e igual a base

  4871

  {

  4870

  while ( p t r _ p o l i n o m i o s != NULL )

  4869

  4867 4868

  4859 4860

  v e t o r _ p o l i n o m i o s * p o l y _ p t r ;

  4866

  int c o n t a d o r ;

  4865

  v e t o r _ d e c o m p _ s i m p l e * d e c o m p _ a t u a l ;

  4864

  l i s t a _ e x p r *Q , *R , * R _ d u m my ;

  4863

  v e t o r _ p o l i n o m i o s * p t r _ p o l i n o m i o s = l i s t a _ p o l i n o m i o s ;

  4862

  {

  4861

  void e n c o n t r a _ d e c o m p _ p a r c i a l _ s e c u n d a r i a ( v e t o r _ d e c o m p _ s i m p l e * p o l y _ a c u m u l a d o s , p o l i n o m i o * base , l i s t a _ e x p r * resto , v e t o r _ p o l i n o m i o s * l i s t a _ p o l i n o m i o s , int grau , v e t o r _ d e c o m p ** retorno , v e t o r _ d e c o m p _ s i m p l e * d e c o m p _ s i m p l e s _ p r i m a r i o , p o l i n o m i o * base _primario , int * total_decomp , t a b e l a _ l i t e r a i s * l i s t a _ l i te r a i s , l i s t a _ e x p r * e q _ e n t r a d a )

  • c o n t a d o r ;

  4914

  

// caso contrario , p r o s s e g u i r com as d e c o m p o s i c o e s p a r c i a i s de forma r e c u r s i v a

  4915

  else

  4916

  {

  4917

  

// caso contrario , deve - se p r o c e d e r com a d e c o m p o s i c a o r e c u r s i v a m e n t e

  4918

  e n c o n t r a _ d e c o m p _ p a r c i a l _ s e c u n d a r i a ( decomp_atual , base , R , p t r _ p o l i n o m i o s , grau , retorno , d e c o m p _ s i m p l e s _ p r i m a r i o , bas e_primario , total_decomp , l i s t a _ l i t e r ai s , e q _ e n t r a d a ) ;

  4919

  // como as d e c o m p o s i c o e s v a l i d a s serao a d i c i o n a d a s no if acima , quando o p r o g r a m a chegar aqui , s i g n i f i c a

  4920

  // que nao p r e c i s o mais de d e c o m p _ a t u a l ;

  4921

  d e s t r o i _ d e c o m p _ s i m p l e s ( d e c o m p _ a t u a l ) ;

  4922

  d e c o m p _ a t u a l = NULL ;

  4923

  }

  4924

  }

  4925

  }

  4926 4927

  // i n c r e m e n t a o p o n t e i r o

  4928

  p t r _ p o l i n o m i o s = p t r _ p o l i n o m i o s - > p r o x i m o _ p o l i n o m i o ;

  4929

  }

  4930

  }

Novo documento

Tags

Documento similar

UM MÉTODO GLOBAL PARA A VERIFICAÇÃO DA SEGURANÇA DE COLUNAS E VIGAS CONTÍNUAS DE AÇO
0
0
12
ANÁLISE LONGITUDINAL DE TABULEIROS EM CAIXÃO MISTOS AÇO-BETÃO: COMPARAÇÃO ENTRE AS FORMULAÇÕES CLÁSSI- CAS E A TEORIA GENERALIZADA DE VIGAS
0
0
10
UNIVERSIDADE NOVA DE LISBOA Faculdade de Ciências e Tecnologia Departamento de Engenharia Civil Adaptive glass pane using shape-memory alloys
0
0
109
SOLUÇÃO CONSTRUTIVA ECO-EFICIENTE DE PAREDES MONOLÍTICAS CONTRIBUTO PARA A SUA CARACTERIZAÇÃO
0
0
8
Eduardo Dias da Silva A – TUA – AÇÃO: O TEXTO TEATRAL, O CORPO E A VOZ COMO MEDIADORES NA APROPRIAÇÃO DA ORALIDADE NO ENSINO-APRENDIZAGEM DE LÍNGUA
0
0
106
ABORDAGEM SINDRÔMICA DE DOENÇAS FEBRIS AGUDAS
0
0
356
ACASO, DESTINO E REVELAÇÃO: UM ESTUDO SOBRE CIRCULAÇÃO, PROJETOS FAMILIARES E TRAJÉTÓRIAS NA FORMAÇÃO DE JOGADORES DE FUTEBOL
0
0
134
DISSERTAÇÃO DE MESTRADO Acesso Inicial Omnidirecional de Usuário em Redes de Ondas Milimétricas via Esquema de Alamouti
0
0
124
A CORDOS REGIONAIS DE COMÉRCIO: O CASO DAS CLÁUSULAS AMBIENTAIS
0
0
139
AÇÃO COLETIVA DE AGROEXTRATIVISTAS EM CIRCUITOS CURTOS DE COMERCIALIZAÇÃO DE PRODUTOS DO CERRADO: ESTUDO DE CASO EM PIRENÓPOLIS – GO
0
0
114
UNIVERSIDADE DE BRASÍLIA – FACULDADE DE DIREITO BRASÍLIA – DF 2013
0
0
161
A ADMINISTRAÇÃO DA TAXA DE CÂMBIO NO PLANO REAL E OS FUNDAMENTOS ECONÔMICOS BRASILEIROS
0
0
187
UNIVERSIDADE DE BRASÍLIA INSTITUTO DE CIÊNCIA POLÍTICA – IPOL ADRIANO MARTINS DE PAIVA
0
0
148
UNIVERSIDADE DE BRASÍLIA FACULDADE DE EDUCAÇÃO PROGRAMA DE PÓS-GRADUAÇÃO EM EDUCAÇÃO- PPGE
0
0
123
UnB INSTITUTO DE CIÊNCIAS HUMANAS - IH DEPARTAMENTO DE GEOGRAFIA - GEA
0
0
179
Show more