7  Matrizes e modelagem

O MUNDO TE CHAMA

Você já percebeu como o mundo moderno se apresenta hoje ? O dinheiro circula digitalmente entre setores variados da economia, dados imensos são conectados em redes sociais (big data), imagens digitais em 3D são criadas por grades numéricas para jogos digitais, a inteligência artificial processa milhões de relações matemáticas ao mesmo tempo por pedaços de palavras (tokens), carros autônomos se locomovem sem motorista, e mesmo uma simples consulta de um produto no celular já faz com que você receba uma enxurrada de ofertas parecidas depois.

Essas situações variadas envolvem entradas, transformações numéricas, e saídas. Em todos esses casos, as transformações estão relacionadas a objetos que podem ser ampliados, comprimidos, rotacionados, inclinados ou refletidos. Na base desses cálculos frequentemente existe uma matriz, uma “máquina” de relações matemáticas capaz de transformar posições no espaço.

Depois de explorar, você consegue:

- Representar transformações geométricas usando matrizes;
- Relacionar rotações, escalas e deformações com operações matemáticas;
- Interpretar matrizes como regras de transformação;
- Simular sistemas que evoluem ao longo do tempo;
- Observar como pequenas interações alteram trajetórias futuras;
- Comparar diferentes cenários usando o mesmo modelo matemático;
- Relacionar matrizes com situações do cotidiano, como redes, populações, economia e propagação;
- Entender que matrizes podem descrever tanto mudanças no espaço quanto mudanças no tempo;
- explorar, modificar e discutir modelos computacionais simples para matrizes.
Figura 7.1: Matrizes permitem transformar situações reais em modelos manipuláveis.

MEXA ANTES DE ENTENDER

Observe uma transformação acontecendo com auxílio do script de JSPlotly da Figura 7.2. No script você escolhe um ponto, aplica uma regra e o ponto muda de lugar.

Figura 7.2: Transformação linear: a matriz pode funcionar como uma regra que altera a posição de um ponto. Clique com o botão direito neste LINK e abra o aplicativo em nova aba.

O JSPlotly acima permite ver como uma matriz 2×2 (2 linhas e 2 colunas) modifica um vetor no plano cartesiano, alterando sua direção, tamanho ou orientação. O ponto original e o ponto transformado aparecem no plano. Experimente mudar o valor de x e y, alterar os números da matriz, comparar o vetor original com o vetor transformado, e observar quando o ponto gira, estica, encolhe ou muda de direção.

Agite antes de usar

O app funciona como uma visualização geométrica da multiplicação matricial.

No app, altere os valores do ponto inicial:

input_x
input_y

Depois experimente modificar os elementos da matriz:

input_a
input_b
input_c
input_d

Observe como o vetor azul original é transformado em um novo vetor. Tente descobrir quais valores ampliam o vetor, quais refletem o vetor, quais trocam as coordenadas, quais deformam o plano, e quais praticamente não alteram nada. Em suma, tente perceber o comportamento geométrico da matriz. Você pode usar o app da seguinte forma:

  1. Escolha um ponto inicial alterando:
input_x
input_y
  1. Modifique os elementos da matriz:
input_a
input_b
input_c
input_d

Observe a direção do vetor, seu tamanho e orientação, bem como reflexões e deformações.

  1. Compare o vetor original com o transformado.

  2. Tente prever o resultado antes de rodar novamente.

Seguem também alguns cenários para você experimentar.

  1. Ampliação horizontal. O eixo x é ampliado.
input_a = 2
input_b = 0
input_c = 0
input_d = 1
  1. Ampliação vertical. O eixo y cresce.
input_a = 1
input_b = 0
input_c = 0
input_d = 2
  1. Reflexão vertical. O vetor é espelhado no eixo y.
input_a = -1
input_b = 0
input_c = 0
input_d = 1
  1. Reflexão horizontal. O vetor é espelhado no eixo x.
input_a = 1
input_b = 0
input_c = 0
input_d = -1
  1. Troca entre coordenadas. As posições x e y trocam de lugar.
input_a = 0
input_b = 1
input_c = 1
input_d = 0
  1. Inclinação do plano. O plano sofre uma deformação inclinada.
input_a = 1
input_b = 1
input_c = 0
input_d = 1

