Support external parameters in the voltage divider#17
Conversation
|
The escaping/quoting issue in |
chiplet
left a comment
There was a problem hiding this comment.
Some comments and questions. Otherwise LGTM 👍
| /// `voltage_divider` computes values for resistor-based voltage dividers. | ||
| /// - Usage: vdiv(<target voltage>, <divider expression>, <resistor series>, (min resistance), (max resistance)) | ||
| /// - Example: vdiv(5.1, "(R1+R2)/R2*0.8", "E96", 500e3, 700e3) | ||
| /// - Usage: vdiv(<target voltage>, <divider expression>, <resistor series>, | ||
| /// {(<min resistance>, <max resistance>)}, ({extra 1}, {extra 2}, ...)) | ||
| /// - Example: vdiv(5.1, "(R1+R2)/R2*E1", "E96", (500e3, 700e3), (0.8)) | ||
| /// - Output: (<closest voltage>, <R1 value>, <R2 value>, ...) | ||
| /// There can be arbitrary many resistors in the divider, but they must be named "R1", "R2", etc. | ||
| /// The computed optimal resistance values are also presented in this order. The minimal and maximal | ||
| /// resistance limits are optional parameters, and only consider the sum of the resistances of all | ||
| /// resistors defined in the expression. | ||
| /// resistance pair is an optional parameter, and the limits only consider the sum of resistance of | ||
| /// all resistors defined in the expression. The "extra" parameters are optional external inputs for | ||
| /// the divider expression, and will be made available as "E1", "E2", etc. in order. |
There was a problem hiding this comment.
For some reason this doc comment is not showing up in the documentation generated with cargo doc.
There was a problem hiding this comment.
The vdiv module is purposefully private (not pub), so to generate docs for it requires passing the --document-private-items flag to cargo doc. But thanks for noticing this, the formatting didn't like the unescaped <> so I've fixed that now in 7be3cd0.
| let re = Regex::new(r"^R[1-9][0-9]*$").unwrap(); | ||
| let mut set = HashSet::new(); | ||
| e.iter_variable_identifiers().for_each(|i| { | ||
| set.insert(i); | ||
| }); | ||
| e.iter_variable_identifiers() | ||
| .filter(|i| re.is_match(i)) // Match only R? identifiers | ||
| .for_each(|i| { | ||
| set.insert(i); | ||
| }); | ||
| set.len() |
There was a problem hiding this comment.
Why is the HashSet used here? Couldn't this be just the following?
fn resistor_identifiers(e: &Node) -> usize {
let re = Regex::new(r"^R[1-9][0-9]*$").unwrap();
e.iter_variable_identifiers()
.filter(|i| re.is_match(i)) // Match only R? identifiers
.count()
}There was a problem hiding this comment.
Say you have parsed an expression of the form R2 = R1 * R1. What iter_variable_identifiers() is going to output is simply all variable identifiers of the parsed node tree in order, i.e. the list R2, R1, R1. The HashSet is used to keep track of already encountered identifiers for a relatively simple way to avoid counting a given identifier more than once.
See the doc comments for the
voltage_dividerfunction for details. By passing external parameters as arguments to thevdivfunction we can leverage the dependency resolving of the evaluator. The given parameters will subsequently be made available viaEnidentifiers wherencounts up from 1 (like is commonly done for resistors as well).Completes the final task of #16.