/* Chebyshev related functions. author: Richard Fateman. 2016 See also cheby.lisp for faster versions of some of this */ kill(tc,onepower)$ tc[0](x):=1$ tc[1](x):=rat(x)$ tc[n](x):=2*x*tc[n-1](x)-tc[n-2](x)$ /*here's another way to generate cheby polys, if you are in a hurry */ tc2[0](x):=1$ tc2[1](x):=x$ tc2[n](x):= if evenp(n) then 2*tc2[n/2](x)^2-1 else 2*tc2[(n+1)/2](x)*tc2[(n-1)/2](x)-x$ ToChebyt(e,x,n):= /* convert analytic expression, depending on x, to Chebyshev series, via taylor series */ block([ tay: taylor(e,x,0,n),q,r,ans:[]], power2cheby(makelist(ratcoef(tay,x,i),i,0,n)))$ /* another version, which has been written elswhere in lisp for maxima */ /* convert analytic function lambda([x]...expression in x) to Chebyshev series The expression f may be a polynomial or function in other variables, too. The result will be a list of the Chebyshev coefficients. Here we try to make them all floats. */ ToCheby2(f,n):= /* this one takes a function, e,g, lambda([x],..) */ apply('chebseries,makelist(AJS1(f,j,n),j,0,n-1))$ AJS1(%%f,j,n):= /* compute a[j]s, by eval at gauss-lobatto points */ block([in:1.0d0/n,p:?pi/n], 2*in*(2-(if (j=n) then 0 else 1))* sum(block([h:p*(k+.5d0)], cos(h*j)*%%f(cos(h))),k,0,n-1))$ ToCheby2x(f,n):= /* this one takes a function, e,g, lambda([x],..) */ block([in:1.0d0/n,p:?pi/n], apply('chebseries,makelist(AJS1x(f,j,n,in,p,0),j,0,n-1)))$ AJS1x(%%f,j,n,in,p,h):= /* compute a[j]s, by eval at gauss-lobatto points */ 2*in*(2-(if (j=n) then 0 else 1))* sum( (h:p*(k+.5d0), print([h,cos(h),%%f(cos(h))]), cos(h*j)*%%f(cos(h))),k,0,n-1)$ FromCheby(a,x):= /* If x is a symbol, this will convert Chebyshev series to an expression in the power basis, i.e. polynomial in x. If x is a number, this will evaluate the series at that point and provide a number. (if a is just numbers). This algorithm is based on recurrence in Clenshaw alg. */ block([N:length(a)-1,keepfloat:true, bj2:0,bj1:0,bj0:0, z:reverse(a)], for j: 1 thru N do (bj0:2*x*bj1-bj2+first(z), bj2:bj1, bj1:bj0,z:rest(z)), x*bj1+first(z)/2 -bj2)$ FromChebyfloat(a,x):= /* x is a floating-point number. This algorithm is based on recurrence in Clenshaw alg. */ block([N:length(a)-1,keepfloat:true,fz:0.0, bj2:0.0,bj1:0.0,bj0:0.0, z:reverse(a)], modedeclare([bj0,bj1,bj2,x,fz],float,[j,N], fixnum), for j: 1 thru N do (fz:first(z), bj0:2.0*x*bj1-bj2+fz, bj2:bj1, bj1:bj0,z:rest(z)), x*bj1+first(z)*0.5 -bj2)$ /* a test */ small_to_zero(expr,eps):= /* Replaces all numbers smaller in absolute value than EPS by zero . */ fullmap(lambda([x], if numberp(x) and abs(x)