@@ -333,86 +333,86 @@ nsys = convert(NonlinearSystem, rn; remove_conserved = true)
333333# or
334334nprob = NonlinearProblem (rn, u0, p; remove_conserved = true )
335335```
336- ` remake ` 's is currently unable to correctly update all ` u0 ` values when the
337- conserved constant(s), ` Γ ` , are updated. As an example consider the following example
336+ ` remake ` is currently unable to correctly update all ` u0 ` values when the
337+ conserved constant(s), ` Γ ` , are updated. As an example consider the following
338338``` @example faq_remake
339339using Catalyst, NonlinearSolve
340340rn = @reaction_network begin
341- (k1,k2 ), X1 <--> X2
342- (k3,k4 ), X1 + X2 --> 2X3
341+ (k₁,k₂ ), X₁ <--> X₂
342+ (k₃,k₄ ), X₁ + X₂ --> 2X₃
343343end
344- u0 = [:X1 => 1.0, :X2 => 2.0, :X3 => 3.0]
345- ps = [:k1 => 0.1, :k2 => 0.2, :k3 => 0.3, :k4 => 0.4]
344+ u0 = [:X₁ => 1.0, :X₂ => 2.0, :X₃ => 3.0]
345+ ps = [:k₁ => 0.1, :k₂ => 0.2, :k₃ => 0.3, :k₄ => 0.4]
346346nlsys = convert(NonlinearSystem, rn; remove_conserved = true, conseqs_remake_warn = false)
347347nlsys = complete(nlsys)
348348equations(nlsys)
349349```
350350If we generate a ` NonlinearProblem ` from this system the conservation constant,
351- ` Γ[1] ` , is automatically set to ` X1 + X2 + X3 = 6` and the initial values are
351+ ` Γ[1] ` , is automatically set to ` X₁ + X₂ + X₃ = 6` and the initial values are
352352those in ` u0 ` . i.e if
353353``` @example faq_remake
354354nlprob1 = NonlinearProblem(nlsys, u0, ps)
355355```
356356then
357357``` @example faq_remake
358- nlprob1[(:X1 , :X2 , :X3 )] == (1.0, 2.0, 3.0)
358+ nlprob1[(:X₁ , :X₂ , :X₃ )] == (1.0, 2.0, 3.0)
359359```
360360and
361361``` @example faq_remake
362362nlprob1.ps[:Γ][1] == 6.0
363363```
364- If we now try to change a value of ` X1 ` , ` X2 ` , or ` X3 ` using ` remake ` , the
364+ If we now try to change a value of ` X₁ ` , ` X₂ ` , or ` X₃ ` using ` remake ` , the
365365conserved constant will be recalculated. i.e. if
366366``` @example faq_remake
367- nlprob2 = remake(nlprob1; u0 = [:X2 => 3.0])
367+ nlprob2 = remake(nlprob1; u0 = [:X₂ => 3.0])
368368```
369369compare
370370``` @example faq_remake
371- println("Correct u0 is: ", (1.0, 3.0, 3.0), "\n", "remade value is: ", nlprob2[(:X1 , :X2 , :X3 )])
371+ println("Correct u0 is: ", (1.0, 3.0, 3.0), "\n", "remade value is: ", nlprob2[(:X₁ , :X₂ , :X₃ )])
372372```
373373and
374374``` @example faq_remake
375375println("Correct Γ is: ", 7.0, "\n", "remade value is: ", nlprob2.ps[:Γ][1])
376376```
377377However, if we try to directly change the value of ` Γ ` it is not always the case
378378that a ` u0 ` value will correctly update so that the conservation law is
379- conserved. i.e. if
379+ conserved. Consider
380380``` @example faq_remake
381- nlprob3 = remake(nlprob1; u0 = [:X2 => nothing], p = [:Γ => [4.0]])
381+ nlprob3 = remake(nlprob1; u0 = [:X₂ => nothing], p = [:Γ => [4.0]])
382382```
383- setting ` [:X2 => nothing] ` for other problem types communicates that the
384- ` u0 ` value for ` X2 ` should be solved for. However, if we examine the values we
383+ Setting ` [:X₂ => nothing] ` for other problem types communicates that the
384+ ` u0 ` value for ` X₂ ` should be solved for. However, if we examine the values we
385385find
386386``` @example faq_remake
387- println("Correct u0 is: ", (1.0, 0.0, 3.0), "\n", "remade value is: ", nlprob3[(:X1 , :X2 , :X3 )])
387+ println("Correct u0 is: ", (1.0, 0.0, 3.0), "\n", "remade value is: ", nlprob3[(:X₁ , :X₂ , :X₃ )])
388388```
389389and
390390``` @example faq_remake
391391println("Correct Γ is: ", 4.0, "\n", "remade value is: ", nlprob3.ps[:Γ][1])
392392```
393- As such, the ` u0 ` value for ` X2 ` has not updated, and the conservation law is
393+ As such, the ` u0 ` value for ` X₂ ` has not updated, and the conservation law is
394394now violated by the ` u0 ` values, i.e,
395395``` @example faq_remake
396- (nlprob3[:X1 ] + nlprob3[:X2 ] + nlprob3[:X3 ]) == nlprob3.ps[:Γ][1]
396+ (nlprob3[:X₁ ] + nlprob3[:X₂ ] + nlprob3[:X₃ ]) == nlprob3.ps[:Γ][1]
397397```
398398Currently, the only way to avoid this issue is to manually specify updated
399399values for the ` u0 ` components, which will ensure that ` Γ ` updates appropriately
400- as in the first example. i.e. we manually set ` X2 ` to the value it should be and
400+ as in the first example. i.e. we manually set ` X₂ ` to the value it should be and
401401` Γ ` will be updated accordingly:
402402``` @example faq_remake
403- nlprob4 = remake(nlprob1; u0 = [:X2 => 0.0])
403+ nlprob4 = remake(nlprob1; u0 = [:X₂ => 0.0])
404404```
405405so that
406406``` @example faq_remake
407- println("Correct u0 is: ", (1.0, 0.0, 3.0), "\n", "remade value is: ", nlprob4[(:X1 , :X2 , :X3 )])
407+ println("Correct u0 is: ", (1.0, 0.0, 3.0), "\n", "remade value is: ", nlprob4[(:X₁ , :X₂ , :X₃ )])
408408```
409409and
410410``` @example faq_remake
411411println("Correct Γ is: ", 4.0, "\n", "remade value is: ", nlprob4.ps[:Γ][1])
412412```
413413
414414Finally, we note there is one extra consideration to take into account if using
415- ` structural_simplify ` . In this case one of ` X1 ` , ` X2 ` , or ` X3 ` will be moved to
415+ ` structural_simplify ` . In this case one of ` X₁ ` , ` X₂ ` , or ` X₃ ` will be moved to
416416being an observed. It will then always correspond to the updated value if one
417417tries to manually change ` Γ ` . Let's see what happens here directly
418418``` @example faq_remake
@@ -435,25 +435,24 @@ Let's now remake
435435``` @example faq_remake
436436nlprob2 = remake(nlprob1; u0 = [obs_unknown => nothing], p = [:Γ => [8.0]])
437437```
438- Here we indicate to assume the observed variable is not known during
439- initialization. Since the observed variable is not considered an unknown,
440- everything works now with the observed variable's assumed initial value adjusted
441- to allow ` Γ = 8 ` :
438+ Here we indicate that the observed variable should be treated as unspecified
439+ during initialization. Since the observed variable is not considered an unknown,
440+ everything now works, with the observed variable's assumed initial value
441+ adjusted to allow ` Γ = 8 ` :
442442``` @example faq_remake
443443correct_u0 = last.(u0)
444444correct_u0[obsidx] = 8 - sum(correct_u0) + correct_u0[obsidx]
445- println("Correct u0 is: ", (1.0, 2.0, 5.0), "\n", "remade value is: ", nlprob2[(:X1 , :X2 , :X3 )])
445+ println("Correct u0 is: ", (1.0, 2.0, 5.0), "\n", "remade value is: ", nlprob2[(:X₁ , :X₂ , :X₃ )])
446446```
447447and ` Γ ` becomes
448448``` @example faq_remake
449449println("Correct Γ is: ", 8.0, "\n", "remade value is: ", nlprob2.ps[:Γ][1])
450450```
451- Unfortunately, as with our first example, trying to enforce that any other
452- variable should have its initial value updated instead of the observed will not
453- work.
451+ Unfortunately, as with our first example, trying to enforce that a
452+ non-eliminated species should have its initial value updated instead of the
453+ observed species will not work.
454454
455455* Summary:* it is not recommended to directly update ` Γ ` via ` remake ` , but to
456- instead update values of the initial guesses, ` u0 ` , to obtain a desired ` Γ ` . At
457- this time the behavior when updating ` Γ ` is inconsistent or incorrect in what
458- will be modified in ` u0 ` , and as such should not be relied on to generate a
459- consistent ` u0 ` that still satisfies the conservation law.
456+ instead update values of the initial guesses in ` u0 ` to obtain a desired ` Γ ` . At
457+ this time the behavior when updating ` Γ ` can result in ` u0 ` values that do not
458+ satisfy the conservation law defined by ` Γ ` as illustrated above.
0 commit comments