When and If in Modelica - logic

Hi I have some puzzles about event and when in Modelica. Below is my code:
model test
Integer bar(start=5, fixed=true);
equation
when (time < 2) then
bar = 1;
end when;
annotation(experiment(StopTime=3));
end test;
My question is why I got 5 instead of 1 when time is less than 2? How can I understand the event(time < 2) in this case? What is the difference of when clause in Modelica and other programming language, like c.

The when equation is only active when the condition becomes true. In your case the condition time < 2 is true from the beginning and only becomes false.
The when-block can be intentionally translated to
b = time < 2;
if not(pre(b)) and b then
bar = 1;
else
bar = pre(bar);
end
For further information you can consult the specification https://modelica.org/documents/ModelicaSpec33Revision1.pdf.

Tobias' answer is correct. But I think for beginners it might be a little daunting to invoke the pre construct or send them to the specification. So in addition to Tobias' answer, I would point the interested reader to this question as well as this chapter in my book. Of specific interest (I suspect) would be this subsection on when and how it is different from if.

Related

assert triggered too late

Please consider the following Modelica example model:
model Detection2
Real x = (1-2*time)*1e5;
parameter Real x_min=0.1;
Real y;
equation
y = max(x,x_min);
assert(y>x_min, "(assert) triggered at t = " + String(time), level=AssertionLevel.warning);
when y <= x_min then
Modelica.Utilities.Streams.print("(when) triggered at t = " + String(time));
end when;
annotation (experiment(StopTime=1));
end Detection2;
When I simulate it (in Dymola 2019FD01), I get the following results:
Results look as expected, but both the assert message and the print statement print the wrong time, they always print the stop time, not the time I expected!?
There are two parts to this:
Why didn't it trigger before the end? The reason is that for numerical reasons solvers create events for such relations, and don't want too many events, and thus consider y>x_min true as long as it is "almost true", i.e. that y>x_min-eps, for some small epsilon. This is explained in section 8.5 Events and Synchronization of the specification. https://specification.modelica.org/v3.4/Ch8.html#events-and-synchronization
Why did it trigger at the end? The reason is that there is an event at the end of the simulation, because the model may contain the terminal operator. At an event the comparisons are treated more literally.
If you had used x>x_min and x<=x_min instead it would have worked as you expected.
Alternatively if you had used y = if x>=x_min then x else x_min then y might be slightly below x_min, but the messages would trigger.

Can someone explain how this ruby basic-calculator code handles addition and subtraction?

So I was working on a Codewars problem here, and found some code posted to Github that works out-of-the-box. Problem is, I don't understand how part of it works. Here are the Codewars directions:
Description:
Create a simple calculator that given a string of operators (+ - * and /) and numbers separated by spaces returns the value of that expression
Example:
Calculator.new.evaluate("2 / 2 + 3 * 4 - 6") # => 7
Remember about the order of operations! Multiplications and divisions have a higher priority and should be performed left-to-right. Additions and subtractions have a lower priority and should also be performed left-to-right.
Here's the code:
class Calculator
def evaluate(string)
operator_stack = []
number_stack = []
string.split(" ").each do |token|
if /\d/.match(token)
number_stack << token.to_i
elsif operator_stack.length > 0 && /[*]|[\/]/.match(operator_stack[-1])
x, y = number_stack.pop, number_stack.pop
temp_result = y.send(operator_stack.pop, x)
number_stack << temp_result
operator_stack << token
else
operator_stack << token
end
end
while(number_stack.length > 0 && operator_stack.length > 0)
x, y = number_stack.shift, number_stack.shift
temp_result = x.send(operator_stack.shift,y)
number_stack.unshift(temp_result)
end
return number_stack[0]
end
end
Now I've learned enough Ruby that I can read through and understand what the various functions do, but when it comes to the mathematical operations the code does, I don't see where or how it handles addition and subtraction. There is some regex that's used to match for multiplication and division present in this line:
elsif operator_stack.length > 0 && /[*]|[\/]/.match(operator_stack[-1])
But since I don't see the plus or minus sign anywhere in the code, I don't get how it performs those operations. Can anyone help?
BTW, I'm done with the Codewars problem and have moved on. I also discovered you can solve this calculator problem with "instance_eval string", which blew my mind when I first saw it. But, it makes sense after reading through what I found here. I should have guessed that there was a one-liner that would work as a basic calculator :)
I would still like to know how this code handles addition and subtraction. Can anyone enlighten me?
The actual operations are performed in these lines:
temp_result = y.send(operator_stack.pop, x)
and later
temp_result = x.send(operator_stack.shift,y)
which says "send the operator_stack.shift/pop message with parameter y to objectx, which is basically the same as doing x <operator> y where <operator> is the operator on top of operator_stack

