Application Center - Maplesoft

App Preview:

Lesson 8: Exact Equations

You can switch back to the summary page by clicking here.

Learn about Maple
Download Application


Lesson 8 -- Exact Equations

Prof. Douglas B. Meade

Industrial Mathematics Institute

Department of Mathematics

University of South Carolina

Columbia, SC 29208



Copyright  2001  by Douglas B. Meade

All rights reserved



Outline of Lesson 8

8.A Basic Theory

                8.A-1 Example 1

8.B Integrating Factors

                8.B-1 Example 2



> restart;

> with( DEtools ):

> with( plots ):

Warning, the name changecoords has been redefined


8.A Basic Theory

The general form for a first-order exact differential equation is

> gen_exact_ode := P(x,y(x)) + Q(x,y(x))*diff(y(x),x) = 0;

gen_exact_ode := P(x, y(x))+Q(x, y(x))*(diff(y(x), x)) = 0


where the functions P(x, y) and Q(x, y) satisfy the conditions

P(x, y) = diff(F(x, y), x)

Q(x, y) = diff(F(x, y), y)

for some function F(x, y) .  At any point ``(x, y) where diff(F(x, y), y) <> 0 , the equation F(x, y) = c , where c is a constant, implicitly defines the function y(x) .  Such curves are called level curves, and are the curves in the xy -plane above which the surface z = F(x, y) maintains the constant height c .

If the function y(x) is so defined implicitly by the equation F(x, y) = c , then implicit differentiation gives

d/dt F(x, y(x)) = F[x]+F[y] `y'`(x)

where subscripts denote partial derivatives.  Now this equation is clearly equivalent to the differential equation, namely,

P(x, y)+Q(x, y)*``(dy/dx) = 0

Thus, solving this exact differential equation amounts to finding the exact "antiderivative," the function F(x, y) whose exact (or total) derivative is just the ODE itself.  The level curves y(x) defined implicitly by F(x, y) = c are the solutions of the exact differential equation.

To find a condition that guarantees the equation

P(x, y)+Q(x, y)*``(dy/dx) = 0

is exact, consider an arbitrary function F(x, y) whose level curves are defined by the equation

> level_curve := F(x,y(x)) = C;

level_curve := F(x, y(x)) = C


for some constant C .  If the function F(x, y) satisfies the the ODE, then the difference of the total derivative of F(x, y) and the ODE itself should be zero.  Thus, the condition for the equation to be exact is

> condition_to_be_exact := collect( diff( lhs(level_curve), x ) - lhs( gen_exact_ode ) = 0, diff(y(x),x) );

condition_to_be_exact := (D[2](F)(x, y(x))-Q(x, y(x)))*(diff(y(x), x))+D[1](F)(x, y(x))-P(x, y(x)) = 0


Careful consideration of this equation shows that it is satisfied when

> condition1 := isolate( eval( condition_to_be_exact, diff(y(x),x)=0 ), F );

> condition2 := isolate( coeff( lhs(condition_to_be_exact), diff(y(x),x) ) = 0, F );

condition1 := D[1](F)(x, y(x)) = P(x, y(x))

condition2 := D[2](F)(x, y(x)) = Q(x, y(x))


That is, when

Diff(F, x) = P and Diff(F, y) = Q .

For arbitrary pairs of functions P and Q, this condition will not be satisfied. However, assuming the function F has continuous second derivatives and the functions P and Q have continuous first derivatives, the equivalence of the mixed second derivatives of F, namely,

> equiv_of_mixed_deriv := D[1](D[2](F)(x,y(x))) = D[2](D[1](F)(x,y(x)));

equiv_of_mixed_deriv := D[1](D[2](F)(x, y(x))) = D[2](D[1](F)(x, y(x)))


combines with the previous argument

> q1 := D[2](condition1);

> q2 := D[1](condition2);

q1 := D[2](D[1](F)(x, y(x))) = D[2](P(x, y(x)))

q2 := D[1](D[2](F)(x, y(x))) = D[1](Q(x, y(x)))


to provide necessary and sufficient conditions for an exact equation.  This condition is

> eval( equiv_of_mixed_deriv, [ D[2](condition1), D[1](condition2) ] );

D[1](Q(x, y(x))) = D[2](P(x, y(x)))


