-
-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds @compound macro #651
Adds @compound macro #651
Conversation
Can you add a corresponding tests file with some tests? |
Could you do a test that checks that the components of a compound is the expected one? Like that H2O indeed consist of 2 H and 1 O? Also, for the test file to be run, you need to add it to the runtests.jl file. You could add it to this section:
Maybe like:
I'd probably also move it to misc tests (?) that it does not necessarily require the DSL. Otherwise looks good :) |
Can be used to query the constituent species of the compound. Adds more tests.
From what I understand the |
src/compound.jl
Outdated
escaped_setmetadata_expr = esc(setmetadata_expr) | ||
|
||
# Construct the array from the remaining arguments | ||
arr = Expr(:vect,(arr_expr)...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you store the component information in a more easy to query manner. You could either have two metadata, CompoundComponent
and CompoundCoefficients
or have CompoundComponent
return a vector of pairs of the form [A => 3, B => 1, C => 2]
for A3BC2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@TorkelE and I spoke, and I think we prefer the approach of storing the symbolic components and their coefficients separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, will implement this in the next commit.
@compound H2O(t) 1H 2O | ||
@test typeof(H2O) == Num | ||
arr_components = [1H ,2O] | ||
@test all((string(c1) == string(c2) for (c1, c2) = zip(components(H2O), arr_components))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should test equality of the numeric coefficients and the symbolic variables separately. For symbolic variables you can use isequal(A,B)
to test if they are the same symbolic. You shouldn't ever be converting to strings when working with symbolic variables except for display reasons.
You probably need to use |
Ok, so some specifications to this.
@variables t
@species C(t) H(t) O(t)
@compound C6H12O2(t) 6C 12H 2O we would store let
@variables t
@species C(t) H(t) O(t)
@compound C6H12O2(t) 6C 12H 2O
@test isequal([C, H, O], components(C6H12O2))
@test isequal([6, 12, 2], coefficients(C6H12O2))
end Here,
let
@variables t
@species C(t) H(t)
@compound C6H12O2(t) 6C 12H 2O
end throws an error.
@variables t
@species C(t) H(t) O
@compound OH O H
@compound C3H5OH3 3C 5H 3OH
@test isequal(components(components(C3H5OH3)[3]), [O, H])
@test isequal(coefficients(components(C3H5OH3)[3]), [1, 1])
@variables t
@species C(t) H(t) O(t)
s = C
@compound C6H12O2(t) 6$s 12H 2O and get the same result as @variables t
@species C(t) H(t) O(t)
@compound C6H12O2(t) 6C 12H 2O I will try to write some proper test cases for you to add to your file, which you can use as specifications, when I get back to the office tomorrow. |
Understood. Will implement these in the following commits. Thank you for the detailed explanation :) |
Ok, here is a slightly more comprehensive test file you can use to ensure that the functionality works. If there are any oddities, just report it and I will have a look.
|
Thank you! Will test this and let you know. |
Fixes tests, changes approach to keep macro hygienic and simple.
After numerous attempts of trying to store the components and coefficients separately within the macro itself, I ran into hygiene and scoping issues with the macro. As a workaround, I switched back to the previous approach and instead made changes to the retrieval functions Also, the Also, the interpolation can be implemented with this approach without the use of $.
|
Also, how can I fix the format check tests? :D |
To fix the format check, you will need to run |
Don't reformat in this PR. The style recently changed, so it will polute the PR by modifying like every Catalyst file... There should be a new style update in the near future that will also require a complete repo reformat, and we can rerun formatting at that time. |
From what I understand GCD is actually creating issues in some cases. For example -
I am using this as a source to get the answers. Here too, |
Are you adding balance of equations and such stuff here as well? Generally, it is better to restrict 1 PR to 1 function. E.g. do one PR to add the |
@LalitChauhan56 will try to take a closer look in the next day or two, but shouldn't there be a way to do this that avoids floating point? Also, is your back substitution step really doing backsub, or is it doing a floating point least squares solve? (Is the matrix non-square, if so I believe it is likely doing least squares?) |
Also, @TorkelE is right that it probably makes sense to do the balancing as a separate PR so we can merge the compound stuff now. |
Understood, I'll create a separate PR for the balancing part. Also, yes there should be a way to avoid floating point numbers. I'll try to figure it out. |
BTW, it would be fine to drop into rational numbers if really needed, though probably slow. It would just be nice to avoid floating point if possible. (That said, if we need to have the first version use floating point and can then refine it over time to be better that is ok too.) I'm not up on the latest methods for balancing, so it may be there is no "standard" integer-based approach. I'd have to look at the literature. |
Although slower, this prevents rounding
@isaacsas This commit uses rational numbers and skips floating point numbers entirely. Also, once you have reviewed this I can delete the balancing code from this PR so that the |
Why don’t you move the balancing stuff out of this PR now so we can get this merged, and then we can review it in the new PR you open. That’ll be easier for us all I think. Thanks! |
It is ok if the new PR has the code for this PR too; once this is merged you can just merge master into your new PR and the redundant code will get dropped. |
@isaacsas I removed the balancing code from this PR. Also can you please take a look at the formatting test failing? I formatted the file using Julia Formatter 1.0.32 but it still fails. |
src/Catalyst.jl
Outdated
# for creating compounds | ||
include("compound.jl") | ||
export @compound | ||
export components, iscompound, coefficients, component_coefficients, balance, get_stoich |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are exporting non-existent functions here? (i.e. balance
and get_stoich
?) Also, let's not export component_coefficients
.
# Test threw exception | ||
# Expression: all(.!(iscompound.components(C6H12O2))) | ||
# type #iscompound has no field components |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are these commented lines about?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There don't seem to be any tests allowing using a parameter or its value as a coefficient?
i.e.
alpha = 2
@compound 2H $alpha*H
or
@parameter alpha = 2
@compound 2H $alpha*H
or something similar (dropping the $
if you want).
Similarly are there tests that allow using a variable like
@species A(t)
B = A
@compound A2 2*B # or @compound 2*$B
Basically, I want to ensure someone can use this programmatically where coefficients and/or species may be stored in a variable. |
Adds tests allowing using a parameter or its value as a coefficient
I added more tests for the functionalities you suggested. Also, regarding this issue, I am unable to make this work. In cases where there is a coefficient in the value of the variable itself such as Letting it work the way it currently does leaves me incorrect components and coefficients. For example -
|
However cases such as |
That sounds ok. I think it is fine if the right most term in the product has to be just a variable and not a general expression. We just want to make sure the coefficients can be expressions (and eventually document all this behavior). |
Looks good, we can clean up later if needed. Thanks, nice work on this PR!!! |
I'm not sure about the formatter issue. We can figure it out later. I'll be traveling the next two weeks, but try to look at your balancing PR when I get some time. @TorkelE said he will also try to work with you on any issues and reviewing that PR. The next step is for you to now update that PR to master (either rebase master onto it, or merge master into it -- I usually do the latter). |
Understood. Thank you for guiding me throughout the PR :) Also, I have updated the balancing PR. |
[WIP] Extension to this PR which creates the
@compound
macro with the updated input.. Also adds theiscompound()
function to check if a species is a compound or not.