123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- %to be included in the same set of modules as ratint, these procedures all
- %ammend the output of ratint, converting complex logs to real arctans, and
- %providing alternative forms for the answer
- % want a procedure to convert the log sum notation to a sum involving
- % radicals. We typically get something like
- %
- % log(x+1)+log_sum(alpha,alpha^2+alpha+1,0,alpha*log(alpha*2+x*alpha),x)
- %
- % as our output from the ratint program,
- % and we want to sub alpha into the log expression and sum.
- % other possibilies include transforming the logarithmic expression (which
- % often contains complex logarithms, to real arctangents.
- % This could be important if definite integration is the goal
- % Example
- % in symbolic mode, we have
- %
- % exp: (log_sum alpha (plus (expt alpha 2) alpha 1) 0
- % (times (log (plus (times alpha x) 1)) alpha) x)
- % need a procedure to get rid of parts of the expression not involving
- % log_sum
- algebraic <<
- logcomplex:=
- {
- log(~x+i) =>
- log(sqrt(x^2+1))+i*atan((1/sqrt(x^2+1))+i*(x/(sqrt(x^2+1)))), %when
- %repart(x)=x,
- log(~x- i) =>
- log(sqrt(x^2+1))-i*atan(1/sqrt(x^2+1)+i*(x/(sqrt(x^2+1)))),
- %when repart(x)=x,
- log(~x+i*~y) =>
- log(sqrt(x*x+y*y))+i*atan(y/sqrt(x*x+y*y)+i*x/(sqrt(x*x+y*y))),% when
- %repart(x)=x and repart(y)=y,
- log(~x-i*~y) =>
- log(sqrt(x*x+y*y))-i*atan(y/(sqrt(x*x+y*y))+i*(x/(sqrt(x*x+y*y)))), % when
- % repart(x)=x and repart(y)=y,
- log(~x/~y) => log(x)-log(y), %when repart(y)=y,
- log(sqrt ~x) => (log x)/2,
- log(-1) => i*pi,
- log(-i) => -i*pi/2,
- log(i) => i*pi/2,
- log(-~x) => i*pi+log(x), % when repart(x)=x and numberp x and x>0,
- log(-i*~x) => -i*pi/2+log(x),
- %when repart(x)=x and numberp x and x>0,
- log(i*~x) => i*pi/2 +log(x) %when repart(x)=x and numberp x and x>0
- }$
- >>;
- %algebraic let logcomplex;
-
- %letrules logcomplex
- symbolic procedure evalplus(a,b);
- if numberp a and numberp b then a+b
- else prepsq simp!* aeval {'plus,a,b};
- procedure my_plus(a,b); lisp evalplus(a,b);
- symbolic procedure evalmax(a,b);
- if numberp a and numberp b then max(a,b)
- else if evalgreaterp(a,b) then a else b;
- procedure my_max(a,b); lisp evalmax(a,b);
- %remove(log_sum(alpha,alpha^2+alpha+1,0,alpha*log(alpha*2+x*alpha))+log(1+x));
- symbolic procedure convert(exp);
- begin scalar temp,solution, answer;
- if(freeof(exp,'log_sum)) then return exp else
- <<
- if(null exp) then return nil else
- <<
- if(car exp='log_sum) then
- <<
- temp:=caddr exp;
- if(not freeof(temp,'beta)) then
- <<
- temp:=subeval(list (list('equal,'beta,'alpha), temp));
- exp:=subeval(list (list('equal,'beta,'alpha),exp));
- >>;
- temp:=reval temp; exp:=reval exp;
- %temp:=sub(beta=alpha,temp) % so temp now depends on alpha
- if(deg(temp,'alpha))>2 then
- << %write "degree of", reval exp, " is >2";
- rederr "cannot convert to radicals, degree > 2";
- >>
- else
- <<
- % temp is of the form alpha^2+alpha+1 or something similar
- if(deg(temp,'alpha)=2) then % solve the quadratic eqn, obtain
- % radicals, and substitute
- << %temp:=reval temp
- solution:= algebraic solve(temp=0,alpha);
- write reval cadr solution;
- %now have a solution list, with two elements
- answer:=subeval(list (reval cadr solution, algebraic reval part(exp,4)));
- answer:=list('plus, answer,subeval(list (reval caddr solution,
- algebraic reval part(exp,4))));
- %answer:=car answer;
- answer:=reval answer;
- >>
- >>
- >>
- else <<
- if null cdr exp then return convert(car exp) else
- return convert (cdr exp);
- >>
- >>
- >>;
- return answer;
- end;
- procedure conv(exp); lisp convert(exp);
- %conv(log(x+1)+log_sum(alpha,alpha^2+alpha-1,0,alpha*log(alpha*x^2+alpha*x-1),x%));
- % procedure to separate real and imaginary parts in a log sum expression
- symbolic procedure separate_real(exp);
- begin scalar re, im, ans;
- re:=algebraic repart(exp);
- im:=algebraic impart(exp);
- ans:= 'list.list(re,im);
- ans:=reval ans;
- return ans;
- end;
- procedure sep(exp); lisp separate_real(exp);
- % input an expression with complex logs, output real arctangents
- symbolic procedure convert_log(exp,var);
- begin scalar sepp,re,im, answer;
-
- algebraic repart(var):=var; algebraic impart(var):=0;
- if(car exp='log) then <<
- sepp:=separate_real(exp); %now have a list of re and im parts
- % can pass these to logtoatan function now
- re:=car exp; im:=cadr exp;
- answer:=logtotan1(re,im,var);
- return answer;
- >> else nil;
- end;
- procedure convertlog(exp,var); lisp convert_log(exp,var);
- % now need an assume real facility, so extract terms dependent on i only
- %
- % This algorithm transforms some complex logarithmic expressions to real
- % arctangents.
- %
- % the algorithm apppears in Manuel Bronsteins book Symbolic Integration I :
- % Transendental Functions, published by Springer Verlag, 1997
- %
- % Given a field K of characteristic 0 such that sqrt(-1) is not in K and A,
- % B are in K[x] with B neq 0, this returns a sum f of real arctangents of
- % polynomials in K[x] such that
- %
- % df = d (A+i*B)
- % -- -- i* log ------
- % dx dx (A-i*B)
- %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- algebraic;
- expr procedure logtoAtan(exp1,exp2,x);
- begin scalar D,C,G, temp, rem;
- rem:=pseudorem(exp1,exp2,x);
- if(part(rem,1)=0) then return (2*atan(exp1/exp2))
- %if(numberp(exp1/exp2)) then return (2*atan(exp1/exp2))
- else <<
- if(deg(exp1,x)<deg(exp2,x)) then return logtoAtan(-exp2,exp1,x)
- else <<
- temp:=gcd_ex(exp2,-exp1,x);
- D:=part(temp,1);
- C:=part(temp,2);
- G:=exp2*D-exp1*C;
- return(2*atan((exp1*D+exp2*C)/G)+ logtoAtan(D,C,x));
- >>;
- >>;
- end;
- %log_sum(alpha,alpha^2+alpha+1,0,alpha*log(alpha*2+x*alpha),x);
- %trst convert;
- %conv(ws);
- %conv(log_sum(beta,beta^2+beta-4,0,beta*log(beta*x^2+beta^2+1),x));
- %------------------------------------------------------------------------------
- end;
|