I know how to easily make a calculator that handles two or three operands with single operator (multiplying or dividing or...).
But how does one go about writing one that handles normal syntax and multiple operands, say 6 * 6 / 3 + 2 or maybe just their reverse polish notation equivalent 6 6 * 3 / 2 +
You can create a fairly simple recursive descent parser that can parse arbitrarily complex arithmetic expressions. The parser generates a tree representation of the expression, which encodes the various precedence/associativity rules of arithmetic.
The nodes of the tree will be operations (*,/,+,-) and the leaves will be numbers.
Evaluating the expression is then just a case of walking the tree and evaluating each node from the bottom up, until you get to the top which is the final result.
Google will throw up loads of examples of doing this in various languages.
Related
Why do I get different results when using the same code running in different version of MATLAB (2016 vs 2021) for sum(b.*x1) where b is single and x1 is double. How to avoid such error between MATLAB version?
MATLAB v.2021:
sum(b.*x1)
ans =
single
-0.0013286
MATLAB 2016
sum(b.*x1)
ans =
single
-0.0013283
In R2017b, they changed the behavior of sum for single-precision floats, and in R2020b they made the same changes for other data types too.
The change speeds up the computation, and improves accuracy by reducing the rounding errors. Simply put, previously the algorithm would just run through the array in sequence, adding up the values. The new behavior computes the sum over smaller portions of the array, and then adds up those results. This is more precise because the running total can become a very large number, and adding smaller numbers to it causes more rounding in those smaller numbers. The speed improvement comes from loop unrolling: the loop now steps over, say, 8 values at the time, and in the loop body, 8 running totals are computed (they don’t specify the number they use, the 8 here is an example).
Thus, your newer result is a better approximation to the sum of your array than the old one.
For more details (a better explanation of the new algorithm and the reason for the change), see this blog post.
Regarding how to avoid the difference: you could implement your own sum function, and use that instead of the builtin one. I would suggest writing it as a MEX-file for efficiency. However, do make sure you match the newer behavior of the builtin sum, as that is the better approximation.
Here is an example of the problem. Let's create an array with N+1 elements, where the first one has a value of N and the rest have a value of 1.
N = 1e8;
a = ones(N+1,1,'single');
a(1) = N;
The sum over this array is expected to be 2*N. If we set N large enough w.r.t. the data type, I see this in R2017a (before the change):
>> sum(a)
ans =
single
150331648
And I see this in R2018b (after the change for single-precision sum):
>> sum(a)
ans =
single
199998976
Both implementations make rounding errors here, but one is obviously much, much closer to the expected result (2e8, or 200000000).
When indexing dictionary in depth I've found different results in the same (as I think) constructions:
q)d:`a`b!(1 2 3;4 5 6)
q)d[`a`b;0]
1 4
q)d[`a`b]0
1 2 3
Why is this happening? How q understands and distinguishes two different cases? Before this I was confident that, for example, calling dyadic function f[a;b] and f[a]b are the same. And now I am not sure even about this.
To index at depth you either need semi colons separating your arguments, or use the dot. Your second example,
d[`a`b] 0
Is taking the 2 lists from the dictionary values and then indexing to return the first.
While
d[`a`b;0]
or
d .(`a`b;0)
Is taking the 2 lists, and then indexing at depth, taking the first element of each, due to the semi colon/dot
When you call a dyadic function it is expecting two parameters, passing one inside the square brackets creates a projection, which is basically using an implicit semi colon, so
f[a]b
is the same as
f[a;]b
which is the same as
f[a;b]
The result of
f[a]
is a projection which is expecting another argument, so
f[a] b
evaluates f[a], then passes argument b to this function, with usual function application via juxtaposition
Your dictionary indexing example does not create a projection, and hence the indexing is not expecting any more arguments, so the first indexing
d[`a`b]
is evaluated immediately to give a result, and then the second index is applied to this result.
It would work the same for a monadic function
q){5+til x}[5] 2
7
Like the top level dictionary index, the application is carried out and then the result is indexed, as only one argument was expected, with no projection involved
EDIT - Adam beat me to it!
I don't think you can consider a function invocation f[a;b] or f[a]b as equivalent to indexing. f[a]b for a function is a projection but you can't project indexing in the same way. A function has a fixed valence, aka fixed number of inputs, but indexing can be done at any depth.
If you take your dictionary and fabricate it to have more depth, you can see that you can keeping indexing deeper and deeper:
q)d:{`a`b!2#enlist value x}/[1;d]
q)d[`a`b;1;1]
5 5
q)d:{`a`b!2#enlist value x}/[2;d]
q)d[`a`b;1;1;1;1]
5 5
q)d:{`a`b!2#enlist value x}/[2;d]
q)d[`a`b;1;1;1;1;1;1]
5 5
Yet you can still index just at the top level d[`a`b]. So the interpreter has to decide if its indexing at the top level, aka d # `a`b or indexing at depth d . (`a`b;0).
To avoid confusion it indexes at top level if you supply one level of indexing and indexes at depth if you supply more than one level of indexing. Thus no projections (at least not in the same manner).
And as mentioned above, functions don't have this ambiguity because they have a fixed number of parameters and so they can be projected.
What's happening here is that d[`a`b] has the depth/valence as d. So when you apply d[`a`b]0 the zero is not indexing at depth. You get expected results if you don't index multiple values of your dictionary:
q)d[`a`b;0]~d[`a`b][0]
0b
q)d[`a;0]~d[`a][0]
1b
q)d[`b;0]~d[`b][0]
1b
This is more clear if you instead consider a 2x3 matrix which has identical behavior to your original example
q)M:(1 2 3;4 5 6)
q)M[0 1;0]
1 4
q)M[0 1][0]
1 2 3
Indexing any one row results in a simple vector
q)type M[0]
7h
q)type M[1]
7h
But indexing more than one row results in a matrix:
q)type M[0 1]
0h
In fact, indexing both rows results in the same exact matrix
q)M~M[0 1]
1b
So we should expect
q)M[0]~M[0 1][0]
1b
as we see above.
None of this should have an impact on calling dyadic functions, since supplying one parameter explicitly results in a function projection and therefore the valence is always reduced.
q)type {2+x*y}
100h
q)type {2+x*y}[10]
104h
I am writing a console program to represent logical expressions( something likes AB'C + A'C) so that I can be simplify( optimize) the expressions and evaluate their values. I tried to use string to represent an expression, but in this way, I can only evaluate its value base on input values, but optimize an expression that represented as string is very difficult( with me), Example, ABC + AB can be AB because ABC+AB = AB(C+1) = AB. I have also think another way it is using vector of vector of literal. Example, AB'C + AB + BC will be represent as below figure:
Explaining: Each column is represent for each term, in above example. The first column represents for AB'C, the second one represents for AB and the third one represents for BC'.
I think it is a good way to present logical expression but I still can not find a way to optimize an expression that repression by this way. I also googled but I did not find sample project for the problem.
In short, I hope someone suggest to me a way to represent, evaluate and optimize an logical expression easier. Thank in advance!
How to represent, evaluate and optimize a logical expression?
To represent this you need to use an expression tree and since you are using only logic operators that are binary operators you want to use a binary expression tree or more specifically this.
To simplify the tree you use the laws of Boolean algebra.
If all of the values are bound, then through the process of simplification the tree will simplify to a root node with either true or false.
For some example code I checked Rosetta Code but they had no task for evaluating Boolean expressions. The closest task is arithmetic evaluation.
I have a few simple equations that I want to pipe through matlab. But I would like to get exact answers, because these values are expected to be used and simplified later on.
Right now Matlab shows sqrt(2.0) as 1.1414 instead of something like 2^(1/2) as I would like.
I tried turning on format rat but this is dangerous becasue it shows sqrt(2) as 1393/985 without any sort of warning.
There is "symbolic math" but it seems like overkill.
All I want is that 2 + sqrt(50) would return something like 2 + 5 * (2)^(1/2) and even my 5 years old CASIO calculator can do this!
So what can I do to get 2 + sqrt(50) evaluate to 2 + 5 * (2)^(1/2) in matlab?
As per #Oleg's comment use symbolic math.
x=sym('2')+sqrt(sym('50'))
x =
5*2^(1/2) + 2
The average time on ten thousand iterations through this expression is 1.2 milliseconds, whilst the time for the numeric expression (x=2+sqrt(50)) is only 0.4 micro seconds, i.e. a factor of ten thousand faster.
I did pre-run the symbolic expression 50 times, because, as Oleg points out in his second comment the symbolic engine needs some warming up. The first run through your expression took my pc almost 2 seconds.
I would therefore recommend using numeric equations due to the huge difference in calculation time. Only use symbolic expressions when you are forced to (e.g. simplifying expressions for a paper) and then use a symbolic computation engine like Maple or Wolfram Alpha.
Matlab main engine is not symbolic but numeric.
Symbolic toolbox. Create expression in x and subs x = 50
syms x
f = 2+sqrt(x)
subs(f,50)
ans =
50^(1/2) + 2
Question
Suppose I have two vectors of arbitrary length. Lets call one pattern and the other series. Now I want to add my repeated pattern to my series in an automatic way.
Typically one can assume that pattern is shorter than series, but it would be nice if the alternate way also worked. In this case just the first few values of pattern should be used.
Example
pattern = 1:3;
series = 1:10;
Should give
2 4 6 5 7 9 8 10 12 11
What have I found so far?
I have searched around but did not find an elegant way to achieve what I want.
The easiest solution I found uses padarray, however I do not have this available
My own solution,that I don't consider to be elegant, is using repmat to repeat the pattern a sufficient amount of times and then cutting of the end.
You could use indexing instead of repmat:
result = series + pattern([mod(0:(numel(series) - 1), numel(pattern)) + 1]);