#set document(title: "1.3 Separable Equations", author: "Jiří Lebl") #set page(width: 8.5in, height: auto, margin: 1in) #import "@preview/cetz:0.5.2" #set text(font: ("STIX Two Text", "Libertinus Serif", "New Computer Modern"), size: 10.5pt, lang: "en") #show math.equation: set text(font: ("STIX Two Math", "New Computer Modern Math")) #set par(justify: true, leading: 0.62em, spacing: 0.9em) #set enum(spacing: 1.1em) // room between list items so tall inline fractions don't collide #set list(spacing: 1.1em) #set table(stroke: 0.5pt + rgb("#c7ccd3")) #let BLUE = rgb("#183B6F") // brand navy — section bars + example/solution labels (white on navy 11.09:1) #let ORANGE = rgb("#A94509") // brand primary-700 — AA-safe deep orange for TEXT (5.93:1 on white; raw brand #F37021 is 2.94:1 and must never carry text) #let RED = rgb("#DC2626") // brand error-600 #let GREEN = rgb("#059669") // brand success-600 (decoration only; small green text uses green-text #007942) #show heading.where(level: 1): it => block(width: 100%, above: 0pt, below: 16pt, fill: gradient.linear(BLUE, rgb("#2C5AA0")), inset: (x: 14pt, y: 12pt), radius: 3pt, text(fill: white, weight: "bold", size: 19pt, it.body)) #show heading.where(level: 2): it => block(width: 100%, above: 18pt, below: 10pt, fill: BLUE, inset: (x: 10pt, y: 6pt), radius: 2pt, text(fill: white, weight: "bold", size: 12pt, it.body)) #show heading.where(level: 3): it => text(fill: ORANGE, weight: "bold", size: 12.5pt, it.body) #show heading.where(level: 4): it => text(fill: BLUE, weight: "bold", size: 10.5pt, it.body) #let examplebox(label, title, body) = block(width: 100%, breakable: true, fill: rgb("#EFF1F5"), stroke: 0.5pt + rgb("#CFDDF0"), radius: 4pt, inset: 10pt, above: 12pt, below: 12pt)[ #block(below: 6pt)[#box(fill: BLUE, inset: (x: 6pt, y: 2pt), radius: 2pt, text(fill: white, weight: "bold", size: 8.5pt, label)) #h(0.4em) #strong[#title]] #body] // rail = decorative left rule (raw brand token); labelcolor = AA-safe label text shade #let notebox(label, rail, labelcolor, tint, body) = block(width: 100%, breakable: true, fill: tint, stroke: (left: 3pt + rail), inset: (left: 10pt, rest: 8pt), radius: (right: 4pt), above: 11pt, below: 11pt)[ #text(fill: labelcolor, weight: "bold", size: 7.5pt, tracking: 0.5pt)[#upper(label)] #linebreak() #body] #let solutionbox(body) = block(above: 4pt, below: 8pt)[ #text(fill: BLUE, weight: "bold", size: 8.5pt)[Solution] #linebreak() #body] #let figph(msg) = block(width: 100%, height: 60pt, fill: rgb("#f6f7f9"), stroke: (paint: rgb("#c7ccd3"), dash: "dashed"), radius: 4pt, inset: 10pt)[ #align(center + horizon, text(fill: rgb("#889"), style: "italic", size: 9pt, msg))] // Standardize inlined figure sizes: measure the natural CeTZ canvas, then scale to a // consistent envelope (aspect-aware; see build_typst.py FIG_* constants). Unlike the // print preamble, dimensions are FLOORED: in an editor a user can trim a figure to a // degenerate 1-D shape (a bare line), and w/h or tw/w would then divide by zero. #let _STD_W = 3.5 #let _WIDE_W = 5.6 #let _MAX_H = 3.4 #let _ASPECT_WIDE = 2.2 #let _UPSCALE_MAX = 1.15 #let stdfig(body) = context { let m = measure(body) let w = calc.max(m.width / 1in, 0.01) let h = calc.max(m.height / 1in, 0.01) let tw = if w / h > _ASPECT_WIDE { _WIDE_W } else { _STD_W } let s = calc.min(tw / w, _MAX_H / h, _UPSCALE_MAX) align(center, box(scale(x: s * 100%, y: s * 100%, reflow: true, body))) } #show figure: set block(breakable: false) #set figure(gap: 8pt) #show figure.caption: set text(size: 8.5pt, fill: rgb("#555")) == 1.3#h(0.6em)Separable Equations When a differential equation is of the form #math.equation(block: false, alt: "y prime equals f open parenthesis x close parenthesis")[$y^(′) = f ( x )$], we can just integrate: #math.equation(block: false, alt: "y equals ∫ f open parenthesis x close parenthesis d x plus C")[$y = ∫ f ( x ) d x + C$]. Unfortunately this method no longer works for the general form of the equation #math.equation(block: false, alt: "y prime equals f open parenthesis x , y close parenthesis")[$y^(′) = f ( x , y )$]. Integrating both sides yields #math.equation(block: true, alt: "y equals ∫ f open parenthesis x , y close parenthesis d x plus C")[$y = ∫ f ( x , y ) d x + C$] Notice the dependence on #math.equation(block: false, alt: "y")[$y$] in the integral. === Separable equations Let us suppose that the equation is #emph[separable]. That is, let us consider #math.equation(block: true, alt: "y prime equals f open parenthesis x close parenthesis g open parenthesis y close parenthesis ,")[$y^(′) = f ( x ) g ( y ) ,$] for some functions #math.equation(block: false, alt: "f open parenthesis x close parenthesis")[$f ( x )$] and #math.equation(block: false, alt: "g open parenthesis y close parenthesis")[$g ( y )$]. Let us write the equation in the Leibniz notation #math.equation(block: true, alt: "the fraction d y over d x equals f open parenthesis x close parenthesis g open parenthesis y close parenthesis")[$frac(d y, d x) = f ( x ) g ( y )$] Then we rewrite the equation as #math.equation(block: true, alt: "the fraction d y over g open parenthesis y close parenthesis equals f open parenthesis x close parenthesis d x")[$frac(d y, g ( y )) = f ( x ) d x$] Now both sides look like something we can integrate. We obtain #math.equation(block: true, alt: "∫ the fraction d y over g open parenthesis y close parenthesis equals ∫ f open parenthesis x close parenthesis d x plus C")[$∫ frac(d y, g ( y )) = ∫ f ( x ) d x + C$] If we can find closed form expressions for these two integrals, we can, perhaps, solve for #math.equation(block: false, alt: "y .")[$y .$] #examplebox("Example 1")[][ Take the equation #math.equation(block: true, alt: "y prime equals x y")[$y^(′) = x y$] First note that #math.equation(block: false, alt: "y equals 0")[$y = 0$] is a solution, so assume #math.equation(block: false, alt: "y not equal to 0")[$y ≠ 0$] from now on, so that we can divide by #math.equation(block: false, alt: "y")[$y$]. Write the equation as #math.equation(block: false, alt: "the fraction d y over d x equals x y ,")[$frac(d y, d x) = x y ,$] then #math.equation(block: true, alt: "∫ the fraction d y over y equals ∫ x d x plus C .")[$∫ frac(d y, y) = ∫ x d x + C .$] We compute the antiderivatives to get #math.equation(block: true, alt: "ln | y | equals the fraction x squared over 2 plus C")[$ln | y | = frac(x^(2), 2) + C$] Or #math.equation(block: true, alt: "| y | equals e to the power the fraction x squared over 2 plus C equals e to the power the fraction x squared over 2 e to the power C equals D e to the power the fraction x squared over 2")[$| y | = e^(frac(x^(2), 2) + C) = e^(frac(x^(2), 2)) e^(C) = D e^(frac(x^(2), 2))$] where #math.equation(block: false, alt: "D greater than 0")[$D > 0$] is some constant. Because #math.equation(block: false, alt: "y equals 0")[$y = 0$] is a solution and because of the absolute value we actually can write: #math.equation(block: true, alt: "y equals D e to the power the fraction x squared over 2")[$y = D e^(frac(x^(2), 2))$] for any number #math.equation(block: false, alt: "D")[$D$] (including zero or negative). We check: #math.equation(block: true, alt: "y prime equals D x e to the power the fraction x squared over 2 equals x open parenthesis D e to the power the fraction x squared over 2 close parenthesis equals x y")[$y^(′) = D x e^(frac(x^(2), 2)) = x ( D e^(frac(x^(2), 2)) ) = x y$] Yay! We should be a little bit more careful with this method. You may be worried that we were integrating in two different variables. We seemingly did a different operation to each side. Let us work through this method more rigorously. Take #math.equation(block: true, alt: "the fraction d y over d x equals f open parenthesis x close parenthesis g open parenthesis y close parenthesis")[$frac(d y, d x) = f ( x ) g ( y )$] We rewrite the equation as follows. Note that #math.equation(block: false, alt: "y equals y open parenthesis x close parenthesis")[$y = y ( x )$] is a function of #math.equation(block: false, alt: "x")[$x$] and so is #math.equation(block: false, alt: "the fraction d y over d x !")[$frac(d y, d x) !$] #math.equation(block: true, alt: "the fraction 1 over g open parenthesis y close parenthesis the fraction d y over d x equals f open parenthesis x close parenthesis")[$frac(1, g ( y )) frac(d y, d x) = f ( x )$] We integrate both sides with respect to #math.equation(block: false, alt: "x .")[$x .$] #math.equation(block: true, alt: "∫ the fraction 1 over g open parenthesis y close parenthesis the fraction d y over d x d x equals ∫ f open parenthesis x close parenthesis d x plus C")[$∫ frac(1, g ( y )) frac(d y, d x) d x = ∫ f ( x ) d x + C$] We use the change of variables formula (substitution) on the left hand side: #math.equation(block: true, alt: "∫ the fraction 1 over g open parenthesis y close parenthesis d y equals ∫ f open parenthesis x close parenthesis d x plus C")[$∫ frac(1, g ( y )) d y = ∫ f ( x ) d x + C$] And we are done. ] === Implicit solutions It is clear that we might sometimes get stuck even if we can do the integration. For example, take the separable equation #math.equation(block: true, alt: "y prime equals the fraction x y over y squared plus 1")[$y^(′) = frac(x y, y^(2) + 1)$] We separate variables, #math.equation(block: true, alt: "the fraction y squared plus 1 over y d y equals open parenthesis y plus the fraction 1 over y close parenthesis d y equals x d x")[$frac(y^(2) + 1, y) d y = ( y + frac(1, y) ) d y = x d x$] We integrate to get #math.equation(block: true, alt: "the fraction y squared over 2 plus l n | y | equals the fraction x squared over 2 plus C")[$frac(y^(2), 2) + l n | y | = frac(x^(2), 2) + C$] or perhaps the easier looking expression (where #math.equation(block: false, alt: "D equals 2 C")[$D = 2 C$]) #math.equation(block: true, alt: "y squared plus 2 l n | y | equals x squared plus D")[$y^(2) + 2 l n | y | = x^(2) + D$] It is not easy to find the solution explicitly as it is hard to solve for #math.equation(block: false, alt: "y")[$y$]. We, therefore, leave the solution in this form and call it an #emph[implicit solution]. It is still easy to check that an implicit solution satisfies the differential equation. In this case, we differentiate with respect to #math.equation(block: false, alt: "x")[$x$], and remember that #math.equation(block: false, alt: "y")[$y$] is a function of #math.equation(block: false, alt: "x")[$x$], to get #math.equation(block: true, alt: "y prime open parenthesis 2 y plus the fraction 2 over y close parenthesis equals 2 x")[$y^(′) ( 2 y + frac(2, y) ) = 2 x$] Multiply both sides by #math.equation(block: false, alt: "y")[$y$] and divide by #math.equation(block: false, alt: "2 open parenthesis y squared plus 1 close parenthesis")[$2 ( y^(2) + 1 )$] and you will get exactly the differential equation. We leave this computation to the reader. If you have an implicit solution, and you want to compute values for #math.equation(block: false, alt: "y")[$y$], you might have to be tricky. You might get multiple solutions #math.equation(block: false, alt: "y")[$y$] for each #math.equation(block: false, alt: "x")[$x$], so you have to pick one. Sometimes you can graph #math.equation(block: false, alt: "x")[$x$] as a function of #math.equation(block: false, alt: "y")[$y$], and then flip your paper. Sometimes you have to do more. Computers are also good at some of these tricks. More advanced mathematical software usually has some way of plotting solutions to implicit equations. For example, for #math.equation(block: false, alt: "C equals 0")[$C = 0$] if you plot all the points #math.equation(block: false, alt: "open parenthesis x , y close parenthesis")[$( x , y )$] that are solutions to #math.equation(block: false, alt: "y squared plus 2 ln | y | equals x squared")[$y^(2) + 2 ln | y | = x^(2)$], you find the two curves in Figure #math.equation(block: false, alt: "1")[$1$]. This is not quite a graph of a function. For each #math.equation(block: false, alt: "x")[$x$] there are two choices of #math.equation(block: false, alt: "y")[$y$]. To find a function you would have to pick one of these two curves. You pick the one that satisfies your initial condition if you have one. For example, the top curve satisfies the condition #math.equation(block: false, alt: "y open parenthesis 1 close parenthesis equals 1")[$y ( 1 ) = 1$]. So for each #math.equation(block: false, alt: "C")[$C$] we really got two solutions. As you can see, computing values from an implicit solution can be somewhat tricky. But sometimes, an implicit solution is the best we can do. #figure(figph[Plot of two mirror-image branches on axes from -5 to 5, a blue one above the horizontal axis bottoming at about 0.7 and a green one below peaking at about -0.7, opening outward like a hyperbola.], alt: "Plot of two mirror-image branches on axes from -5 to 5, a blue one above the horizontal axis bottoming at about 0.7 and a green one below peaking at about -0.7, opening outward like a hyperbola.", caption: [Figure #math.equation(block: false, alt: "1")[$1$]: The implicit solution #math.equation(block: false, alt: "y squared plus 2 ln | y | equals x squared")[$y^(2) + 2 ln | y | = x^(2)$] to #math.equation(block: false, alt: "y prime equals the fraction x y over y squared plus 1")[$y^(′) = frac(x y, y^(2) + 1)$].]) The equation above also has the solution #math.equation(block: false, alt: "y equals 0")[$y = 0$]. So the general solution is #math.equation(block: true, alt: "y squared plus 2 ln | y | equals x squared plus C , and y equals 0 .")[$y^(2) + 2 ln | y | = x^(2) + C , #h(2em) "and" #h(2em) y = 0 .$] These outlying solutions such as #math.equation(block: false, alt: "y equals 0")[$y = 0$] are sometimes called #emph[singular solutions]. #examplebox("Example 2")[][ Solve #math.equation(block: false, alt: "x squared y prime equals 1 minus x squared plus y squared minus x squared y squared")[$x^(2) y^(′) = 1 − x^(2) + y^(2) − x^(2) y^(2)$], #math.equation(block: false, alt: "y open parenthesis 1 close parenthesis equals 0 .")[$y ( 1 ) = 0 .$] #solutionbox[ First factor the right hand side to obtain #math.equation(block: true, alt: "x squared y prime equals open parenthesis 1 minus x squared close parenthesis open parenthesis 1 plus y squared close parenthesis")[$x^(2) y^(′) = ( 1 − x^(2) ) ( 1 + y^(2) )$] Separate variables, integrate, and solve for #math.equation(block: false, alt: "y")[$y$] #math.equation(block: true, alt: "the fraction y prime over 1 plus y squared equals the fraction 1 minus x squared over x squared ,; the fraction y prime over 1 plus y squared equals the fraction 1 over x squared minus 1 ,; arctan open parenthesis y close parenthesis equals minus the fraction 1 over x squared minus x plus C ,; y equals tan open parenthesis minus the fraction 1 over x minus x plus C close parenthesis")[$frac(y^(′), 1 + y^(2)) = frac(1 − x^(2), x^(2)) , \ frac(y^(′), 1 + y^(2)) = frac(1, x^(2)) − 1 , \ "arctan" ( y ) = − frac(1, x^(2)) − x + C , \ y = tan ( − frac(1, x) − x + C )$] Solve for the initial condition, #math.equation(block: false, alt: "0 equals tan open parenthesis minus 2 plus C close parenthesis")[$0 = tan ( − 2 + C )$] to get #math.equation(block: false, alt: "C equals 2")[$C = 2$] (or #math.equation(block: false, alt: "C equals 2 plus π")[$C = 2 + π$], or #math.equation(block: false, alt: "C equals 2 plus 2 π")[$C = 2 + 2 π$], etc.). The particular solution we seek is, therefore, #math.equation(block: true, alt: "y equals tan open parenthesis the fraction minus 1 over x minus x plus 2 close parenthesis .")[$y = tan ( frac(− 1, x) − x + 2 ) .$] ] ] #examplebox("Example 3")[][ Bob made a cup of coffee, and Bob likes to drink coffee only once reaches 60 degrees Celsius and will not burn him. Initially at time #math.equation(block: false, alt: "t equals 0")[$t = 0$] minutes, Bob measured the temperature and the coffee was 89 degrees Celsius. One minute later, Bob measured the coffee again and it had 85 degrees. The temperature of the room (the ambient temperature) is 22 degrees. When should Bob start drinking? #solutionbox[ Let #math.equation(block: false, alt: "T")[$T$] be the temperature of the coffee in degrees Celsius, and let #math.equation(block: false, alt: "A")[$A$] be the ambient (room) temperature, also in degrees Celsius. states that the rate at which the temperature of the coffee is changing is proportional to the difference between the ambient temperature and the temperature of the coffee. That is, #math.equation(block: true, alt: "the fraction d T over d t equals k open parenthesis A minus T close parenthesis ,")[$frac(d T, d t) = k ( A − T ) ,$] for some constant #math.equation(block: false, alt: "k")[$k$]. For our setup #math.equation(block: false, alt: "A equals 22")[$A = 22$], #math.equation(block: false, alt: "T open parenthesis 0 close parenthesis equals 89")[$T ( 0 ) = 89$], #math.equation(block: false, alt: "T open parenthesis 1 close parenthesis equals 85")[$T ( 1 ) = 85$]. We separate variables and integrate (let #math.equation(block: false, alt: "C")[$C$] and #math.equation(block: false, alt: "D")[$D$] denote arbitrary constants) #math.equation(block: true, alt: "the fraction 1 over T minus A the fraction d T over d t equals minus k ,; ln open parenthesis T minus A close parenthesis equals minus k t plus C , open parenthesis note that T minus A greater than 0 close parenthesis; T minus A equals D e to the power minus k t ,; T equals A plus D e to the power minus k t")[$frac(1, T − A) frac(d T, d t) = − k , \ ln ( T − A ) = − k t + C , ( "note that" T − A > 0 ) \ T − A = D e^(− k t) , \ T = A + D e^(− k t)$] That is, #math.equation(block: false, alt: "T equals 22 plus D e to the power minus k t")[$T = 22 + D e^(− k t)$]. We plug in the first condition: #math.equation(block: false, alt: "89 equals T open parenthesis 0 close parenthesis equals 22 plus D")[$89 = T ( 0 ) = 22 + D$], and hence #math.equation(block: false, alt: "D equals 67")[$D = 67$]. So #math.equation(block: false, alt: "T equals 22 plus 67 e to the power minus k t")[$T = 22 + 67 e^(− k t)$]. The second condition says #math.equation(block: false, alt: "85 equals T open parenthesis 1 close parenthesis equals 22 plus 67 e to the power minus k")[$85 = T ( 1 ) = 22 + 67 e^(− k)$]. Solving for #math.equation(block: false, alt: "k")[$k$] we get #math.equation(block: false, alt: "k equals minus ln the fraction 85 minus 22 over 67 approximately equals 0.0616")[$k = − ln frac(85 − 22, 67) ≈ 0.0616$]. Now we solve for the time #math.equation(block: false, alt: "t")[$t$] that gives us a temperature of 60 degrees. Namely, we solve #math.equation(block: true, alt: "60 equals 22 plus 67 e to the power minus 0.0616 t")[$60 = 22 + 67 e^(− 0.0616 t)$] to get #math.equation(block: false, alt: "t equals minus the fraction ln the fraction 60 minus 22 over 67 over 0.0616 approximately equals 9.21")[$t = − frac(ln frac(60 − 22, 67), 0.0616) ≈ 9.21$] minutes. So Bob can begin to drink the coffee at just over 9 minutes from the time Bob made it. That is probably about the amount of time it took us to calculate how long it would take. See Figure #math.equation(block: false, alt: "2")[$2$]. #figure(figph[Two plots of the same coffee-cooling curve. Left, over 12.5 minutes: it falls from 89 degrees, hitting 85 at t = 1 and 60 at t = 9.2. Right, over 80 minutes: it decays onto the ambient 22 degrees.], alt: "Two plots of the same coffee-cooling curve. Left, over 12.5 minutes: it falls from 89 degrees, hitting 85 at t = 1 and 60 at t = 9.2. Right, over 80 minutes: it decays onto the ambient 22 degrees.", caption: [Figure #math.equation(block: false, alt: "2")[$2$]: Graphs of the coffee temperature function #math.equation(block: false, alt: "T open parenthesis t close parenthesis")[$T ( t )$]. On the left, horizontal lines are drawn at temperatures #math.equation(block: false, alt: "60")[$60$], #math.equation(block: false, alt: "85")[$85$], and #math.equation(block: false, alt: "89")[$89$]. Vertical lines are drawn at #math.equation(block: false, alt: "t equals 1")[$t = 1$] and #math.equation(block: false, alt: "t equals 9.21")[$t = 9.21$]. Notice that the temperature of the coffee hits #math.equation(block: false, alt: "85")[$85$] at #math.equation(block: false, alt: "t equals 1")[$t = 1$], and #math.equation(block: false, alt: "60")[$60$] at #math.equation(block: false, alt: "t approximately equals 9.21")[$t ≈ 9.21$]. On the right, the graph is over a longer period of time, with a horizontal line at the ambient temperature #math.equation(block: false, alt: "22")[$22$].]) ] ] #examplebox("Example 4")[][ Find the general solution to #math.equation(block: false, alt: "y prime equals the fraction minus x y squared over 3")[$y^(′) = frac(− x y^(2), 3)$] (including singular solutions). #solutionbox[ First note that #math.equation(block: false, alt: "y equals 0")[$y = 0$] is a solution (a singular solution). Now assume that #math.equation(block: false, alt: "y ⧸ equals 0")[$y "⧸" = 0$]. #math.equation(block: true, alt: "minus the fraction 3 over y squared y prime equals x ,; the fraction 3 over y equals the fraction x squared over 2 plus C ,; y equals the fraction 3 over the fraction x squared over 2 plus C equals the fraction 6 over x squared plus 2 C .")[$− frac(3, y^(2)) y^(′) = x , \ frac(3, y) = frac(x^(2), 2) + C , \ y = frac(3, frac(x^(2), 2) + C) = frac(6, x^(2) + 2 C) .$] So the general solution is, #math.equation(block: true, alt: "y equals the fraction 6 over x squared plus 2 C , and y equals 0 .")[$y = frac(6, x^(2) + 2 C) , #h(1em) "and" #h(1em) y = 0 .$] ] ]