Pergunta

Estou escrevendo um programa em Em processamento Isso transforma números complexos. No entanto, quero ter um método de pegar uma sequência de entrada e calcular a transformação usando uma variável complexa. Por exemplo:

1/(z+1)
(z^2)/(z/2)

onde z é um número complexo. Agora, eu olhei para Jep e alguns exemplos, mas não posso descobrir se isso permitir que você insira Z como uma variável (e, em qualquer caso, não é gratuita). Existe um analisador de expressão para Java (que funciona no processamento, que usa uma versão antiga do Java e não tem genéricos) que eu poderia usar para fazer isso?

Se não houver, alguém poderia me indicar o básico de como criar um?

Foi útil?

Solução

Como mencionado por Philo, você pode usar genéricos. Experimente este esboço de processamento:

import java.util.*;
java.util.List<String> list = Arrays.asList("a", "b", "c");
textFont(loadFont("UMingCN-30.vlw"));
for(int i = 0; i < list.size(); i++) {
  text(list.get(i), 5, int(i*30)+30);
}

E há uma versão não comercial do JEP disponível (GPL). Baixe aqui e adicione -o ao seu processamento de classe (importe -o). Depois de fazer isso com sucesso, você pode usar o JEP assim:

void setup() {
  org.nfunk.jep.JEP parser = new org.nfunk.jep.JEP();
  parser.addComplex();
  try {
    parser.parseExpression("(1+2*i) + (3+8*i)");
    println(parser.getComplexValue());
  } catch(Exception e) {
    e.printStackTrace();
  }
}

que produz a saída (esperada): (4.0, 10.0)

Outras dicas

Veja isso: http://bracer.sourceforge.net É a minha implementação do algoritmo de pátio de desvio e esse analisador suporta números complexos.

Se, por algum motivo, você precisar de mais flexibilidade do que os analisadores de expressão matemática "enlatados" sugeridos até agora (= controle total sobre operadores, precedência, construção de árvores), convém considerar meu analisador configurável:

https://github.com/stefanhaustein/expressionparser

Exemplo de código de avaliação direta para o seu caso:

static HashMap<String, Complex> variables = new HashMap<>();

/**
 * Processes the calls from the parser directly to a Complex value.
 */
static class ComplexProcessor extends ExpressionParser.Processor<Complex> {
  @Override
  public Complex infixOperator(ExpressionParser.Tokenizer tokenizer, String name, Complex left, Complex right) {
    switch (name.charAt(0)) {
      case '+': return left.plus(right);
      case '-': return left.minus(right);
      case '*': return left.times(right);
      case '/': return left.divides(right);
      case '^':
        if (right.im() != 0 || right.re() == (int) right.re()) {
          return left.pow((int) right.re());
        }
        throw new RuntimeException("Only integer exponents supported by Complex.pow().");
      default:
        throw new IllegalArgumentException();
    }
  }

  @Override
  public Complex prefixOperator(ExpressionParser.Tokenizer tokenizer, String name, Complex argument) {
    return name.equals("-") ? new Complex(0,0).minus(argument) : argument;
  }

  @Override
  public Complex numberLiteral(ExpressionParser.Tokenizer tokenizer, String value) {
    return new Complex(Double.parseDouble(value), 0);
  }

  @Override
  public Complex identifier(ExpressionParser.Tokenizer tokenizer, String name) {
    Complex value = variables.get(name);
    if (value == null) {
      throw new IllegalArgumentException("Undeclared variable: " + name);
    }
    return value;
  }

  @Override
  public Complex group(ExpressionParser.Tokenizer tokenizer, String paren, List<Complex> elements) {
    return elements.get(0);
  }

  /**
   * Creates a parser for this processor with matching operations and precedences set up.
   */
  static ExpressionParser<Complex> createParser() {
    ExpressionParser<Complex> parser = new ExpressionParser<Complex>(new ComplexProcessor());
    parser.addCallBrackets("(", ",", ")");
    parser.addGroupBrackets("(", null, ")");
    parser.addOperators(ExpressionParser.OperatorType.INFIX_RTL, 4, "^");
    parser.addOperators(ExpressionParser.OperatorType.PREFIX, 3, "+", "-");
    // 2 Reserved for implicit multiplication
    parser.addOperators(ExpressionParser.OperatorType.INFIX, 1, "*", "/");
    parser.addOperators(ExpressionParser.OperatorType.INFIX, 0, "+", "-");
    return parser;
  }
}

