We discuss a simple but effective implementation of a method to separate variables. Separation of variables is a well-known and much-used technique to solve ordinary and partial differential equations.
An expression $F(x,y)$ with the 2 independent variables $x$ and $y$ is separable when $\frac{\partial F}{\partial x}/F = \frac{F_x}{F}$ depends only on $x$, see 1, 2. This is easy to see because if $F$ is separable, it can be written as $F=f(x)\cdot R(y)$. If on both sides we take the derivative with respect to $x$ and divide by $F$ we obtain: $\frac{F_x}{F} = \frac{f_x}{f}$. Since we know that the right-hand side is a function of only x, the left-hand side must be as well. The separated function $f(x)$ can then be found by solving the differential equation:
$|f(x)| = e^{\int(F_x/Fdx)}$ (1)
The function $g(y)$ can be found in a similar way, e.g. by computing:
$|g(y)| = e^{\int(F_y/Fdy)}$, (2)
or by using $g(y) = F(x,y)/f(x)$. Note that the latter approach might be computationally more costly because we have to properly factor out the x-dependency. With the above aproach eqs. (1)-(2), we lose any constant factors, e.g. when $F(x,y)=C \cdot f(x) \cdot g(y)$, we have lost $C$. We can find $C$ during the evaluation of our results: we check that $C = \frac{F(x,y)}{f(x)\cdot g(y)}$ is free of $x$ and $y$.
The maxima implementation for separation of variables has been implemented as follows:
Function: separable(expr,x,y,[options])
If the input expression is a separable function in the independent variables $x$ and $y$, e.g. the expression can be written as $C\cdot f(x)\cdot g(y)$, with $C$ a constant independent of $x,y$, then separable(expr,x,y) returns a list of the form $[f(x), C\cdot g(y)]$, or false when the expression is not separable. When the optional input option 'splitConstant=true is set, the constant factor will be separated as well and a list $[f(x),g(y),C]$ will be returned.
Function: isSeparable(expr,x,y)
If the input expression can be written as a separable expression $f(x)\cdot g(y)$, return true, otherwise return false.
Function: constant_factors(expr,varlist)
If the input expression can be written as $C\cdot F(x,y)$, with $C$ an expression free of the variables in the list varlist, constant_factors will return the constant, or 1.
For some expressions is it not immediately clear from inspection that they are separable. For instance the expression
$e^{x^2+y^2}(\cos(x+y) + \cos(x-y))$
can be rewritten as the product of separable functions:
$e^{x^2} \cdot e^{y^2} \cdot 2\cos(x) \cos(y)$
The maxima implementation of the above algorithm recognizes this without relying on pattern matching to recognize this separation.
In [ ]:
kill(all);batch("~/mathematics/maxima_files/separable.mac");
In [2]:
expr1 : 6*e^(x^2+y^2)*(2*cos(x+y) + 2*cos(x-y));
Out[2]:
In [3]:
separable(expr1,x,y);
Out[3]:
The constant factor is always added to the second term $g(y)$. We can also separate the constant by using the optional command 'splitConstant=true. The constant factor is then added to the list.
In [4]:
expr2 : separable(expr1,x,y,'splitConstant=true);
Out[4]:
We can also call the routine responsible for the separation of the constant factor independently:
In [5]:
constant_factors(5*c*x+5*c,[x]);
Out[5]:
constant_factors also tries to find a shared minus sign. If all terms in an expression of the form a+b+c+d have a minus sign, e.g. expr: -a-b-c-d, then the minus sign will also be factored out.
In [6]:
constant_factors(-5*c*x-5*c,[x]);
Out[6]:
Sometimes we just want to know if an expression is separable or not. We can then skip some internal computations.
In [7]:
isSeparable(x*y,x,y);
Out[7]:
In [8]:
ode:'diff(y,x)=f(x)*g(y);
Out[8]:
In [9]:
S:separable(rhs(ode),x,y);
Out[9]:
In [10]:
sol:integrate(1/S[2],y)=integrate(S[1],x);
Out[10]:
[1] C.P. Viazminsky, On separation of variables, arXiv:math/0210167 (https://arxiv.org/pdf/math/0210167.pdf)
[2] J.A. Cid, A simple method to find out when and ordinary differential equation is separable, International Journal of Mathematical Education in Science and Technology Vol. 40 , Iss. 5,2009 (http://www4.ujaen.es/~angelcid/Archivos/Papers/IJMEST.pdf)