Employ early bail-out in MATLAB

There is a example for Employ early bail-out in this book (http://www.amazon.com/Accelerating-MATLAB-Performance-speed-programs/dp/1482211297) (#YairAltman). for speed improvement we can convert this code:
data = [];
newData = [];
outerIdx = 1;
while outerIdx <= 20
outerIdx = outerIdx + 1;
for innerIdx = -100 : 100
if innerIdx == 0
continue % skips to next innerIdx (=1)
elseif outerIdx > 15
break % skips to next outerIdx
else
data(end+1) = outerIdx/innerIdx;
newData(end+1) = process(data);
end
end % for innerIdx
end % while outerIdx
to this code:
function bailableProcessing()
for outerIdx = 1 : 5
middleIdx = 10
while middleIdx <= 20
middleIdx = middleIdx + 1;
for innerIdx = -100 : 100
data = outerIdx/innerIdx + middleIdx;
if data == SOME_VALUE
return
else
process(data);
end
end % for innerIdx
end % while middleIdx
end % for outerIdx
end % bailableProcessing()
How we did this conversion? Why we have different middleIdx range in new code? Where is checking for innerIdx and outerIdx in new code? what is this new data = outerIdx/innerIdx + middleIdx calculation?
we have only this information for second code :
We could place the code segment that should be bailed-out within a
dedicated function and return from the function when the bail-out
condition occurs.
I am sorry that I did not clarify within the text that the second code segment is not a direct replacement of the first. If you reread the early bail-out section (3.1.3) perhaps you can see that it has two main parts:
The first part of the section (which includes the top code segment) illustrates the basic mechanism of using break/continue in order to bail-out from a complex processing loop, in order to save processing time in computing values that are not needed.
In contrast, the second part of the section deals with cases when we wish to break out of an ancestor loop that is not the direct parent loop. I mention in the text that there are three alternatives that we can use in this case, and the second code segment that you mentioned is one of them (the other alternatives are to use dedicated flags with break/continue and to use try/catch blocks). The three code segments that I provided in this second part of the section should all be equivalent to each other, but they are NOT equivalent to the code-segment at the top of the section.
Perhaps I should have clarified this in the text, or maybe I should have used the same example throughout. I will think about this for the second edition of the book (if and when it ever appears).
I have used a variant of these code segments in other sections of the book to illustrate various other aspects of performance speedups (for example, 3.1.4 & 3.1.6) - in all these cases the code segments are NOT equivalent to each other. They are merely used to illustrate the corresponding text.
I hope you like my book in general and think that it is useful. I would be grateful if you would place a positive feedback about it on Amazon (direct link).
p.s. - #SamRoberts was correct to surmise that mention of my name would act as a "bat-signal", attracting my attention :-)
it's all far more simple than you think!
How we did this conversion?
Irrationally. Those two codes are completely different.
Why we have different middleIdx range in new code?
Randomness. The point of the author is something different.
Where is checking for innerIdx and outerIdx in new code?
dont need that, as it's not intended to be the same code.
what is this new data = outerIdx/innerIdx + middleIdx calculation?
a random calculation as well as data(end+1) = outerIdx/innerIdx; in the original code.
i suppose the author wants to illustrate something far more profoundly: that if you wrap your code that does (possibly many) loops (fors/whiles, doesnt matter) inside a function and you issue a return statement if you somehow detect that you're done, it will result in an effectively "bailable" computation, e.g. the method that does the work returns earlier than it would normally do. that is illustrated here by the condition that checks on data == SOME_VALUE; you can have your favourite bailout condition there instead :-)
moreover, the keywords [continue/break] inside the first example are meant to illustrate that you can [skip the rest of/leave] the inner-most loop from whereever you call them. in principal, you can implement a bailout using these by e.g.
bailing = false;
for outer = 1:1000
for inner = 1:1000
if <somebailingcondition>
bailing = true;
break;
else
<do stuff>
end
end
if bailing
break;
end
end
but that would be very clumsy as that "cascade" of breaks will need to be as long as you have nested loops and messes up the code.
i hope that could clarify your issues.

problems implementing negamax for tic-tac-toe in ruby

I'm banging my head against the wall trying to implement negamax for tic-tac-toe
def negamax(board_obj, mark, depth)
if board_obj.game_over?
return value(board_obj)
else
max = -1.0/0 # negative infinity
if mark == #mark
next_mark = #opponent_mark
else
next_mark = #mark
end
board_obj.empty_squares.each do |square|
board_obj[square] = mark
x = -negamax(board_obj, next_mark, depth + 1)
board_obj[square] = ' '
if x > max
max = x
#scores << x
#best_move = square if depth == 1
end
end
return max
end
end
# determines value of final board state
def value(board_obj)
if board_obj.mark_win?(#mark)
return 1
elsif board_obj.mark_win?(#opponent_mark)
return -1
else
return 0
end
end
the rest of the code is here: https://github.com/dave-maldonado/tic-tac-doh/blob/AI/tic-tac-doh.rb
It does produce a result but the AI is easily beat so I know something's wrong, any help
is appreciated!
The problem is that value needs to be relative to the mark in the current execution of negamax rather than always relative to the computer. If you pass in the mark argument to value from negamax with the following modified definition for value, you'll get the right results:
def value(board_obj, mark)
if board_obj.mark_win?(mark)
return 1
elsif board_obj.mark_win?(mark == 'X' ? 'O' : 'X')
return -1
else
return 0
end
end
That is, the first two lines of the negamax body need to be:
if board_obj.game_over?
return value(board_obj, mark)
That said, this overall program leaves an awful lot to be desired relative to Ruby, good design principles, etc (no offense intended). Now that you have it running, you might want to head over to the Code Review SE for some feedback. :-) And while it's too late to use TDD ;-), it would also be a good one to put "under test".
Also, please understand that per one of the other comments, this is not a kind of question that you'll typically get an answer to here at SO. I don't even know if this question will survive the review process without getting deleted. I worked on it for a variety of personal reasons.
Update: Looking at your reference implementation, you'll note that the negamax code includes the expression sign[color]*Analysis(b). It's that sign[color] that you were missing, effectively.

Unexpected $end after while loop and nested if

I have this program that I am working on that is supposed to find the sum of the first 1000 prime numbers. Currently all I am concerned with is making sure that the program is finding the first 1000 prime numbers, I will add the functionality for adding them later. Here is what I have:
#!/usr/bin/ruby
def prime(num)
is_prime = true
for i in 2..Math.sqrt(num)
if (num % i) == 0
is_prime = false
else
is_prime = true
end
end
return is_prime
end
i = 2
number_of_primes = 0
while number_of_primes < 1000
prime = prime(i)
if prime == true
number_of_primes++
end
i++
end
When i try to run the program I get the following feedback:
sumOfPrimes.rb:32: syntax error, unexpected keyword_end
sumOfPrimes.rb:34: syntax error, unexpected keyword_end
what gives? Any direction is appreciated.
Ruby doesn't have ++ operator, you need to do += 1
number_of_primes += 1
Unasked for, but a few pieces of advice if you're interested:
One of the cool things about Ruby is that question marks are legal in method names. As such you'll often find that 'predicate' methods (methods that test something and return true or false) end with a question mark, like this: odd?. Your prime method is a perfect candidate for this, so we can rename it prime?.
You use a local variable, is_prime, to hold whether you have found a factor of the number you're testing yet - this is the kind of thing you'd expect to do in an imperative language such as java or C - but Ruby has all sorts of cool features from functional programming that you will gain great power and expressiveness by learning. If you haven't come across them before, you may need to google what a block is and how the syntax works, but for this purpose you can just think of it as a way to get some code run on every item of a collection. It can be used with a variety of cool methods, and one of them is perfectly suited to your purpose: none?, which returns true if no items in the collection it is called on, when passed to the code block you give, return true. So your prime? method can be rewritten like this:
def prime? num
(2..Math.sqrt(num)).none? { |x| num % x == 0 }
end
Apart from being shorter, the advantage of not needing to use local variables like is_prime is that you give yourself fewer opportunities to introduce bugs - if for example you think the contents of is_prime is one thing but it's actually another. It's also, if you look carefully, a lot closer to the actual mathematical definition of a prime number. So by cutting out the unnecessary code you can get closer to exposing the 'meaning' of what you're writing.
As far as getting the first 1000 primes goes, infinite streams are a really cool way to do this but are probably a bit complex to explain here - definitely google if you're interested as they really are amazing! But just out of interest, here's a simple way you could do it using just recursion and no local variables (remember local variables are the devil!):
def first_n_primes(i = 2, primes = [], n)
if primes.count == n then primes
elsif prime? i then first_n_primes(i + 1, primes + [i], n)
else first_n_primes(i + 1, primes, n)
end
end
And as far as summing them up goes all I'll say is have a search for a ruby method called inject - also called reduce. It might be a bit brain-bending at first if you haven't come across the concept before but it's well worth learning! Very cool and very powerful.
Have fun!

Resources