Exemplo de invocação:

  variables.put("i", new Complex(0, 1));
  variables.put("z", new Complex(1, 1));

  ExpressionParser<Complex> parser = ComplexProcessor.createParser();
  System.out.println("(z^2)/(z/2):", parser.parse("(z^2)/(z/2)"));

O próprio analisador é implementado em um único arquivo java Sem dependências, para fins de avaliação, é simples copiar para o seu próprio projeto

Eu (e, na verdade, faria manualmente uma mesa de análise e usava um analisador simples de LR ou Lalr para processar. Em uma redução, você pode executar os cálculos. Uma vantagem disso é que é fácil modificar o "idioma" ou entrada aceitável.

Aqui está uma solução louca: o Java possui um mecanismo JavaScript embutido (suponho que você possa acessá-lo do processamento). Agora, você escreve uma classe JavaScript que funciona com números complexos (copie -o de aqui). Em seguida, sobrecarregar os operadores de matemática conforme especificado aqui. Depois disso, você pode apenas avaliar essa string de Java. É uma loucura e não tenho certeza de que funcionará (não conheço JavaScript). Talvez faça encontrar uma solução mais simplificadora sem analisar expressões.

Aqui está um link para um analisador de expressão matemática direto (64 linhas): http://javadots.blogspot.com/2008/11/arithemetic-expressions-solver-in-64.html

Ajustar para apoiar suas necessidades não deve ser muito difícil

Usar Apache Common Math. É muito fácil de usar.

Você pode inicializar as duas peças imaginárias reais+. Você também pode inicializá -los a partir de uma string. Ele suporta uma ampla variedade de operações que você pode fazer com números imaginários.

Aqui está um exemplo de código para fazer algumas operações comuns:

package complex;
import static java.lang.String.format;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.math3.complex.Complex;
import org.apache.commons.math3.complex.ComplexFormat;
public class Do 
{
    public static void main(String[] args) 
{
     ComplexFormat format = new ComplexFormat();
    Complex lhs = new Complex(1.0, 3.0);
    Complex rhs = new Complex(2.0, 5.0);

    Complex answer = lhs.add(rhs);       // add two complex numbers
    System.out.println("Add : "+ format.format(answer));
    answer = lhs.subtract(rhs);  // subtract two complex numbers
    System.out.println("Subtract : "+ format.format(answer));
    answer = lhs.conjugate();
    System.out.println("Conjgate : "+ format.format(answer));
    double d = lhs.abs();
    System.out.println("Absolute : "+d);
    Complex first  = new Complex(1.0, 3.0);
    Complex second = new Complex(2.0, 5.0);

    answer = first.log();        // natural logarithm.
            System.out.println("Logarithm : "+ format.format(answer));
    answer = first.cos();        // cosine
            System.out.println("Cosine : "+ format.format(answer));
    answer = first.pow(second);  // first raised to the power of second
            System.out.println("Power : "+ format.format(answer));

            Complex z = new Complex(2.0,2.0);
            Complex z1 = z.reciprocal();
            System.out.println("Recipocal : "+ format.format(z1));

            System.out.println("Absoltue of 2+2i is "+z.abs());
            System.out.println("Argument of 2+2i is "+z.getArgument());

    Complex r = new Complex(6.3,9.6);
    String conj = format.format(r.conjugate());
    String reci = format.format(r.reciprocal());

    System.out.println("Conjugate : "+conj+" Recipocal : "+reci);

    //answer = lhs.abs();          // absolute value
    //answer = lhs.conjugate(rhs); // complex conjugate

    //make complex to string

    ComplexFormat format = new ComplexFormat(); // default format
    Complex c = new Complex(1.1111, 2.2222);
    String s = format.format(c); // s contains "1.11 + 2.22i"
    System.out.println(s);

    //make string to complex

    String z = "2.5+3.6i";
    Complex e = format.parse(z);
    System.out.println(e);

}    
}

Outra alternativa é Fraid, se você quiser outra opção.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top