diff --git a/doc/eval.texi b/doc/eval.texi index 92fdc6d0a6..b481bfe17f 100644 --- a/doc/eval.texi +++ b/doc/eval.texi @@ -106,6 +106,13 @@ the evaluation of @var{y}, return 0 otherwise. @item ifnot(x, y) Evaluate @var{x}, and if the result is zero return the result of the evaluation of @var{y}, return 0 otherwise. + +@item taylor(expr, x) +Evaluate a taylor series at x. +expr represents the LD(0)-th derivates of f(x) at 0. +note, when you have the derivatives at y instead of 0 +taylor(expr, x-y) can be used +When the series does not converge the results are undefined. @end table The following constants are available: diff --git a/libavutil/eval.c b/libavutil/eval.c index 1a18bf9ec5..fda099734c 100644 --- a/libavutil/eval.c +++ b/libavutil/eval.c @@ -134,7 +134,7 @@ struct AVExpr { e_squish, e_gauss, e_ld, e_isnan, e_mod, e_max, e_min, e_eq, e_gt, e_gte, e_pow, e_mul, e_div, e_add, - e_last, e_st, e_while, e_floor, e_ceil, e_trunc, + e_last, e_st, e_while, e_taylor, e_floor, e_ceil, e_trunc, e_sqrt, e_not, e_random, e_hypot, e_gcd, e_if, e_ifnot, } type; @@ -181,6 +181,23 @@ static double eval_expr(Parser *p, AVExpr *e) d=eval_expr(p, e->param[1]); return d; } + case e_taylor: { + double t = 1, d = 0, v; + double x = eval_expr(p, e->param[1]); + int i; + double var0 = p->var[0]; + for(i=0; i<1000; i++) { + double ld = d; + p->var[0] = i; + v = eval_expr(p, e->param[0]); + d += t*v; + if(ld==d && v) + break; + t *= x / (i+1); + } + p->var[0] = var0; + return d; + } default: { double d = eval_expr(p, e->param[0]); double d2 = eval_expr(p, e->param[1]); @@ -318,6 +335,7 @@ static int parse_primary(AVExpr **e, Parser *p) else if (strmatch(next, "isnan" )) d->type = e_isnan; else if (strmatch(next, "st" )) d->type = e_st; else if (strmatch(next, "while" )) d->type = e_while; + else if (strmatch(next, "taylor")) d->type = e_taylor; else if (strmatch(next, "floor" )) d->type = e_floor; else if (strmatch(next, "ceil" )) d->type = e_ceil; else if (strmatch(next, "trunc" )) d->type = e_trunc; @@ -698,6 +716,8 @@ int main(int argc, char **argv) "if(1, 2)", "ifnot(0, 23)", "ifnot(1, NaN) + if(0, 1)", + "taylor(1, 1)", + "taylor(eq(mod(ld(0),4),1)-eq(mod(ld(0),4),3), PI/2)", NULL }; diff --git a/tests/ref/fate/eval b/tests/ref/fate/eval index 09e310f25d..e5e796c5c7 100644 --- a/tests/ref/fate/eval +++ b/tests/ref/fate/eval @@ -169,5 +169,11 @@ Evaluating 'ifnot(0, 23)' Evaluating 'ifnot(1, NaN) + if(0, 1)' 'ifnot(1, NaN) + if(0, 1)' -> 0.000000 +Evaluating 'taylor(1, 1)' +'taylor(1, 1)' -> 2.718282 + +Evaluating 'taylor(eq(mod(ld(0),4),1)-eq(mod(ld(0),4),3), PI/2)' +'taylor(eq(mod(ld(0),4),1)-eq(mod(ld(0),4),3), PI/2)' -> 1.000000 + 12.700000 == 12.7 0.931323 == 0.931322575