I am working on a project that uses Katex format to display mathematical formulas.
Now I am facing a bit of a problem here.
For rendering a fraction the katex syntax is
\dfrac{x}{y}
Now if I have a variable x of value 3 and another variable y of value 5.
How would I inject the values into the Katex syntax?
I want to have something like
var x = 3;
var y = 5;
\dfrac{x}{y}
where the x and y in katex syntax will be replaced by the actual values.
Note: I am also using the https://github.com/talyssonoc/react-katex
to render Katex.
I think I'd use macro substitution for this. Try to get your formula expressed as \frac{\x}{\y} by whatever machinery is generating the formula. Then you can substitute either the variable names or the values in place of those macros. Something like this:
katex.render("\\frac{\\x}{\\y}", element, {
macros: {
"\\x": String(x),
"\\y": String(y),
}
});
If you don't have a way to control how the formulas are constructed initially, this merely shifts the problem from substituting values into the formula to substituting commands into it. In that case, you probably want to tokenize the input string into commands \… and other letters. Commands remain as they are, while other letters are subject to variable substitution.
One thing to be careful of is grouping: Input \frac xy renders just fine, but with x=34.5 and y=5.67 substituted in the naive way, the result \frac 34.55.67 (which is what both text and macro substitution will give you) renders as \frac{3}{4}.55.67. So make sure that each macro you have in your formula is enclosed by {…} or add another level of {…} when you do the substitution as in "\\x": "{" + x + "}". Enclosing macros by {…} inside the formula has the benefit that you won't have to worry about a macro eating a subsequent space: \text{\x is 2} is bad but \text{{\x} is 2} is better.
But even with grouping done correctly, this approach is not perfect since not all non-commands are indeed variables. For example with \begin{array}{rlrl}…\end{array} neither the a in array nor the r in rlrl should be considered a variable. Fixing this is really problematic, as it requires a lot of semantic insight.
One way to tackle this dilemma would be letting KaTeX do its rendering and then doing the substitution in the resulting DOM subtree. You should be able to identify variables as <span class="mord …">…</span> (mord stands for math ordinary). This means you depend on the exact representation KaTeX uses for its output, so you should make sure you run a fixed version of KaTeX as these internal things are subject to change without notice. Also be aware of the fact that in some (possibly future) version this might break certain constructs which depend on the width of a given box, although even things as problematic as \underbrace appear to work with this substitution approach at the moment.
Related
I have some code that runs fine and does what I want, although there may be a simpler more elegant solution, this works :
round(Int16, floor(rand(TruncatedNormal(150,20,50,250))))
However when I try to execute it multiple times, using map, it throws an error saying it doesn't like the Int16 specification, so this:
map(round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))), 1:2)
throws this error
ERROR: MethodError: objects of type Int16 are not callable
I just want to run it twice (in this case) and sum the results. Why is it unhappy? Thx. J
The first argument to map is a function. So, with your code, Julia is trying to make a function call:
round(Int16, floor(rand(TruncatedNormal(150,20,50,250))))()
But the output of round(Int16, ...) isn't a function, it's a number, so you cannot call it. That's why the error says "objects of type Int16 are not callable." You could fix this by using an anonymous function:
map(() -> round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))), 1:2)
But the "Julian" way to do this is to use a comprehension:
[round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))) for _ in 1:2]
EDIT:
If you are going to sum the results, then you can use something that looks like a comprehension but is called a generator expression. This is basically everything above with the [ ] around the expression. A generator expression can be used directly in functions like sum or mean, etc.
sum(round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))) for _ in 1:2)
The advantage to generator expressions is that they don't allocate the memory for the full array. So, if you did this 100 times and used the sum approach above, you wouldn't need to allocate space for 100 numbers.
This goes beyond the original question, but OP wanted to use the sum expression where the 2 in 1:2 is a 1-element vector. Of course, if the input is always a 1-element vector, then I recommend first(x) like the comments. But this is a nice opportunity to show the importance of breaking things down into functions frequently in Julia. For example, you could take the entire sum expression and define a function
generatenumbers(n::Integer) = sum(... for _ in 1:n)
where n is a scalar. Then if you have some odd array expression for n (1-element vector, many such ns in a multi-dim array, etc.), you can just do:
generatenumbers.(ns)
# will apply to each element and return same shape as ns
If the de-sugaring logic is more complex than applying element-wise, you can even define:
generatenumbers(ns::AbstractArray) = # ... something more complex
The point is to define an "atomic" function that expresses the statement or task you want clearly, then use dispatch to apply it to more complicated data-structures that appear in practical code. This is a common design pattern in Julia (not the only option, but an effective one).
Adding on the answer from #darsnack.
If you want to run it multiple times in order to keep the results (it wasn't clear from the question). Then you could also ask rand to produce a vector by doing the following (and also making the type conversion through the floor call).
Moving from:
map(round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))), 1:2)
to:
floor.(Int16, rand(TruncatedNormal(150,20,50,250), 2))
The documentation is here.
EDIT
SOLVED
Solution was to use the long double versions of sin & cos: sinl & cosl.
It is my first post here, so bear with me :).
I come today here to ask for your input on a small problem that I am having with a C application at work. Basically, I am computing an Extended Kalman Filter and one of my formulas (that I store in a variable) has multiple computations of sin and cos, at least 16 in total in the same line. I want to decrease the time it takes for the computation to be done, so the idea is to compute each cos and sin separately, store them in a variable, and then replace the variables back in the formula.
So I did this:
const ComputationType sin_Roll = compute_sin((ComputationType)(Roll));
const ComputationType sin_Pitch = compute_sin((ComputationType)(Pitch));
const ComputationType cos_Pitch = compute_cos((ComputationType)(Pitch));
const ComputationType cos_Roll = compute_cos((ComputationType)(Roll));
Where ComputationType is a macro definition (renaming) of the type Double. I know it looks ugly, a lot of maybe unnecessary castings, but this code is generated in Python and it was specifically designed so....
Also, compute_cos and compute_sin are defined as such:
#define compute_sin(a) sinf(a)
#define compute_cos(a) cosf(a)
My problem is the value I get from the "optimized" formula is different from the value of the original one.
I will post the code of both and I apologise in advance because it is very ugly and hard to follow but the main points where cos and sin have been replaced can be seen. This is my task, to clean it up and optimize it, but I am doing it step by step to make sure I don't introduce a bug.
So, the new value is:
ComputationType newValue = (ComputationType)(((((((ComputationType)-1.0))*(sin_Pitch))+((DT)*((((Dg_y)+((((ComputationType)-1.0))*(Gy)))*(cos_Pitch)*(cos_Roll))+(((Gz)+((((ComputationType)-1.0))*(Dg_z)))*(cos_Pitch)*(sin_Roll)))))*(cos_Pitch)*(cos_Roll))+((((DT)*((((Dg_y)+((((ComputationType)-1.0))*(Gy)))*(cos_Roll)*(sin_Pitch))+(((Gz)+((((ComputationType)-1.0))*(Dg_z)))*(sin_Pitch)*(sin_Roll))))+(cos_Pitch))*(cos_Roll)*(sin_Pitch))+((((ComputationType)-1.0))*(DT)*((((Gz)+((((ComputationType)-1.0))*(Dg_z)))*(cos_Roll))+((((ComputationType)-1.0))*((Dg_y)+((((ComputationType)-1.0))*(Gy)))*(sin_Roll)))*(sin_Roll)));
And the original is:
ComputationType originalValue = (ComputationType)(((((((ComputationType)-1.0))*(compute_sin((ComputationType)(Pitch))))+((DT)*((((Dg_y)+((((ComputationType)-1.0))*(Gy)))*(compute_cos((ComputationType)(Pitch)))*(compute_cos((ComputationType)(Roll))))+(((Gz)+((((ComputationType)-1.0))*(Dg_z)))*(compute_cos((ComputationType)(Pitch)))*(compute_sin((ComputationType)(Roll)))))))*(compute_cos((ComputationType)(Pitch)))*(compute_cos((ComputationType)(Roll))))+((((DT)*((((Dg_y)+((((ComputationType)-1.0))*(Gy)))*(compute_cos((ComputationType)(Roll)))*(compute_sin((ComputationType)(Pitch))))+(((Gz)+((((ComputationType)-1.0))*(Dg_z)))*(compute_sin((ComputationType)(Pitch)))*(compute_sin((ComputationType)(Roll))))))+(compute_cos((ComputationType)(Pitch))))*(compute_cos((ComputationType)(Roll)))*(compute_sin((ComputationType)(Pitch))))+((((ComputationType)-1.0))*(DT)*((((Gz)+((((ComputationType)-1.0))*(Dg_z)))*(compute_cos((ComputationType)(Roll))))+((((ComputationType)-1.0))*((Dg_y)+((((ComputationType)-1.0))*(Gy)))*(compute_sin((ComputationType)(Roll)))))*(compute_sin((ComputationType)(Roll)))));
What I want is to get the same value as in the original formula. To compare them I use memcmp.
Any help is welcome. I kindly thank you in advance :).
EDIT
I will post also the values that I get.
New value : -1.2214615708217025e-005
Original value : -1.2214615708215651e-005
They are similar up to a point, but the application is safety critical and it is necessary to validate the results.
You can not meet your expectation for a couple of reasons.
By altering the code you adjust the machine instructions being used in subtle ways that will impact the final value.
For instance if originally it was using fused multiplies and adds and this is no longer happening it will change the result.
You don't mention the target architecture. Some architectures retain more than 64bits in the floating point pipeline. These extra bits get rounded when forced into 64bit memory. Again altering how this works will have minor effects on the final output.
My aim is to populate an array in compile phase (i.e. in a macro), and use it in execution phase. For some reason, though, object returned by a macro is not recognized by Racket as an array. To illustrate the problem, shortest code showing this behaviour:
(require (for-syntax math/array))
(require math/array)
(define-syntax (A stx)
(datum->syntax stx `(define a ,(array #[#[1 2] #[3 4]]))))
(A)
After execution of this macro, 'a' is something, but I don't know what it is. It is not an array ((array? a) -> #f) nor a string, array-ref is not working on it, obviously, but it prints as: (array #[#[1 2] #[3 4]]). "class-of" from the "swindle" module claims it is "primitive-class:unknown-primitive", for what it's worth.
I have tried outputting a vector instead of an array, but it works as expected, i.e. resulting value is a vector in execution phase.
I have tried using CommonLisp style defmacro from "compatibility" module, thinking that this may have something to do do with datum->syntax transformation, but this changed nothing.
I have tested this on Win7 with Racket 6.5 and 6.7, as well as on Linux with Racket 6.7 - problem persists.
Any ideas?
update
Thanks to great answers and suggestions, I came up with following solution:
(require (for-syntax math/array))
(require math/array)
(define-syntax (my-array stx)
(syntax-case stx ()
[(_ id)
(let
([arr (build-array
#(20 20)
(lambda (ind)
(let
([x (vector-ref ind 1)]
[y (vector-ref ind 0)])
(list 'some-symbol x y (* x y)))))])
(with-syntax ([syn-arr (eval (read (open-input-string (string-append "#'" (format "~v" arr)))))])
#'(define id syn-arr)))]))
(my-array A)
I'm not sure if this is proper Racket (I welcome all suggestions on code improvement) but here is how it works:
Array is built and stored in "arr" variable. It is then printed to string, prepended with #' (so that this string represents syntax object now) and evaluated as code. This effectively converts array to syntax object, that can be embedded in macro output.
Advantage of this approach is, that every object that can be written out and then read back by Racket can be output by macro. Disadvantage is, that some objects can't (I'm looking at you, custom struct!) and therefore additional string-creating function may be required in some cases.
First of all, don’t use datum->syntax like that. You’re throwing away all hygiene information there, so if someone was using a different language where define was called something else (like def, for example), that would not work. For a principled introduction to Racket macros, consider reading Fear of Macros.
Second of all, the issue here is that you are creating what is sometimes known as “3D syntax”. 3D syntax should probably be an error in this context, but the gist is that there is only a small set of things that you can safely put inside of a syntax object:
a symbol
a number
a boolean
a character
a string
the empty list
a pair of two pieces of valid syntax
a vector of valid syntax
a box of valid syntax
a hash table of valid syntax keys and values
a prefab struct containing exclusively valid syntax
Anything else is “3D syntax”, which is illegal as the output of a macro. Notably, arrays from math/array are not permitted.
This seems like a rather extreme limitation, but the point is that the above list is simply the list of things that can end up in compiled code. Racket does not know how to serialize arbitrary things to bytecode, which is reasonable: it wouldn’t make much sense to embed a closure in compiled code, for example. However, it’s perfectly reasonable to produce an expression that creates an array, which is what you should do here.
Writing your macro more properly, you would get something like this:
#lang racket
(require math/array)
(define-syntax (define-simple-array stx)
(syntax-case stx ()
[(_ id)
#'(define id (array #(#(1 2) #(3 4))))]))
(define-simple-array x)
Now, x is (array #[#[1 2] #[3 4]]). Note that you can remove the for-syntax import of math/array, since you are no longer using it at compile time, which makes sense: macros just manipulate bits of code. You only need math/array at runtime to create the actual value you end up with.
I am trying to create a vector dynamically in dependence of n (for example 1 or 4). If my n is bigger I need to have more values in my vector.
for i=1:(N-n)
yvecT(i)=y(n+i); % Achtung, Zeilenvektor
for k=n:-1:1
F(i-1+n,:)=[-y(i) -y(i-k) u(i) u(i-k)];
end
end
%n=1 F(i,:)=[-y(i) u(i)];
%n=2 F(i,:)=[-y(i) -y(i-1) u(i) u(i-1)];
%n=4 F(i,:)=[-y(i) -y(i-1) -y(i-2) -y(i-3) u(i) u(i-1) u(i-2) u(i-3)];
it is a function used to identify a System....
You should have posted the for-loop (with the if-statements) from the link in the question and stated that you wanted it to work for an arbitary n. That would have made everyone understand your problem. I think the easiest way to do what you do is to use subreferencing. So in case n==2 we do not have
F(i-1,:)=[-y(i) -y(i-1) u(i) u(i-1)];
but rather,
F(i-(n-1),:)=[-y(i:-1:(n-1)) u(i:-1:(n-1))];
This looks messier, but it works for any arbitary n. Some other comments about the code. The variable i is also a function returning the imaginary unit. By naming a variable i you overload this function. The recommended way is to use 1i as an imaginary unit, so it is not critical, but in case you do not necessarily need i as a variable you should consider another name. Also it is easier for us to understand in case you write in english. So in general, prefer comments in english when posting here.
An Example
Suppose we have a text to write and could be converted to "uppercase or lowercase", and can be printed "at left, center or right".
Specific case implementation (too many functions)
writeInUpperCaseAndCentered(char *str){//..}
writeInLowerCaseAndCentered(char *str){//..}
writeInUpperCaseAndLeft(char *str){//..}
and so on...
vs
Many Argument function (bad readability and even hard to code without a nice autocompletion IDE)
write( char *str , int toUpper, int centered ){//..}
vs
Context dependent (hard to reuse, hard to code, use of ugly globals, and sometimes even impossible to "detect" a context)
writeComplex (char *str)
{
// analize str and perhaps some global variables and
// (under who knows what rules) put it center/left/right and upper/lowercase
}
And perhaps there are others options..(and are welcome)
The question is:
Is there is any good practice or experience/academic advice for this (recurrent) trilemma ?
EDIT:
What I usually do is to combine "specific case" implementation, with an internal (I mean not in header) general common many-argument function, implementing only used cases, and hiding the ugly code, but I don't know if there is a better way that I don't know. This kind of things make me realize of why OOP was invented.
I'd avoid your first option because as you say the number of function you end up having to implement (though possibly only as macros) can grow out of control. The count doubles when you decide to add italic support, and doubles again for underline.
I'd probably avoid the second option as well. Againg consider what happens when you find it necessary to add support for italics or underlines. Now you need to add another parameter to the function, find all of the cases where you called the function and updated those calls. In short, anoying, though once again you could probably simplify the process with appropriate use of macros.
That leaves the third option. You can actually get some of the benefits of the other alternatives with this using bitflags. For example
#define WRITE_FORMAT_LEFT 1
#define WRITE_FORMAT_RIGHT 2
#define WRITE_FORMAT_CENTER 4
#define WRITE_FORMAT_BOLD 8
#define WRITE_FORMAT_ITALIC 16
....
write(char *string, unsigned int format)
{
if (format & WRITE_FORMAT_LEFT)
{
// write left
}
...
}
EDIT: To answer Greg S.
I think that the biggest improvement is that it means that if I decide, at this point, to add support for underlined text I it takes two steps
Add #define WRITE_FORMAT_UNDERLINE 32 to the header
Add the support for underlines in write().
At this point it can call write(..., ... | WRITE_FORMAT_UNLDERINE) where ever I like. More to the point I don't need to modify pre-existing calls to write, which I would have to do if I added a parameter to its signature.
Another potential benefit is that it allows you do something like the following:
#define WRITE_ALERT_FORMAT (WRITE_FORMAT_CENTER | \
WRITE_FORMAT_BOLD | \
WRITE_FORMAT_ITALIC)
I prefer the argument way.
Because there's going to be some code that all the different scenarios need to use. Making a function out of each scenario will produce code duplication, which is bad.
Instead of using an argument for each different case (toUpper, centered etc..), use a struct. If you need to add more cases then you only need to alter the struct:
typedef struct {
int toUpper;
int centered;
// etc...
} cases;
write( char *str , cases c ){//..}
I'd go for a combination of methods 1 and 2.
Code a method (A) that has all the arguments you need/can think of right now and a "bare" version (B) with no extra arguments. This version can call the first method with the default values. If your language supports it add default arguments. I'd also recommend that you use meaningful names for your arguments and, where possible, enumerations rather than magic numbers or a series of true/false flags. This will make it far easier to read your code and what values are actually being passed without having to look up the method definition.
This gives you a limited set of methods to maintain and 90% of your usages will be the basic method.
If you need to extend the functionality later add a new method with the new arguments and modify (A) to call this. You might want to modify (B) to call this as well, but it's not necessary.
I've run into exactly this situation a number of times -- my preference is none of the above, but instead to use a single formatter object. I can supply it with the number of arguments necessary to specify a particular format.
One major advantage of this is that I can create objects that specify logical formats instead of physical formats. This allows, for example, something like:
Format title = {upper_case, centered, bold};
Format body = {lower_case, left, normal};
write(title, "This is the title");
write(body, "This is some plain text");
Decoupling the logical format from the physical format gives you roughly the same kind of capabilities as a style sheet. If you want to change all your titles from italic to bold-face, change your body style from left justified to fully justified, etc., it becomes relatively easy to do that. With your current code, you're likely to end up searching through all your code and examining "by hand" to figure out whether a particular lower-case, left-justified item is body-text that you want to re-format, or a foot-note that you want to leave alone...
As you already mentioned, one striking point is readability: writeInUpperCaseAndCentered("Foobar!") is much easier to understand than write("Foobar!", true, true), although you could eliminate that problem by using enumerations. On the other hand, having arguments avoids awkward constructions like:
if(foo)
writeInUpperCaseAndCentered("Foobar!");
else if(bar)
writeInLowerCaseAndCentered("Foobar!");
else
...
In my humble opinion, this is a very strong argument (no pun intended) for the argument way.
I suggest more cohesive functions as opposed to superfunctions that can do all kinds of things unless a superfunction is really called for (printf would have been quite awkward if it only printed one type at a time). Signature redundancy should generally not be considered redundant code. Technically speaking it is more code, but you should focus more on eliminating logical redundancies in your code. The result is code that's much easier to maintain with very concise, well-defined behavior. Think of this as the ideal when it seems redundant to write/use multiple functions.