I am creating a procedure that uses an if statement to perform a decision.
I have four variables: Altitude, Velocity, Angle and Temperature.
The procedure is as follows:
procedure Test3 is
begin
if (Integer(Status_System.Altitude_Measured)) >= Critical_Altitude
and (Integer(Status_System.Velocity_Measured)) >= Critical_Velocity
and (Integer(Status_System.Angle_Measured)) >= Critical_Angle
and (Integer(Status_System.Temperature_Measured)) >= Critical_Temperature
then
DT_Put ("message 1");
else
null;
end if;
end Test3;
This procedure is bassicaly taking the idea that if all the critcal values for the variables are met for each and every variable then it will print a message.
I want to be able to have a shorter way of paring up the statements so I can do the following:
If I have 4 variables: Altitude, velocity, angle and temperature
and I want to have a statement that says, If atleast 3 of these varibles (doesnt matter which three) are all exceeding their critical values
then display a message.
Is it even possible to do this?
I would hate to think that I would have to write each and every possible combination for the if statements.
In short, I want an if statement that says at least 3 of the variables shown are at their criticle value so print a message.
The same would be good for atleast 2 of these variables as well.
First, you should try to use specific types for altitude, velocity, angle and temperature. By using different types you'll leverage strong typing provided by Ada and avoid mistakes such as mixing or comparing altitudes and temperatures. Your example suggests that all of them are Integer. One possible definition could be (there are many others):
type Temperature is digits 5 range -273.15 .. 300.0;
type Angle is digits 5 range -180.0 .. 180.0;
The advantage of such definition is that you define both the range of values and the precision (captors all have a finite precision).
Counting the number of errors is one way do that.
In Ada 2012, you could write:
EDIT
Errors : Natural := 0;
...
Errors := Errors + (if Altitude_Measured > Critical_Altitude then 1 else 0);
Errors := Errors + (if Velocity_Measured > Critical_Velocity then 1 else 0);
Errors := Errors + (if Angle_Measured > Critical_Angle then 1 else 0);
Errors := Errors + (if Temperature_Measured > Critical_Temperature then 1 else 0);
if Errors >= 2 then
...
end if;
Boolean is an enumeration type with values (False, True). As with any enumeration type, the 'Pos attribute can be used to get the position of a value in the list of enumeration literals. Thus, Boolean'Pos(B) equals 0 if B is false, 1 if B is true.
Thus you could say
True_Count := Boolean'Pos(Integer(Status_System.Altitude_Measured) >= Critical_Altitude)
+ Boolean'Pos(Integer(Status_System.Velocity_Measured) >= Critical_Velocity)
+ Boolean'Pos(Integer(Status_System.Angle_Measured) >= Critical_Angle)
+ Boolean'Pos(Integer(Status_System.Temperature_Measured)) >= Critical_Temperature);
Related
Goal: perform rolling window calculations on panel data in Stata with variables PanelVar, TimeVar, and Var1, where the window can change within a loop over different window sizes.
Problem: no access to SSC for the packages that would take care of this (like rangestat)
I know that
by PanelVar: gen Var1_1 = Var1[_n]
produces a copy of Var1 in Var1_1. So I thought it would make sense to try
by PanelVar: gen Var1SumLag = sum(Var1[(_n-3)/_n])
to produce a rolling window calculation for _n-3 to _n for the whole variable. But it fails to produce the results I want, it just produces zeros.
You could use sum(Var1) - sum(Var1[_n-3]), but I also want to be able to make the rolling window left justified (summing future observations) as well as right justified (summing past observations).
Essentially I would like to replicate Python's ".rolling().agg()" functionality.
In Stata _n is the index of the current observation. The expression (_n - 3) / _n yields -2 when _n is 1 and increases slowly with _n but is always less than 1. As a subscript applied to extract values from observations of a variable it always yields missing values given an extra rule that Stata rounds down expressions so supplied. Hence it reduces to -2, -1 or 0: in each case it yields missing values when given as a subscript. Experiment will show you that given any numeric variable say numvar references to numvar[-2] or numvar[-1] or numvar[0] all yield missing values. Otherwise put, you seem to be hoping that the / yields a set of subscripts that return a sequence you can sum over, but that is a long way from what Stata will do in that context: the / is just interpreted as division. (The running sum of missings is always returned as 0, which is an expression of missings being ignored in that calculation: just as 2 + 3 + . + 4 is returned as 9 so also . + . + . + . is returned as 0.)
A fairly general way to do what you want is to use time series operators, and this is strongly preferable to subscripts as (1) doing the right thing with gaps (2) automatically working for panels too. Thus after a tsset or xtset
L0.numvar + L1.numvar + L2.numvar + L3.numvar
yields the sum of the current value and the three previous and
L0.numvar + F1.numvar + F2.numvar + F3.numvar
yields the sum of the current value and the three next. If any of these terms is missing, the sum will be too; a work-around for that is to return say
cond(missing(L3.numvar), 0, L3.numvar)
More general code will require some kind of loop.
Given a desire to loop over lags (negative) and leads (positive) some code might look like this, given a range of subscripts as local macros i <= j
* example i and j
local i = -3
local j = 0
gen double wanted = 0
forval k = `i'/`j' {
if `k' < 0 {
local k1 = -(`k')
replace wanted = wanted + L`k1'.numvar
}
else replace wanted = wanted + F`k'.numvar
}
Alternatively, use Mata.
EDIT There's a simpler method, to use tssmooth ma to get moving averages and then multiply up by the number of terms.
tssmooth ma wanted1=numvar, w(3 1)
tssmooth ma wanted2=numvar, w(0 1 3)
replace wanted1 = 4 * wanted1
replace wanted2 = 4 * wanted2
Note that in contrast to the method above tssmooth ma uses whatever is available at the beginning and end of each panel. So, the first moving average, the average of the first value and the three previous, is returned as just the first value at the beginning of each panel (when the three previous values are unknown).
Suppose I want to solve the equation x + 3 = 40 using GNU bc. One way I could do this would be to start by checking to see if 0 is a solution, then checking 1, and so on, until I get to the right answer. (Obviously not the best way to do algebra, but oh well.) So I enter the following code into GNU bc:
int solver(int x);
define solver(x){
if(x + 3 == 40) return x;
x = x + 1;
solver(x)
}
solver(0)
It produces 37 - the right answer, of course - but the 37 is then followed by 37 zeros. Based on some experimentation, it seems like each zero comes from an instance of the if statement being false, but how do I prevent the zeros from showing up? I'm using GNU bc to solve more complicated functions and create more complex lists of numbers, so it really isn't practical for me to sort through all the zeros. Any help would be appreciated, since I haven't yet figured anything out.
For each operation that isn't an assignment, bc prints an exit status. One way to suppress that is to assign to the dummy value . (which is just the value of the last result anyway), another way is to make sure you explicitly print exactly what you need.
I would have written your function like this:
#!/usr/bin/bc -q
define solver(x) {
if (x + 3 == 40) return x
return solver(x+1)
}
print solver(0), "\n"
quit
A few remarks for your attempt:
I don't understand what your first line is supposed to do, I just dropped it
I've indented the code, added some whitespace and removed the semicolons – mostly a matter of taste and readability
I've simplified the recursive call to avoid the solver(x) line stand on its own, as this produces the spurious 0
As for your suspicion that the if statement produces the zeroes: try, in an interactive session, the following:
1 == 2 # Equality test on its own produces output
0
1 == 1 # ... for both true and false statements
1
if (1 == 2) print "yes\n" # No output from false if condition
if (1 == 1) print "yes\n" # If statement is true, print string
yes
How can I check if the value in cell #0 is equal to the value in cell #1? I am trying to write code equivalent to:
if(a == b)
{
//do stuff
}
else
{
//do something else
}
I have read Brainfuck compare 2 numbers as greater than or less than, and the second answer gave me a general idea of what I'd need to do, but I cannot figure it out. (That solution gives if a < b, else.)
I am thinking I need to do something along the lines of decrementing both values, and if they reach 0 at the same time, then they are true. But I keep getting stuck at the same exit point every time I think about it.
How can I check if two cells are equal in brainfuck?
I think I have it, I'm not a brainfuck expert but this question looked interesting. There might be a simpler way to do it, but I went with your method of decrementing values one by one.
In this case, if the two values in cell 0 and 1 are equal jump a ton forward, if they are not equal jump a little forward (second brackets is the not equal case, third brackets is the equal case)
Note that I'm using brainfucks while statements as a ghetto if (cell != 0)
+++++++++++++++++
>
+++++++++++++++++
>+<
[ - < - >] <[>>>>>] >> [>>>>>>>>>>>>>>>>>>>>>]
Try it online: http://fatiherikli.github.io/brainfuck-visualizer/#KysrKysrKysrKysrKysrKysKPgorKysrKysrKysrKysrKysrKwo+KzwKWyAtIDwgLSA+XSA8Wz4+Pj4+XSA+PiBbPj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+XQoKCg==
An example implementation, print T (true) if the two values are equal, F (false) if they are not equal
http://fatiherikli.github.io/brainfuck-visualizer/#KysrCj4KKysrKwo+KzwKWyAtIDwgLSA+XSA8Wz4+PgorKysrKysrKysrKysrKysrKysrKworKysrKysrKysrKysrKysrKysrKworKysrKysrKysrKysrKysrKysrKworKysrKysrKysrCi4KPgoKXSA+PiBbCisrKysrKysrKysrKysrKysrKysrCisrKysrKysrKysrKysrKysrKysrCisrKysrKysrKysrKysrKysrKysrCisrKysrKysrKysrKysrKysrKysrCisrKwouCj4KXQ==
+>>(a+++++)>(b+++++)>>+<<<
[[->]<<]
<
[>>>>>-<<<<<
a>b
]
>>
[->>-<
a<b
]
>>
[-
a=b
]
Pointer ends on the same pointer in the same state but the code within the appropriate brackets has been executed.
I came up with this for my bf compiler thing
basically it subtracts and then checks if the result is 0.
Can be easily changed to execute stuff in if/else-ish way
Layout:
[A] B
>[-<->]+<[>-<[-]]>
Output
0 [result]
Result is 1 if equal
I'm new to OpenModelica and I've a few questions regarding the code of 'BouncingBall.mo' which is distributed with the software as example code.
1) what's the difference between 'when' and 'if'?
2)what's the purpose of variable 'foo' in the code?
3)in line(15) - "when {h <= 0.0 and v <= 0.0,impact}",, shouldn't the expression for 'when' be enough as "{h <= 0.0 and v <= 0.0}" because this becomes TRUE when impact occurs, what's the purpose of impact(to me its redundant here) and what does the comma(,) before impact means?
model BouncingBall
parameter Real e = 0.7 "coefficient of restitution";
parameter Real g = 9.81 "gravity acceleration";
Real h(start = 1) "height of ball";
Real v "velocity of ball";
Boolean flying(start = true) "true, if ball is flying";
Boolean impact;
Real v_new;
Integer foo;
equation
impact = h <= 0.0;
foo = if impact then 1 else 2;
der(v) = if flying then -g else 0;
der(h) = v;
when {h <= 0.0 and v <= 0.0,impact} then
v_new = if edge(impact) then -e * pre(v) else 0;
flying = v_new > 0;
reinit(v, v_new);
end when;
end BouncingBall;
OK, that's quite a few questions. Let me attempt to answer them:
What is the difference between when and if.
The questions inside a when clause are only "active" at the instant that the conditional expressions used in the when clause becomes active. In contrast, equations inside an if statement are true as long as the conditional expression stays true.
What's the purpose of foo?
Probably for visualization. It has no clear impact on the model that I can see.
Why is impact listed in the when clause.
One of the problems you have so-called Zeno systems like this is that it will continue to bounce indefinitely with smaller and smaller intervals. I suspect the impact flag here is meant to indicate when the system has stopped bouncing. This is normally done by checking to make sure that the conditional expression h<=0.0 actually becomes false at some point. Because event detection includes numerical tolerancing, at some point the height of the bounces never gets outside of the tolerance range and you need to detect this or the ball never bounces again and just continues to fall. (it's hard to explain without actually running the simulation and seeing the effect).
What does the , do in the when clause.
Consider the following: when {a, b} then. The thing is, if you want to have a when clause trigger when either a or b become true, you might think you'll write it as when a or b then. But that's not correct because that will only trigger when the first one becomes true. To see this better, consider this code:
a = time>1.0;
b = time>2.0;
when {a, b} then
// Equation set 1
end when;
when a or b then
// Equation set 2
end when;
So equation set 1 will get executed twice here because it will get executed when a becomes true and then again when b becomes true. But equation set 2 will only get executed once when a becomes true. That's because the whole expression a or b only becomes true at one instant.
These are common points of confusion about when. Hopefully these explanations help.
I have to calculate the value of arctan(x) . I have calculated the value of this by evaluating the following series :
Arctan (x) = x – x^3/3 + x^5/5 – x^7/7 + x^9/9 - …
But the following code can not calculate the actual value. For example, calculate_angle(1) returns 38.34 . Why?
const double DEGREES_PER_RADIAN = 57.296;
double calculate_angle(double x)
{
int power=5,count=3;
double term,result,prev_res;
prev_res = x;
result= x-pow(x,3)/3;
while(abs(result-prev_res)<1e-10)
{
term = pow(x,power)/power;
if(count%2==0)
term = term*(-1);
prev_res=result;
result=result+term;
++count;
power+=2;
// if(count=99)
// break;
}
return result*DEGREES_PER_RADIAN;
}
EDIT: I found the culprit. You forgot to include stdlib.h, where the function abs resides. You must have ignored the warning about abs being implicitly declared. I checked that removing the include yields the result 38.19 and including it yields the result ~45.
The compiler is not required to stop compilation when an undeclared function is being used (in this case abs). Instead, it is allowed to make assumptions on how the function is declared (in this case, wrong one.)
Besides, like other posters already stated, your use of abs is inappropriate as it returns an int, not a double or float. The condition in the while should be >1e-100 not <1e-100. The 1e-100 is also too small.
--
You forgot to increase count and power after calculating the first two summands:
prev_res = x;
result= x-pow(x,3)/3;
count = 4; <<<<<<
power = 5; <<<<<<
while(abs(result-prev_res)<1e-100)
{
term = pow(x,power)/power;
if(count%2==1)
term = term*(-1);
Also I consider your use of the count variable counterintuitive: it is intialized with 3 like if it denotes the last used power; but then, loop iterations increase it by 1 instead of 2 and you decide the sign by count%2 == 1 as opposed to power%4 == 3
The series converges to tan^{-1} x, but not very fast. Consider the series when x=1:
1 - 1/3 + 1/5 - 1/7 + 1/9 - ...
What is the error when truncating at the 1/9 term? It's around 1/9. To get 10^{-100} accuracy, you would need to have 10^{100} terms. The universe would end before you'd get that. And, catastrophic round-off error and truncation error would make the answer utterly unreliable. You only have 14 digits to play with for doubles.
Look at reference works like Abramowitz and Stegun [AMS 55] or the new NIST Digital Library of Mathematical Functions at http://dlmf.nist.gov to see how these are done in practice. Often, one uses Padé approximants instead of Taylor series. Even when you stick with Taylor series, you often use Chebyshev approximation to cut down on the total error.
I also recommend Numerical Methods that [Usually] Work, by Forman Acton. Or the Numerical Recipes in ... series.
Your sign is the wrong way around after the first two terms. It should be:
if(count%2==0)
term = term*(-1);
Your comparison is the wrong way around in the while condition. Also, you're expecting an unrealistically high level of precision. I would suggest something more like this:
while(fabs(result-prev_res)>1e-8)
Finally, you'll get a more accurate result with a better value for DEGREES_PER_RADIAN. Why not something like this:
const double DEGREES_PER_RADIAN = 180/M_PI;