that is,

> nec_and_suff_condition := (P,Q) -> diff( Q(x,y), x ) = diff( P(x,y), y ):

> nec_and_suff_condition(P,Q);

diff(Q(x, y), x) = diff(P(x, y), y)


8.A-1 Example 1

Consider the differential equation

> ode := exp(y(x)) + (x*exp(y(x))+cos(y(x))) * diff(y(x),x) = 0;

ode := exp(y(x))+(x*exp(y(x))+cos(y(x)))*(diff(y(x), x)) = 0


To check if this ODE is exact, identify the coefficients for the general form

> P := unapply( eval( lhs(ode), [diff(y(x),x)=0, y(x)=y] ), (x,y) ):

> Q := unapply( eval( coeff(lhs(ode),diff(y(x),x)), y(x)=y ), (x,y) ):
'P'(x,y) = P(x,y);

'Q'(x,y) = Q(x,y);

P(x, y) = exp(y)

Q(x, y) = x*exp(y)+cos(y)


and check the necessary and sufficient condition for exactness:

> nec_and_suff_condition(P,Q);

exp(y) = exp(y)


Since this is an exact equation, we construct the solution in the form F(x, y) = C where

 Diff(F(x, y), x) = P(x, y)


Diff(F(x, y), y) = Q(x, y)

The first of these is satisfied when

> q1 := F(x,y) = int( P(x,y), x ) + g(y);

q1 := F(x, y) = x*exp(y)+g(y)


To satisfy the second condition requires

> q2 := diff( rhs(q1), y ) - Q(x,y) = 0;

q2 := (diff(g(y), y))-cos(y) = 0


Thus, integrating both sides and isolating g(y) gives

> q3 := isolate( map( int, q2, y ), g(y) );

q3 := g(y) = sin(y)


and so the function F(x, y) is

> soln_F := eval( rhs(q1), q3 );

soln_F := x*exp(y)+sin(y)


and the implicit solution of the differential equation is

> soln := soln_F = C;

soln := x*exp(y)+sin(y) = C


A quick pause to check that this solution does satisfy the differential equation reveals

> odetest( eval(soln,y=y(x)), ode );



The function F is also called a first integral of the ODE. The Maple command firint , from the DEtools package, can be used to express the solution of an exact ODE in terms of its first integral. For example,

> firint( ode );

x*exp(y(x))+sin(y(x))+_C1 = 0


Note that essentially the same solution is returned with either of the following single commands

> exactsol( ode, y(x) );

> dsolve( ode, y(x), [exact] );

{x*exp(y(x))+sin(y(x))+_C1 = 0}

x*exp(y(x))+sin(y(x))+_C1 = 0


The even simpler command

> infolevel[dsolve] := 3:

> dsolve( ode, y(x) );

> infolevel[dsolve] := 0:

`Methods for first order ODEs:`
`--- Trying classification methods ---`

`trying a quadrature`

`trying 1st order linear`

`trying Bernoulli`

`trying separable`

`trying inverse linear`

`<- 1st order linear successful`

`<- inverse linear successful`

x+exp(-y(x))*sin(y(x))-exp(-y(x))*_C1 = 0


returns an equivalent, but different, solution. This is because Maple is able to find several classifications for this example

> odeadvisor( ode );

[[_1st_order, _with_exponential_symmetries], _exact]


and uses a different solution method.


8.B Integrating Factors

Most first-order ODEs are not exact. Some of these ODEs can be made exact by multiplying the ODE by an appropriate function so that the new ODE is exact. The integrating factor, mu(x, y) , must be chosen so that the necessary and sufficient condition is satisfied by the coefficients of the ODE after multiplication by mu(x, y) :

Applying the necessary and sufficient condition for exactness to the ODE

P(x, y(x))+Q(x, y(x))*(diff(y(x), x)) = 0

leads to

> unassign('P','Q','mu');

> nec_and_suff_condition( mu*P, mu*Q );

(diff(mu(x, y), x))*Q(x, y)+mu(x, y)*(diff(Q(x, y), x)) = (diff(mu(x, y), y))*P(x, y)+mu(x, y)*(diff(P(x, y), y))