Agora mais alguns cenários, dessa vez bastante utilizados em Computação e Engenharias, e que remetem a conceitos observados na organização de dados e solução de sistemas complexos (ajustes de curvas a pontos experimentais, por exemplo). Eles falam sobre alguns “tipos de matrizes” que produzem comportamentos geométricos diferentes no plano. Seguem esses cenários.

Considere inicialmente a matriz:

\[ \begin{bmatrix} 1 & 2 \\ -1 & 1 \end{bmatrix} \tag{7.1}\]

  1. Matriz identidade. Nada muda no vetor transformado. A matriz atua como “não fazer nada”. Apesar disso, esse tipo de matriz é essencial para resolver sistemas de equações lineares e transformações geométricas envolvidas com matriz inversa.

\[ \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} \tag{7.2}\]

No script fica assim:

input_a = 1
input_b = 0
input_c = 0
input_d = 1
  1. Matriz simétrica. Os elementos fora da diagonal principal são iguais. Esse tipo de matriz aparece muito em Física, computação gráfica e análise de dados, especialmente em sistemas onde as relações entre variáveis são recíprocas.

\[ \begin{bmatrix} 1 & 2 \\ 2 & 1 \end{bmatrix} \tag{7.3}\]

input_a = 1
input_b = 2
input_c = 2
input_d = 1
  1. Matriz nula. Todos os elementos são zero. Nesse caso, qualquer vetor é transformado no vetor nulo, fazendo com que o ponto desapareça na origem. \[ \begin{bmatrix} 0 & 0 \\ 0 & 0 \end{bmatrix} \tag{7.4}\]
input_a = 0
input_b = 0
input_c = 0
input_d = 0
  1. Matriz transposta. A transposta é obtida trocando linhas por colunas. Compare essa matriz com sua versão original, e observe como pequenas mudanças reorganizam completamente a transformação geométrica.

\[ \begin{bmatrix} 1 & -1 \\ 2 & 1 \end{bmatrix} \tag{7.5}\]

input_a = 1
input_b = -1
input_c = 2
input_d = 1
  1. Matriz diagonal. Apenas os elementos da diagonal principal são diferentes de zero. Essas matrizes normalmente ampliam ou comprimem os eixos independentemente.

\[ \begin{bmatrix} 3 & 0 \\ 0 & 0.5 \end{bmatrix} \tag{7.6}\]

input_a = 3
input_b = 0
input_c = 0
input_d= 0.5
  1. Matriz inversa. Algumas transformações podem ser desfeitas por outra matriz. A matriz inversa atua como um caminho de volta, restaurando a configuração original do vetor. Se a matriz ampliou o eixo x por 2, a matriz inversa reduz o eixo x pela metade, retornando o vetor à escala original. Essa matriz é usada em modelagem linear (quando se tem pontos que parecem desenhar um reta) e não linear (quando se tem pontos que parecem desenhar uma curva). Considerando a matriz original abaixo:

\[ \begin{bmatrix} 2 & 0 \\ 0 & 1 \end{bmatrix} \tag{7.7}\]

Ela amplia o eixo x por um fator 2. Então sua matriz inversa faz o caminho contrário:

\[ \begin{bmatrix} 0.5 & 0 \\ 0 & 1 \end{bmatrix} \tag{7.8}\]

No script:

input_a = 0.5
input_b = 0
input_c = 0
input_d = 1

Esse cenários reproduzem de forma simplificada algumas transformações matriciais que são comumente observadas em vários campos, tais como computação gráfica, modelagem 3D, jogos digitais, inteligência artificial, robótica, Engenharia, Física, Estatística, processamento de imagens e animações. Toda vez que um objeto gira, muda de escala ou se move em ambientes digitais, existe uma grande chance de matrizes estarem trabalhando silenciosamente por detrás.

Essas transformações são denominadas por transformações lineares, e são comumente utilizadas para representar uma ação sobre um objeto. O efeito final permite que o objeto experimente rotação, ampliação, redução, reflexão, cisalhamento (corte ou deformação), mistura, troca, fluxo, propagação e dependência entre variáveis.

Por dentro do script

Uma matriz pode ser entendida como uma regra matemática que recebe um vetor e devolve outro. Pode-se considerar o vetor original como:

\[ \begin{bmatrix} x \\ y \end{bmatrix} \tag{7.9}\]

e a matriz como:

\[ \begin{bmatrix} a & b \\ c & d \end{bmatrix} \tag{7.10}\]

Por exemplo, se no script está escrito:

