@@ -333,86 +333,86 @@ nsys = convert(NonlinearSystem, rn; remove_conserved = true)
333
333
# or
334
334
nprob = NonlinearProblem (rn, u0, p; remove_conserved = true )
335
335
```
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
338
338
``` @example faq_remake
339
339
using Catalyst, NonlinearSolve
340
340
rn = @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₃
343
343
end
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]
346
346
nlsys = convert(NonlinearSystem, rn; remove_conserved = true, conseqs_remake_warn = false)
347
347
nlsys = complete(nlsys)
348
348
equations(nlsys)
349
349
```
350
350
If 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
352
352
those in ` u0 ` . i.e if
353
353
``` @example faq_remake
354
354
nlprob1 = NonlinearProblem(nlsys, u0, ps)
355
355
```
356
356
then
357
357
``` @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)
359
359
```
360
360
and
361
361
``` @example faq_remake
362
362
nlprob1.ps[:Γ][1] == 6.0
363
363
```
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
365
365
conserved constant will be recalculated. i.e. if
366
366
``` @example faq_remake
367
- nlprob2 = remake(nlprob1; u0 = [:X2 => 3.0])
367
+ nlprob2 = remake(nlprob1; u0 = [:X₂ => 3.0])
368
368
```
369
369
compare
370
370
``` @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₃ )])
372
372
```
373
373
and
374
374
``` @example faq_remake
375
375
println("Correct Γ is: ", 7.0, "\n", "remade value is: ", nlprob2.ps[:Γ][1])
376
376
```
377
377
However, if we try to directly change the value of ` Γ ` it is not always the case
378
378
that a ` u0 ` value will correctly update so that the conservation law is
379
- conserved. i.e. if
379
+ conserved. Consider
380
380
``` @example faq_remake
381
- nlprob3 = remake(nlprob1; u0 = [:X2 => nothing], p = [:Γ => [4.0]])
381
+ nlprob3 = remake(nlprob1; u0 = [:X₂ => nothing], p = [:Γ => [4.0]])
382
382
```
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
385
385
find
386
386
``` @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₃ )])
388
388
```
389
389
and
390
390
``` @example faq_remake
391
391
println("Correct Γ is: ", 4.0, "\n", "remade value is: ", nlprob3.ps[:Γ][1])
392
392
```
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
394
394
now violated by the ` u0 ` values, i.e,
395
395
``` @example faq_remake
396
- (nlprob3[:X1 ] + nlprob3[:X2 ] + nlprob3[:X3 ]) == nlprob3.ps[:Γ][1]
396
+ (nlprob3[:X₁ ] + nlprob3[:X₂ ] + nlprob3[:X₃ ]) == nlprob3.ps[:Γ][1]
397
397
```
398
398
Currently, the only way to avoid this issue is to manually specify updated
399
399
values 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
401
401
` Γ ` will be updated accordingly:
402
402
``` @example faq_remake
403
- nlprob4 = remake(nlprob1; u0 = [:X2 => 0.0])
403
+ nlprob4 = remake(nlprob1; u0 = [:X₂ => 0.0])
404
404
```
405
405
so that
406
406
``` @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₃ )])
408
408
```
409
409
and
410
410
``` @example faq_remake
411
411
println("Correct Γ is: ", 4.0, "\n", "remade value is: ", nlprob4.ps[:Γ][1])
412
412
```
413
413
414
414
Finally, 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
416
416
being an observed. It will then always correspond to the updated value if one
417
417
tries to manually change ` Γ ` . Let's see what happens here directly
418
418
``` @example faq_remake
@@ -435,25 +435,24 @@ Let's now remake
435
435
``` @example faq_remake
436
436
nlprob2 = remake(nlprob1; u0 = [obs_unknown => nothing], p = [:Γ => [8.0]])
437
437
```
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 ` :
442
442
``` @example faq_remake
443
443
correct_u0 = last.(u0)
444
444
correct_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₃ )])
446
446
```
447
447
and ` Γ ` becomes
448
448
``` @example faq_remake
449
449
println("Correct Γ is: ", 8.0, "\n", "remade value is: ", nlprob2.ps[:Γ][1])
450
450
```
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.
454
454
455
455
* 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