From 1c0c0471df3ab4d6108fdabaf071a8bbd4074a6f Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Fri, 4 Jan 2013 13:06:09 +0100 Subject: [PATCH] Simplify some generalized math formulas: Now the 'sin^2+cos^2=1' and the 'sinh^2-cosh^2=-1' code can handle, for example: sin^4+cos^4=1, sinh^10-cosh^10=-1. Also, the arguments can be also multitokens, so that it's possible to simplify, for example: 'sin^2(k())+cos^2(k())=1'. --- lib/tokenize.cpp | 39 +++++++++++++++++++++++++++++++-------- test/testtokenize.cpp | 8 ++++++++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 9c77aa60f..061089e87 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9350,14 +9350,37 @@ void Tokenizer::simplifyMathExpressions() tok->str("0"); } - if (Token::Match(tok,"pow ( sin ( %any% ) , 2 ) + pow ( cos ( %any% ) , 2 )") && tok->strAt(4) == tok->strAt(14)) { - tok->deleteNext(18); - tok->str("1"); - } - - if (Token::Match(tok,"pow ( sinh ( %any% ) , 2 ) - pow ( cosh ( %any% ) , 2 )") && tok->strAt(4) == tok->strAt(14)) { - tok->deleteNext(18); - tok->str("-1"); + //Pythagorean trigonometric identity: pow(sin(x),2n)+pow(cos(x),2n) = 1 + //Hyperbolic identity: pow(sinh(x),2n)-pow(cosh(x),2n) = -1 + //2n = any number which is multiple of 2 + if (Token::simpleMatch(tok, "pow (")) { + if (Token::simpleMatch(tok->tokAt(2), "sin (")) { + Token *tok2 = tok->linkAt(3); + if (!Token::Match(tok2, ") , %num% ) + pow ( cos (") || + MathLib::toLongNumber(tok2->strAt(2)) % 2 != 0) + continue; + Token *tok3 = tok2->tokAt(8); + if (!Token::Match(tok3->link(), ") , %num% )") || + tok3->link()->strAt(2) != tok2->strAt(2)) + continue; + if (tok->tokAt(3)->stringifyList(tok2->next()) == tok3->stringifyList(tok3->link()->next())) { + Token::eraseTokens(tok, tok3->link()->tokAt(4)); + tok->str("1"); + } + } else if (Token::simpleMatch(tok->tokAt(2), "sinh (")) { + Token *tok2 = tok->linkAt(3); + if (!Token::Match(tok2, ") , %num% ) - pow ( cosh (") || + MathLib::toLongNumber(tok2->strAt(2)) % 2 != 0) + continue; + Token *tok3 = tok2->tokAt(8); + if (!Token::Match(tok3->link(), ") , %num% )") || + tok3->link()->strAt(2) != tok2->strAt(2)) + continue; + if (tok->tokAt(3)->stringifyList(tok2->next()) == tok3->stringifyList(tok3->link()->next())) { + Token::eraseTokens(tok, tok3->link()->tokAt(4)); + tok->str("-1"); + } + } } } } diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 9a0189c35..62887076c 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -7725,6 +7725,10 @@ private: " std::cout<