input_a = 2
input_b = 1
input_c = 0
input_d = 3

a matriz utilizada será:

\[ \begin{bmatrix} 2 & 1 \\ 0 & 3 \end{bmatrix} \]

Essa matriz é a que será aplicada ao vetor original do plano cartesiano durante a transformação. Então o novo vetor será:

\[ \begin{bmatrix} a & b \\ c & d \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} ax+by \\ cx+dy \end{bmatrix} \tag{7.11}\]

Portanto, a nova coordenada x depende da combinação entre x e y. Já a nova coordenada y passa a depender dessa mistura, e com ambas as tranformações controladas pela matriz. Quer saber como funciona essa transformação no código da Figura 7.2 ?

O script apresenta dois vetores, um original e outro transformado pela matriz. A transformação ocorre pelas equações:

\[ x'=ax+by \tag{7.12}\]

\[ y'=cx+dy \tag{7.13}\]

Cada elemento da matriz possui uma função geométrica. Alguns valores ampliam o vetor, outros comprimem, alguns refletem, e outros misturam os eixos x e y. O interessante é que o plano inteiro pode ser deformado usando apenas quatro números.

No código, o trecho abaixo faz exatamente a multiplicação da matriz pelo vetor.

let x2 = a * x + b * y;
let y2 = c * x + d * y;

A linha que segue desenha o vetor original saindo da origem.

x: [0, x],
y: [0, y]

Já a próxima, desenha o vetor transformado.

x: [0, x2],
y: [0, y2]

FAZENDO APARECER

O app da seção anterior possibilitou perceber que uma matriz 2×2 pode transformar um ponto ou vetor no plano. Mas imagine se, em vez de transformar apenas um vetor, você pudesse transformar uma figura inteira ! A ideia é a mesma, mas aplicada a todos os pontos que formam o quadrado. Ficaria mais fácil perceber como rotações, ampliações e cisalhamentos podem ser descritos por matrizes. E esse é o objetivo do próximo script.

Figura 7.3: Quando uma matriz transforma todos os pontos de uma figura, ela transforma a aparência da figura. Clique com o botão direito neste LINK e abra o aplicativo em nova aba.

Agite antes de usar

No app, altere primeiro o tipo de transformação. Você pode usar “rotacao”, “escala” ou “cisalhamento”:

input_tipo = "rotacao"

Depois modifique os valores de:

input_angulo
input_escala

Observe como o quadrado original é transformado. Tente perceber quais transformações preservam a forma, quais alteram o tamanho e quais deformam a figura.

  1. Escolha o tipo de transformação:
input_tipo = "rotacao"
  1. Se escolher rotação, altere:
input_angulo = 45
  1. Se escolher escala ou cisalhamento, altere:
input_escala = 1.5
  1. Compare o quadrado original com o transformado.

  2. Observe se a figura apenas gira, aumenta, diminui ou se deforma.

  3. Tente prever o resultado antes de executar novamente.

Para ajudar diretamente nessas transformações, seguem alguns cenários interessantes.

  1. Rotação suave. O quadrado gira ao redor da origem, mas mantém seu tamanho e sua forma.
input_tipo = "rotacao"
input_angulo = 30
input_escala = 1.5
  1. Rotação de 90 graus. A figura gira um quarto de volta no plano cartesiano.
input_tipo = "rotacao"
input_angulo = 90
input_escala = 1.5
  1. Rotação negativa. O quadrado gira no sentido horário.
input_tipo = "rotacao"
input_angulo = -45
input_escala = 1.5
  1. Rotação completa. A figura retorna praticamente à posição original após uma volta inteira.
input_tipo = "rotacao"
input_angulo = 360
input_escala = 1.5
  1. Ampliação uniforme. O quadrado aumenta de tamanho sem deformar sua geometria.
input_tipo = "escala"
input_angulo = 45
input_escala = 2
  1. Redução uniforme. A figura diminui, mas preserva a forma original.
input_tipo = "escala"
input_angulo = 45
input_escala = 0.5
  1. Escala negativa. A figura sofre inversão geométrica juntamente com mudança de tamanho.
input_tipo = "escala"
input_angulo = 45
input_escala = -1
  1. Cisalhamento moderado. O quadrado começa a inclinar lateralmente.
input_tipo = "cisalhamento"
input_angulo = 45
input_escala = 1
  1. Cisalhamento intenso. A deformação lateral se torna bastante evidente.
input_tipo = "cisalhamento"
input_angulo = 45
input_escala = 2
  1. Cisalhamento negativo. A inclinação ocorre para o lado oposto.
input_tipo = "cisalhamento"
input_angulo = 45
input_escala = -1
  1. Quase uma reta. Um cisalhamento extremo começa a deformar fortemente a figura.
input_tipo = "cisalhamento"
input_angulo = 45
input_escala = 5
  1. Rotação pequena. Pequenos ângulos produzem transformações discretas, úteis em animações suaves.
input_tipo = "rotacao"
input_angulo = 5
input_escala = 1.5
  1. Ampliação extrema. A figura cresce muito rapidamente.
input_tipo = "escala"
input_angulo = 45
input_escala = 3
  1. Figura espelhada e ampliada. A escala negativa combinada com módulo maior que a unidade (1) cria inversão e ampliação simultaneamente.
input_tipo = "escala"
input_angulo = 45
input_escala = -2
  1. Sem transformação. A figura permanece praticamente inalterada.
input_tipo = "escala"
input_angulo = 45
input_escala = 1

Por dentro do script

No JSPlotly anterior, a matriz era preenchida diretamente com os valores a, b, c e d. Agora, esses valores são calculados automaticamente a partir do tipo de transformação escolhido.

Para uma rotação, por exemplo, a matriz é:

\[ \begin{bmatrix} \cos(\theta) & -\sin(\theta) \\ \sin(\theta) & \cos(\theta) \end{bmatrix} \tag{7.14}\]

Para uma escala uniforme, a matriz é:

\[ \begin{bmatrix} s & 0 \\ 0 & s \end{bmatrix} \tag{7.15}\]

Para um cisalhamento horizontal, a matriz é:

\[ \begin{bmatrix} 1 & k \\ 0 & 1 \end{bmatrix} \tag{7.16}\]

Em todos os casos, a regra geral continua sendo a mesma:

$$ \[\begin{bmatrix} x' \\ y' \end{bmatrix}\]

=

\[\begin{bmatrix} a & b \\ c & d \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix}\]

$${#eq-transformacaoGeral2}

A diferença é que agora essa transformação é aplicada a vários pontos da figura, um por vez.

O quadrado inicial é formado por listas de coordenadas:

let x = [-1, 1, 1, -1, -1];
let y = [-1, -1, 1, 1, -1];

Cada par (x[i], y[i]) representa um vértice do quadrado, e o último ponto repete o primeiro para fechar a figura. O trecho abaixo cria listas vazias para guardar os novos pontos transformados:

let x2 = [];
let y2 = [];

Em seguida, um laço (loop) percorre todos os pontos do quadrado:

for (let i = 0; i < x.length; i++) {
  x2.push(a*x[i] + b*y[i]);
  y2.push(c*x[i] + d*y[i]);
}

Esse último trecho é o coração do script. Ele aplica a matriz de transformação em cada vértice da figura. Assim, a mesma multiplicação matricial que antes transformava um ponto, agora transforma uma figura completa.


VOLTA PRO MUNDO

Em muitos problemas do mundo real, matrizes vão bem além de mudar posições no espaço. Elas descrevem como sistemas inteiros podem evoluir ao longo do tempo. Crescimento populacional, propagação de epidemias, predição por redes neurais, transporte e sinalização de trânsito (semáforos), circulação de dinheiro entre setores econômicos, redes de comunicação, e mesmo algoritmos de inteligência artificial são modelados por matrizes. Nesses casos, cada multiplicação matricial representa uma nova etapa do sistema, permitindo acompanhar tendências, equilíbrios, explosões de crescimento ou colapsos dinâmicos.

O próximo script propõe isso, usar uma matriz para transformar o estado de um sistema ao longo do tempo.

Figura 7.4: Matrizes e modelagem dinâmica: pequenas regras de interação podem produzir grandes mudanças ao longo do tempo. Clique neste LINK para abrir em nova aba.

O script mostra como uma matriz pode representar a evolução de um sistema ao longo do tempo. A ideia é simples:

\[ estado(t+1) = A \cdot estado(t) \]

Ou seja, o estado futuro depende do estado atual e de uma matriz de transformação (A). Essa matriz define como duas partes do sistema influenciam uma à outra. Dependendo do cenário escolhido, essas partes podem representar duas espécies, dois setores econômicos, dois conjuntos de suscetíveis e infectados, dois nós de uma rede, e tantos outros pares.

O gráfico da esquerda mostra a evolução temporal. Ele responde perguntas como se A ou B crescem ou diminuem, se o total se conserva, ou se o sistema explode ou estabiliza. Já o gráfico da direita mostra a trajetória no espaço de estados, e em que cada ponto representa uma combinação entre A e B.

Agite antes de usar

Execute o script com algum cenario como “populacao”, “economia”, “epidemia”, ou “rede”.

const cenario = "populacao";
const passos = 30;
const intensidade = 1.0;
const inicialA = 10;
const inicialB = 5;

Depois altere o cenário e observe como a mesma estrutura matemática produz comportamentos diferentes. Em seguida, altere a intensidade (0.3; 1.5, por exemplo). Veja como a força das interações muda a trajetória do sistema.

A matriz A determina o que acontece com cada componente do sistema.

Por exemplo:

novoA = A[0][0] * estado[0] + A[0][1] * estado[1];
novoB = A[1][0] * estado[0] + A[1][1] * estado[1];

Isso significa que o novo valor de A depende de quanto A preserva de si mesmo, e de quanto B influencia A. Já o novo valor de B depende de quanto A influencia B, e de quanto B preserva de si mesmo.

Você pode usar o app seguindo o rápido tutorial abaixo.

  1. Rode o script com cenario = "populacao";
  2. Observe as curvas de A, B e Total no gráfico da esquerda;
  3. Observe a trajetória no espaço de estados no gráfico da direita;
  4. Troque para cenario = "economia";
  5. Veja se o total cresce, diminui ou se estabiliza;
  6. Troque para cenario = "epidemia";
  7. Observe como suscetíveis e infectados se relacionam;
  8. Troque para cenario = "rede";
  9. Compare o fluxo entre os dois nós;
  10. Aumente intensidade;
  11. Veja como as interações ficam mais fortes;
  12. Altere inicialA e inicialB;
  13. Observe como o ponto de partida muda toda a trajetória.

Perceba nessa “brincadeira” que, em adição a seus valores iniciais, o sistema muda por causa da matriz que governa as relações. Seguem alguns cenários interessantes, também.

  1. População com interação fraca. Quando as interações são fracas, cada componente mantém mais seu próprio comportamento ?
const cenario = "populacao";
const intensidade = 0.3;
  1. População com interação forte. Uma pequena influência entre espécies pode se amplificar ao longo do tempo ?
const cenario = "populacao";
const intensidade = 1.8;
  1. Economia entre setores. Um setor mais forte ao início altera o fluxo econômico futuro ?
const cenario = "economia";
const inicialA = 20;
const inicialB = 5;
  1. Propagação simplificada. Como a interação entre suscetíveis e infectados altera a evolução do sistema ?
const cenario = "epidemia";
const intensidade = 1.2;
  1. Rede de conexões. Em uma rede, o ponto inicial muda o caminho da informação ou do fluxo ?
const cenario = "rede";
const inicialA = 5;
const inicialB = 20;
  1. Muitos passos. O comportamento de longo prazo revela crescimento, queda, equilíbrio ou explosão ?
const passos = 80;

Por dentro do script

O script começa escolhendo um cenário:

const cenario = "populacao";

Cada cenário define uma matriz diferente. No caso populacional, por exemplo:

A = [
  [1.05, 0.10 * intensidade],
  [0.05 * intensidade, 0.95]
];

Essa matriz indica que:

  • a espécie A cresce um pouco por si mesma;
  • a espécie B influencia A;
  • a espécie A influencia B;
  • a espécie B diminui levemente por si mesma.

Depois o script define o estado inicial:

let estado = [inicialA, inicialB];

Em seguida, aplica repetidamente a matriz ao estado atual:

let novoA = A[0][0] * estado[0] + A[0][1] * estado[1];
let novoB = A[1][0] * estado[0] + A[1][1] * estado[1];

estado = [novoA, novoB];

Cada repetição representa um novo passo no tempo e, por isso, uma matriz simples consegue gerar uma trajetória inteira.


E SE…

Agora aquela seção para assimilar o conteúdo visto por abstração ou mesmo por devaneio ! Mas é pra isso que serve essa parte do texto, certo ? Para refletir com pé no chão, mas permitindo-se colocar a cabeça nas nuvens.

  • E se aumentar o ângulo de rotação fizesse a figura “girar” exatamente como um objeto em um jogo ou aplicativo ?
  • E se ampliar a escala fosse parecido com usar zoom em uma imagem, mas controlado por uma matriz ?
  • E se um pequeno cisalhamento fosse suficiente para deformar completamente uma figura após várias transformações ?
  • E se a mesma matriz pudesse transformar tanto desenhos geométricos quanto populações, epidemias e redes ?
  • E se uma pequena mudança na intensidade das interações alterasse completamente o futuro de um sistema ?
  • E se duas espécies começassem quase iguais, mas terminassem muito diferentes após vários passos da simulação ?
  • E se um pequeno número inicial de infectados acabasse dominando o sistema inteiro ?
  • E se redes sociais, trânsito ou fluxo de informações funcionassem de modo parecido com os modelos do script ?
  • E se o “estado atual” de um sistema influenciasse continuamente o próximo estado, como acontece em hábitos, economia ou estudos ?
  • E se matrizes fossem uma forma de descrever mudanças que acontecem no tempo e no espaço ao mesmo tempo ?
  • E se o trajeto mostrado no espaço de estados fosse parecido com acompanhar a evolução de escolhas ao longo da vida ?
  • E se transformar figuras no plano e prever comportamentos futuros fossem apenas duas arestas da mesma Matemática ?

MESMO PADRÃO, OUTROS MUNDOS

Você já deve ter percebido pelos parágrafos anteriores que não há propriamente um conjunto ou outro de aplicações para matrizes. Quem sabe a limitação para seu uso seja aquela ditada pela criatividade humana, somente. Imagine, por exemplo, um desses aplicativos de celular ou computador que modificam um rosto ou uma paisagem. Uma imagem digital pode ser pensada como uma matriz de pixels, onde cada número representa uma intensidade de cor ou luminosidade. Modificar essa matriz pode clarear a imagem, escurecer a imagem, inverter cores, detectar bordas, borrar regiões, ou realçar detalhes. Isso é a “alma” dos manipuladores de imagens !

Uma rede social também pode ser representada por uma matriz de conexões. Se duas pessoas estão conectadas, a matriz registra essa relação, permitindo estudar influência, grupos, centralidade, propagação de informação e formação de comunidades. Em jogos e animações digitais as matrizes ajudam a mover personagens, girar objetos, mudar perspectivas, simular câmeras e transformar mundos 2D e 3D.

Em inteligência artificial, redes neurais usam muitas operações matriciais. Dados entram como vetores ou matrizes, pesos são organizados em matrizes, e o resultado é uma sequência de transformações, fazendo da IA uma grande cadeia de transformações matemáticas. Também em Ecologia matrizes podem ser empregadas para representar reprodução, mortalidade, competição, migração e transição entre fases evolutivas ou ontogenéticas (desenvolvimento do organismo). Isso permite projetar panoramas para o crescimento de uma população, como sua estabilização, colapso ou explosão.


POR DENTRO DA FERRAMENTA

Nessa seção, damos sequência a um aprendizado panorâmico em JavaScript, voltado ou não à edição de objetos com JSPlotly, como realizado no capítulo anterior. Nesse sentido, segue um pouco sobre a estrutura de JS para aritmética e arrays (vetores).

E agora um truque bem bacana !!! Você poderá treinar a linguagem JavaScript utilizando um JSPlotly específico para isso !. Esse JSPlotly personalizado está disponível na Figura 9.22 que segue. Abra-o num navegador e deixe-o quietinho lá. *Quando quiser rodar algum trecho desses treinamentos, basta copiar, colar o trecho no campo "ÁREA PARA DIGITAR COMANDOS", e rodá-lo*. Muito legal, não ?!

Figura 7.5: JSPlotly personalizado para treinamento da linguagem JavaScript JSPlotly_treinoJS.html. Basta clicar com o botão direito do mouse para abri-lo em outra janela do navegador. Deixe-o quietinho lá. Quando quiser executar algum trecho de código ao longo desse treinamento, basta copiar, colar no campo “ÁREA PARA DIGITAR COMANDOS”, e rodar no JSPlotly personalizado.

Aritmética

Diversas operações matemáticas são possíveis, quer pelo JS puro, quer pela instalação de bibliotecas específicas, tais como Plotly.js utilizada no JSPlotly, mathjs ou numjs. Segue abaixo uma lista de operações aritméticas realizadas com a linguagem:

  1. + : adição de números ou concatenação de texto (strings);
  2. - : subtração;
  3. * : multiplicação;
  4. / : divisão;
  5. % : módulo;
  6. ++ : incremento de valor;
  7. -- : decremento;
  8. ** : exponenciação.

Obs: o operador de módulo *%* divide o primeiro operando pelo segundo operando e retorna o resto.

Os exemplos a seguir ilustram o uso desses operadores aritméticos, bem como de algumas constantes matemáticas. Para testá-los, cole no JSPlotly customizado para treinamento de JS, como informado acima. Você pode experimentá-los separadamente ou em bloco.

let resultado = 0;

resultado = 5 + 3;                 print("5 + 3 = ", resultado);          // 8
resultado = 10 - 4;                print("10 - 4 = ", resultado);          // 6
resultado = 6 * 7;                 print("6 * 7 = ", resultado);           // 42
resultado = 20 / 5;                print("20 / 5 = ", resultado);          // 4
resultado = 17 % 3;                print("17 % 3 = ", resultado);          // 2
resultado = 2 ** 3;                print("2 ** 3 = ", resultado);          // 8
let contador = 5; contador++;      print("contador++ = ", contador);       // 6
let decrementar = 8; decrementar--;print("decrementar-- = ", decrementar); // 7
let soma = 10; soma += 5;          print("soma += 5 = ", soma);            // 15
let diferenca = 20; diferenca -= 7;print("diferença -= 7 = ", diferenca);   // 13
let produto = 3; produto *= 4;     print("produto *= 4 = ", produto);       // 12
let quociente = 24; quociente /= 3;print("quociente /= 3 = ", quociente);   // 8
resultado = Math.sqrt(25);         print("sqrt(25) = ", resultado);         // 5
resultado = Math.abs(-15);         print("abs(-15) = ", resultado);         // 15
resultado = Math.floor(7.8);       print("floor(7.8) = ", resultado);       // 7
resultado = Math.ceil(7.2);        print("ceil(7.2) = ", resultado);        // 8
resultado = Math.round(9.4);       print("round(9.4) = ", resultado);       // 9
resultado = Math.max(42, 27);      print("max(42,27) = ", resultado);       // 42
resultado = Math.min(42, 27);      print("min(42,27) = ", resultado);       // 27
resultado = Math.sin(Math.PI/2);   print("sin(π/2) = ", resultado); 

Arrays

Um array em JavaScript representa uma estrutura de dados para armazenamento de elementos ordenados. Esses elementos podem envolver qualquer tipo de dado, como números, strings (termos), objetos, etc. Na prática, um array pode ser criado, acessado, filtrado, ou mapeado. Seguem exemplos:

Criação

const numeros = [1, 2, 3, 4, 5];
const cores = ['vermelho', 'verde', 'azul'];

Acesso

print(numeros[0]);
print(cores[2]);

Ou seja, para você acessar o array numeros, por exemplo, basta colar e rodar o seguinte trecho no JSPlotly de treinamento:

const numeros = [1, 2, 3, 4, 5];
const cores = ['vermelho', 'verde', 'azul'];

print(numeros[0]);

Mapeamento (map)

const numeros = [1, 2, 3, 4, 5];
const quadrados = numeros.map(numero => numero * numero);
print(quadrados);

Uma palavrinha sobre métodos

Observe que, diferente do que já foi explicitado, agora aparece um comando múltiplo, como “numeros.map”. Existe uma infinidade de comandos com esta sintaxe em JS. Ele representa a função que será aplicada a cada elemento do array numeros pelo método map. Além disso, surge a sintaxe “=>” ou sintaxe de arrow function (função de seta), uma forma concisa de atribuir um mapeamento.

Em JavaScript, objetos são tratados como no mundo real, ou seja, possuem atributos e comportamentos. Atributos descrevem as características que um objeto possui, e os comportamentos as ações que podem realizar. A notação em JS para referenciar as propriedades de um objeto pode ser, alternativamente:

objeto.propriedade

...ou...

objeto[propriedade]
  Voltando ao exemplo acima e esmiuçando-o um pouquinho mais, o método map() (numeros.map) é chamado no array numeros (um Array.prototype). O *protótipo* permite transmitir propriedades e métodos para um objeto JS. No caso, o método map() itera sobre cada elemento do array original (refinamento por ações sucessivas para aproximar um resultado desejado), aplica uma função a cada um deles e retorna um novo array com os resultados. Assim, numero => numero numero* é a função de seta. E nesse caso, numero é o parâmetro de entrada da função, um atalho para o elemento atual do array sendo processado pelo map. Em adição, “=>” representa o separador entre o(s) parâmetro(s) e o corpo da função. Finalmente, “numero * numero” é a expressão que é executada, com o resultado sendo retornado pela função. Seguem outros exemplos para arrays e mapeamento:
 const x = [0, 1, 2, 3, 4];
 const y = x.map(valor => Math.pow(2, valor))
 print(y);
const Vmax = 100;
const Km = 10;
const S_values = Array.from({length: 10}, (_, i) => i * 5);

const V_values = S_values.map(S => (Vmax * S) / (Km + S));

print("Valores de S:", S_values);
print("Valores de V:", V_values);

JavaScript, uma linguagem orientada a objetos

  Ainda que o esforço para traduzir os comandos acima possa auxliar como funciona a linguagem, é por óbvio esperar uma certa confusão de termos. Sendo assim, vamos subindo de nível ….!
  Como diz o título acima, JS é uma linguagem orientada a objetos. Isso significa que o código é organizado em torno de objetos, que combinam dados (propriedades) e comportamentos (métodos) para modelar entidades do mundo real (não, não são fantasmas!). Isso permite um código mais modular, reutilizável e fácil de gerenciar, ao organizar a lógica em “partes” menores e mais compreensíveis (pensamento computacional).

Objetos, propriedades, e métodos

  Um objeto é uma estrutura que agrupa dados e comportamentos. Os dados ficam guardados em propriedades, e os comportamentos são implementados por métodos (funções dentro do objeto). Assim, propriedades constituem pares nome–valor armazenados dentro de um objeto, podendo variar como números, textos, arrays, e outros objetos. Já os métodos são funções associadas a um objeto, e que descrevem ações que ele pode executar.
  Objetos em JS “podem ser comparados a objetos da vida real”, e guardam informações relacionadas entre si. Por exemplo, o objeto “ponto” abaixo representa um ponto no plano:
const ponto = { x: 2, y: 5 };  // objeto com duas propriedades

Assim, as propriedades são as características do objeto:


print(ponto.x);  // mostra 2
print(ponto.y);  // mostra 5
  Assim, um objeto pode ser encarado como um “pacote” contendo nome, conteúdo e ferramentas próprias. Virtualmente, tudo em JavaScript — arrays, funções, strings, números — é, de alguma forma, um objeto com suas propriedades e métodos. Segue um exemplo:


const carro = {
  marca: "Toyota",        // propriedade (dado)
  ano: 2022,              // propriedade
  ligar: function() {     // método (ação)
    console.log("O carro está ligado!");
  }
};

carro.ligar();            // chama o método
console.log(carro.marca); // acessa a propriedade

Reforçando (não custa nada…), um objeto JavaScript envolve uma coleção de propriedades, onde cada propriedade é definida por um par chave-valor, permitindo uma representação ordenada de elementos. Objetos podem conter diferentes tipos de dados como valores, números, strings, booleanos (falso/verdadeiro), arrays, outras funções e até mesmo outros objetos. Objetos criados são facilmente acessados por seus atributos. Seguem exemplos para testes.

Criação

const pessoa = {
    nome: 'João',
    idade: 30,
    cidade: 'São Paulo'
};

Acesso

print(pessoa.nome);
print(pessoa['idade']);

Atributos

pessoa.profissao = 'Engenheiro';
print(pessoa);

Para um exemplo fechado de objetos:

let pessoa = {
  nome: "João",
  idade: 30,
  profissao: "Desenvolvedor",
  hobbies: ["leitura", "música", "jogos"],
  endereco: {
    rua: "Rua Principal, 123",
    cidade: "São Paulo",
  },
  saudacao: function () {
    print("Olá, meu nome é " + this.nome);
  },
};

print(pessoa.nome); // Saída: "João"
print(pessoa.hobbies[0]); // Saída: "leitura"
pessoa.saudacao(); // Saída: "Olá, meu nome é João"

E por aí vai !! No próximo capítulo esse seção irá explorar um pouco sobre variáveis e funções em JavaScript.