Skip to main content

differential equations - Should DSolve always return solution with constant of integration?


Bug introduced in 10.0.0 and fixed in 10.0.2




Clear[y,x];
DSolve[D[y[x], x] - y[x]^2 + y[x]*Sin[x] - Cos[x] == 0, y[x], x,

GeneratedParameters -> C]

or


DSolve[D[y[x], x] - y[x]^2 + y[x]*Sin[x] - Cos[x] == 0, y[x], x]

both return a solution that does not include C[1], the constant of integration.


{{y[x] -> Sin[x]}}

The question is: Should DSolve always return an arbitrary constant? Even though the answer is correct, it is missing C[1] hence this is a particular solution.


If DSolve does not have to generate a constant of integration in the solution of a differential equation, then what caused it not to generate it in this specific case?



Update:


Let me add a solution found by Maple for this, which does include a constant of integration:


Clear[C,y,x];
eq = Derivative[1][y][x] - y[x]^2 + y[x]*Sin[x] - Cos[x] == 0;
eq /. y -> (- Exp[-Cos[#]]/(C[1] + Integrate[ Exp[-Cos[#]], x]) + Sin[#] &);
Simplify[%]
(* True *)

So, the above is a general solution with a constant of integration that solves the same differential equation.



Answer




I think it's a bug.


Tracing


Tracing the evaluation of DSolve as the following:


eq = D[y[x], x] - y[x]^2 + y[x]*Sin[x] - Cos[x] == 0;

traceRes = Trace[DSolve[eq, y[x], x,
GeneratedParameters -> ThisIsForGeneralC],
{TraceInternal -> True,
TraceOff -> _Message}];


and formatting (using the levelIndentFunc function I mentioned here) and exporting the result (it will be around 200 MByte):


Export["[Trace-result] DSolve.txt", levelIndentFunc @ traceRes, "String"]

Searching the "unique" footprint ThisIsForGeneralC we made on purpose, it's not hard to find where the problem comes from.


Analysis


Here, from the trace result we can see, MMA eventually arrives a point like:


DSolve`DSolveFirstOrderODEDump`f = {{{y[x] -> E^Cos[x]*DSolve`DSolveFirstOrderODEDump`const[2] + E^Cos[x]*Integrate[DSolve`DSolveFirstOrderODEDump`const[1]/E^Cos[K[1]], {K[1], 1, x}]}}}
DSolve`DSolveFirstOrderODEDump`f = DSolve`DSolveFirstOrderODEDump`f[[1,1,1,2]]; {DSolve`DSolveFirstOrderODEDump`f, DSolve`DSolveFirstOrderODEDump`g} = {Coefficient[DSolve`DSolveFirstOrderODEDump`f, DSolve`DSolveFirstOrderODEDump`const[1]], Coefficient[DSolve`DSolveFirstOrderODEDump`f, DSolve`DSolveFirstOrderODEDump`const[2]]}; {{y[x] -> -((ThisIsForGeneralC[1]*D[DSolve`DSolveFirstOrderODEDump`f, x] + D[DSolve`DSolveFirstOrderODEDump`g, x])/(DSolve`DSolveFirstOrderODEDump`h*(ThisIsForGeneralC[1]*DSolve`DSolveFirstOrderODEDump`f + DSolve`DSolveFirstOrderODEDump`g)))}}

which is actually



f = {{{y[x] -> E^Cos[x]*const[2] + E^Cos[x]*Integrate[const[1]/E^Cos[K[1]], {K[1], 1, x}]}}}; 
f = f[[1, 1, 1, 2]]

intermedia f


{f, g} = {Coefficient[f, const[1]], Coefficient[f, const[2]]}
{{y[x] -> -((ThisIsForGeneralC[1]*D[f, x] + D[g, x])/(h*(ThisIsForGeneralC[1]*f + g)))}}

final false result


Note the f = Coefficient[f, const[1]] part, which is incorrectly evaluated to 0! That's the one to blame for our issue!


If we replace f with the correct value:



f = E^Cos[x]*Integrate[E^(-Cos[K[1]]), {K[1], 1, x}];

We'll get effectively the same general solution as the one mentioned in OP:


{{y[x] -> -((ThisIsForGeneralC[1]*D[f, x] + D[g, x])/(h*(ThisIsForGeneralC[1]*f + g)))}}

correct result


Some perhaps fixes coming up to my mind include:



  1. Introducing new rule for Integrate (Please compare Integrate[a b[x], {x, 0, 1}] and Integrate[a b[x], x]); Or

  2. Introducing new rule for Coefficient (Maybe not a good idea); Or


  3. Using method other than Coefficient in DSolve.


Comments

Popular posts from this blog

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...