Open Nits7029 opened 2 years ago
Perhaps I'm missing a bit of documentation on how units actually work. They're not really intended to be hand-written, and the format is mostly made to ease calculations. Each key in the units
object is a base-unit and each value a power. So Newtons, being equivalent to kg * m / s^2
or kg^1 * m^1 * s^-2
becomes { kg: 1, m: 1, s: -2 }
. You don't have to use the base SI units as your base units, but I'd recommend it if you want to be able to convert between units. That means only m
, s
, kg
, K
, mol
, cd
, A
and bit
(alright, bit is not included in SI, but it gets honorable mention) should be used as keys in the units. All the default variables use these units, and are defined in https://github.com/kgram/equation-resolver/blob/master/src/defaultVariables.ts.
So, how to express your variables in these units? For kN
, kilo is a number and should be moved out of the unit and Newton is a compound unit, kg * m / s^2
. Divide it by m
and you get kg / s^2
. cm
should have the "centi-" moved outside the unit. Thus, it becomes:
{
abc: { type: "unit", value: { type: "number", value: 50000 }, units: { kg: 1, s: -2 } },
d: { type: "unit", value: { type: "number", value: 5 }, units: { m: 1 } },
r: { type: "number", value: 2 },
}
Not exactly the most readable. So instead of writing it out by hand, why not just calculate it? Using parse
from equation-parser
and resolve
from equation-resolver
, you can just create it from the string "50 kN/m"
.
Here's a couple examples. The first example uses the literally defined variables, the second uses a small helper function called toVariable
to create its variables from equations, the third converts the result to MN
, and the last one disables automatic simplification to Newtons, just as an illustration. Note that both the helper function and all the examples includes defaultVariables
. This is necessary to use any common units, such as kN
, m
or cm
, so don't forget that part.
There should probably be some simpler way to define variables directly as equations, but I'm not really sure what API would make sense, since it should still be possible to use already-evaluated variables such as the ones in defaultVariables
. If you have suggestions, I'm open.
@kgram I really appreciate a quick and promising reply.
Yes, agree, missing a bit of documentation. Would be great if you document that with proper different examples so it would be better to understand for developers.
The use case I proposed is mostly all developers looking to evaluate expressions.
Thanks for your help, I will bother you again if I stuck anywhere for different use cases. :)
@kgram could you please give me some examples for Logarithm Equation evaluation? Thanks.
And for formula writing, I am going to use https://cortexjs.io/mathlive/ and we can read the written formula as ascii-math. It works for the simple formula to input direct ascii-math to EquationEvaluate but some complex formulas with subscript, log ... are not working directly in EquationEvaluate
Example: ascii-math am getting is => M{ed;as} So if i input M{ed;as} into EquationEvaluate then it renders as M_{ed;as} And also how to input this kind of variable's value?
So could you please guide me on how to achieve that? I am open to your suggestion for different math input libraries which can directly work with EquationEvaluate
Logarithms exist as two functions defined in defaultFunctions
: ln(x)
is the natural logarithm and log(x, base)
has variable base, with the base defaulting to 10 if not specified.
You can do variable subscripts using underscore (a variable or function named M_1
would render as "M₁"), but you cannot have non-variable-name characters, such as ;
... at least not yet. I guess I hadn't considered things like matrix-indexing (which I'm guessing is what you want here?) in my implementation. It should definitely be included, but I'll have to look into how best to handle it.
There currently is no WYSIWYG editor compatible with this library as far as I know. Ironically, I started out wanting to create a math WYSIWYG editor, but I found that the only renderer available was LaTeX based, which is awful to read and write as plaintext in my opinion. So I started writing a parser and renderer, and then might as well add evaluation, and then I got busy with life and never got around to the WYSIWYG editor.
I think you could write a converter for equations. The LaTeX math syntax is not super complicated at its base as far as I remember, just plain math and slash-commands with arguments in curly braces. The problem is handling the sheer amount of commands. "MathLive supports over 800 LaTeX commands." Would be a bit of a mouthful to handle them all, but a subset would probably be possible.
ok @kgram, thanks for the explanation
@kgram could you please tell me how to render the formula with the variable value in place?
Example:
I'm assuming you'd want this to work with arbitrary formulas and variables? If you can live with the constraint that variables can't have complex expressions (then you'd have to figure out if the variable has to be wrapped in a parenthesis, which is not trivial), but are just numbers or maybe numbers and units, then it's definitely doable. Maybe an AST mapping function would be a good idea to implement at some point, but I can't guarantee when I'll get around to that, so if you need it now, I'd suggest taking a crack at it yourself.
Basically, what I'd do is to split the input into a variable name ('λ_LT'
), an equation ('1/sqrt(C_1)*0.9λ_Z*sqrt(B_ω)'
) and a variable lookup ({ 'λ_Z': '450', ... }
). Using parse
from equation-parser
, you then manually parse the equation and variables.
When parsed you can map the AST to replace the variables with their values (remember to clone rather than modify the AST if you also wish to render the original equation) using a recursive function. Take a look at the documentation of the AST. You should clone everything, but all nodes with EquationNode
properties must also be mapped. When you encounter a variable
node, you check if it's one of the variables you passed down, and return the parsed variable value instead. The tricky thing here is to detect if the value needs to be wrapped in a parenthesis, but this is unnecessary if you're only using number-variables.
After this mapping, you can render everything. If you want to render the equation and variables with equals, you can wrap it in an equals
-node, e.g. const fullEquation = { type: 'equals', a: { type: 'variable', name: variableName }, b: variableEquation }
. Given that you already parsed your equations, there's no need for that. You can render them using EquationPreparsed
or EquationEvaluatePreparsed
.
@kgram first of all thanks for creating such a great library. and It's working like a charm.
But here I want to achieve one thing, How to define variables values with units defined in an equation?
So here is the explanation:
It gives me the correct result with the correct unit = *110^6 N**
Now I am trying to use a real equation with variables as below:
And it's giving me a wrong result with wrong unit = 1⋅10^5 kN/m cm
I am not sure whether the way I passed the variables is correct or not.
So could you please give me a proper example to achieve the correct result?
Thanks