Ask Your Question
1

integration of real functions

asked 2024-11-19 10:58:14 +0100

Antonis gravatar image

Is it possible to integrate real functions? For example, integrating

f=(1+sin(x))/(1-cos(x))
from sage.symbolic.integration.integral import indefinite_integral
indefinite_integral(f, x)

Sage returns:

โˆ’(cos ๐‘ฅ + 1)/ sin ๐‘ฅ + log(cos ๐‘ฅ โˆ’ 1)

Now, this is correct if complex numbers are allowed but as a real function it is not, because of course the cos(x)-1 is non-positive. Is there a way to ask sage to integrate as a real function?

edit retag flag offensive close merge delete

Comments

Welcome to Ask Sage! Thank you for your question!

slelievre gravatar imageslelievre ( 2024-11-19 12:06:04 +0100 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2024-11-20 12:25:00 +0100

Emmanuel Charpentier gravatar image

Different algorithms lead to different expressions :

sage: f(x)=(1+sin(x))/(1-cos(x))
sage: Fm(x)=f(x).integrate(x, algorithm="maxima") ; Fm
x |--> -(cos(x) + 1)/sin(x) + log(cos(x) - 1)
sage: Fg(x)=f(x).integrate(x, algorithm="giac") ; Fg
x |--> -(2*tan(1/2*x) + 1)/tan(1/2*x) - log(tan(1/2*x)^2 + 1) + 2*log(abs(tan(1/2*x)))
sage: Fs(x)=f(x).integrate(x, algorithm="sympy") ; Fs
x |--> -1/tan(1/2*x) - log(tan(1/2*x)^2 + 1) + 2*log(tan(1/2*x))
sage: Ff(x)=f(x).integrate(x, algorithm="fricas") ; Ff
x |--> (log(-1/2*cos(x) + 1/2)*sin(x) - cos(x) - 1)/sin(x)

As you noted, the expression returned by Maxima is never real for $x\in\mathbb{R}$. This is not, by a long range, the first instance of a problematic integration result given by Maxima...

The three other expressions are real and present a pole at $x=0$.

One can check that all four expressions re-derivate to f(x) (I use Wolfram engine's FullSimplify as a shortcut) :

sage: [(h(x).diff(x)-f(x))._mathematica_().FullSimplify().sage() for h in (Fm, Fg, Fs, Ff)]
[0, -Csc(x) + Csc(conjugate(x)), 0, 0]

(The expression given for Fg is null for $x\in\mathbb{R}$).

Plotting the real function to stimulate our intuition :

sage: plot([Fm, Fg, Fs, Ff], (-1, 1), ymin=-10, ymax=10, detect_poles="show", le
....: gend_label=["Fm", "Fg", "Fs", "Ff"], axes=False, frame=True)
verbose 0 (3954: plot.py, generate_plot_points) WARNING: When plotting, failed to evaluate function at 200 points.
verbose 0 (3954: plot.py, generate_plot_points) Last error message: 'Unable to compute f(1.0)'
verbose 0 (3954: plot.py, generate_plot_points) WARNING: When plotting, failed to evaluate function at 100 points.
verbose 0 (3954: plot.py, generate_plot_points) Last error message: 'Unable to compute f(-0.007791788689424723)'
Launched png viewer for Graphics object consisting of 7 graphics primitives

image description

This suggests that Fs and Ff are equal and that Fg differs from them by an integration constant. I haven't been able to check this symbolically, but numerical check does not invalidate it :

sage: plot([lambda u:Fs(u)-Ff(u), lambda u:Fg(u)-Fs(u)], (-1, 1), legend_label=[
....: "Fs-Ff", "Fg-Fs"])
verbose 0 (3954: plot.py, generate_plot_points) WARNING: When plotting, failed to evaluate function at 100 points.
verbose 0 (3954: plot.py, generate_plot_points) Last error message: 'unable to simplify to float approximation'
verbose 0 (3954: plot.py, generate_plot_points) WARNING: When plotting, failed to evaluate function at 100 points.
verbose 0 (3954: plot.py, generate_plot_points) Last error message: 'unable to simplify to float approximation'
Launched png viewer for Graphics object consisting of 2 graphics primitives

image description

FWIW, the Wolfram engine gives yet another expression :

sage: f(x)._mathematica_().Integrate(x)
-((Sin[x/2]*(-2*Cos[x/2]*Hypergeometric2F1[-1/2, 1, 1/2, -Tan[x/2]^2] + 
    (x + 4*Log[Sin[x/2]])*Sin[x/2]))/(-1 + Cos[x]))

which (currently) does not translate automatically to Sage, but can be hand-translated :

sage: FM(x)=-((sin(x/2)(-2cos(x/2)hypergeometric([-1/2, 1],[1/2], -tan(x)^2) ....: + (x+4log(sin(x/2)))*sin(x/2)))/(cos(x)-1))

EDIT : This expression can be simplified by Wolfram engine :

sage: f(x)._mathematica_().Integrate(x).FunctionExpand().sage(locals={("Tan",1):tan})
(2*(arctan(tan(1/2*x))*tan(1/2*x) + 1)*cos(1/2*x) - (x + 4*log(sin(1/2*x)))*sin(1/2*x))*sin(1/2*x)/(cos(x) - 1)

Interestingly, one can coax Maxima to give a (partially) real result, by using the expressions of $\sin{x}$ and $\cos{x}$ in terms of $\tan{x/2}$ :

sage: Ss=(sin(2*x)==2*tan(x)/(1+tan(x)^2)).subs(x==x/2)
sage: Sc=(cos(2*x)==(1-tan(x)^2)/(1+tan(x)^2)).subs(x=x/2)
sage: # Check my distant memories
sage: bool(Ss.subs(x==2*x))
True
sage: bool(Sc.subs(x==2*x))
True
sage: f(x).subs(Ss).subs(Sc).integrate(x, algorithm="maxima")
-1/tan(1/2*x) - log(tan(1/2*x)^2 + 1) + 2*log(tan(1/2*x))

One notes that this expression is real only for $\tan{x/2}>0$.

HTH,

edit flag offensive delete link more

Comments

Wow! I did not expect such a detailed answer. Thank you so much. I have to study it.

Antonis gravatar imageAntonis ( 2024-11-20 14:47:41 +0100 )edit

Maxima can give a solution valid for all x with nonzero tan(x/2):

sage: maxima_console()

(%i1) logabs:true$

(%i2) 'integrate((1+sin(x))/(1-cos(x)),x)$

(%i3) changevar(%,tan(x/2)-t,t,x)$

(%i4) ev(%,integrate)$

(%i5) %,t=tan(x/2);

(%o5)          

                1                   x  2              !     x    !
        -   (-------) -   log(tan (---) + 1) + 2 log( !tan(---)  !)
               x                    2                 !     2    !
          tan(---)
               2

(Notice the absolute value on the last tan(x/2) )

Or simply:

(%i1) logabs:true$

(%i2) integrate((1+sin(x))/(1-cos(x)),x);
                                          cos(x) + 1
(%o2)                    log(1 - cos(x)) - ----------
                                            sin(x)
achrzesz gravatar imageachrzesz ( 2024-11-20 15:23:37 +0100 )edit

@achrzesz : your excellent comment should be an alternative answer for the benefit of future ask.sagemath.org (per)users...

Your solution can be implemented entirely rom Sage (i. e. without interaction to a new maxima instance) as follows :

sage: ola=maxima_calculus.get("logabs")
sage: maxima_calculus.set("logabs","true")
sage: foo=integrate((1+sin(x))/(1-cos(x)), x, algorithm="maxima")
sage: maxima_calculus.set("logabs",ola)
sage: foo
-(cos(x) + 1)/sin(x) + log(-cos(x) + 1)

HTH,

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2024-11-20 23:57:47 +0100 )edit

Is this code minimal? Because I tried:

sage: maxima_calculus.set("logabs","true")
sage: integrate((1+sin(x))/(1-cos(x)), x)

and it works the same.

Antonis gravatar imageAntonis ( 2024-11-21 10:53:51 +0100 )edit

Is this code minimal?

Yes : You don't change an important global variable for a single computation purpose without restoring its default value afterwards. The default values of these variables are an essential part of Sage's interface to Maxima...

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2024-11-21 11:37:32 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2024-11-19 10:58:14 +0100

Seen: 135 times

Last updated: Nov 20