This is a partial differential equation, but there are numerous cases where the determination of the integrating factor can be completed under the assumption that mu is a function of either x or y , but not both. If at least one of Diff(Q, x) and  Diff(P, y) is zero, an integrating factor for the original ODE can be found by a process illustrated in the following example.


8.B-1 Example 2

As an example, consider the following ODE,

> ode2 := P(x,y(x)) + Q(x,y(x)) * diff( y(x), x ) = 0;

ode2 := P(x, y(x))+Q(x, y(x))*(diff(y(x), x)) = 0


for which the coefficients P(x, y) and Q(x, y) are

> P := (x,y) -> x*y-2:

> Q := (x,y) -> x^2-x*y:
'P'(x,y) = P(x,y);

'Q'(x,y) = Q(x,y);

P(x, y) = y*x-2

Q(x, y) = x^2-y*x


That this equation is not exact can be seen from

> nec_and_suff_condition( P,Q );

2*x-y = x


or from

> odeadvisor( ode2, [exact] );



An integrating factor, if one exists, must satisfy the partial differential equation

> mu_pde := nec_and_suff_condition( mu*P, mu*Q );

mu_pde := (diff(mu(x, y), x))*(x^2-y*x)+mu(x, y)*(2*x-y) = (diff(mu(x, y), y))*(y*x-2)+mu(x, y)*x


With a little inspection, it can be seen that this PDE simplifies to a linear ODE when the integrating factor is assumed to be independent of y .  The result of this assumption is

> mu_ode := eval( mu_pde, mu(x,y)=mu(x) );

mu_ode := (diff(mu(x), x))*(x^2-y*x)+mu(x)*(2*x-y) = mu(x)*x


or better still,

> mu_ode2 := simplify( isolate( mu_ode, diff(mu(x),x) ) );

mu_ode2 := diff(mu(x), x) = -mu(x)/x


The general solution to this separable (and linear) ODE is found to be

> mu_sol := dsolve( mu_ode2, mu(x) );

mu_sol := mu(x) = _C1/x


Since any (non-trivial) solution can be used as an integrating factor, choose _C1=1 and define

> mu := unapply( eval( rhs(mu_sol), _C1=1 ), x );

mu := proc (x) options operator, arrow; 1/x end proc


To confirm that this function is an integrating factor for the ODE, apply the necessary and sufficient condition for exactness, obtaining

> simplify( nec_and_suff_condition( mu*P, mu*Q ) );

1 = 1


or use

> odeadvisor( mu(x)*ode2, [exact] );



The Maple command mutest , in the DEtools package, provides an alternate method for checking the validity of an integrating factor for a differential equation:

> mutest( mu(x), ode2 );



The intfactor command, also from the DEtools package, can be used as a black box to find an integrating factor. An integrating factor for this ODE is

> intfactor( ode2 );



The solution to the exact form of the original ODE is

> dsolve( mu(x)*ode2, y(x), [exact], implicit );

y(x)*x-2*ln(x)-1/2*y(x)^2+_C1 = 0


Note that without the optional argument implicit Maple returns the pair of solutions

> dsolve( mu(x)*ode2, y(x), [exact] );

y(x) = x+(x^2-4*ln(x)+2*_C1)^(1/2), y(x) = x-(x^2-4*ln(x)+2*_C1)^(1/2)


The specific solution obtained depends upon the specific initial condition.

The same solutions are also obtained from either of

> exactsol( ode2 );

> dsolve( ode2, y(x), [exact] );

{y(x) = x+(x^2-4*ln(x)+2*_C1)^(1/2), y(x) = x-(x^2-4*ln(x)+2*_C1)^(1/2)}

y(x) = x+(x^2-4*ln(x)+2*_C1)^(1/2), y(x) = x-(x^2-4*ln(x)+2*_C1)^(1/2)


In terms of first integrals, the original ODE is not exact so does not have a first integral

> firint( ode2 );

Error, (in ODEtools/firint) the given ODE is not exact


But, when multiplied by the integrating factor, it has the first integral

> q := firint( mu(x)*ode2 );

q := (x^2*y(x)-1/2*y(x)^2*x)/x-2*ln(x)+_C1 = 0


which simplifies to the implicit solution found above.

> simplify( q );

y(x)*x-2*ln(x)-1/2*y(x)^2+_C1 = 0


[Back to ODE Powertool Table of Contents]