How to round a real number? - vdm++

Say I wanted to round a real number to a natural number, how could I do this in VDM++? The MATH library does not appear to have any function that does this.
Thanks,
Ricardo

There is a "floor" operator in VDM. This returns the largest integer that is less than or equal to its argument.
> p floor 1.23
= 1
Executed in 0.034 secs.
> p floor -1.23
= -2
Executed in 0.002 secs.
> p floor 123
= 123
Executed in 0.001 secs.
>

Related

How to identify recurring patterns in time-series data in Matlab

I am calculating ENSO indices using Matlab and one condition is that I have to find anomalous sea surface temperatures. The condition is that an El Niño event is characterised by sea surface temperatures that are 0.5 degrees above the normalised "0-value" for 5 months. I have gotten as far as to make my monthly time series data logical (i.e. "1" is a monthly data value above 0.5 and "0" is a monthly data value below 0.5), but I wanted to know if there was a command in Matlab that allows me to identify when this value repeats 5 times or more.
As an example code:
Monthly_data=[0 0 1 1 1 1 1 0 0 0 1 1 0 0 0 0 1 0 1 1 1 1 1 1 1 0]
I would ideally need a command that finds when a minimum of five "1"s occur after each other. Does this exist?
If more info is needed please let me know, I am new to matlab so I am not yet sure of the structure and syntax that is valued for asking questions on here.
Thank you!
not sure this is what you need but perhaps gives you some direction.
> x = diff(Monthly_data);
> find(x==-1)-find(x==1)
ans =
5 2 1 7
these are the lengths of the 1 sequences. You may need to pad front and end of the array with 0 to eliminate sequences missing one boundary.
To find the start index of the sequence longer than 5:
> s=find(x==1);
> s(find(x==-1)-s>5)
ans = 18
or
> s(find(x==-1)-s>=5)
ans =
2 18
note that because of the diff lag, these are one more than the array index, or consider it as position for zero based indexing.

Given a positive number , how to determine its surrounding integers in matlab

Can someone please explain how to get the surrounding integers for a given positive number ( for ex. if number is 18.2378 then it should return 18 and 19 )
(I actually need this to determine that the given number is between 0-1 or 2-3 or 4-5 and so on....and if it is in between 0-1 or 2-3 or 4-5 etc then some expression evaluates , else some other expression must evaluate.)
The floor and ceil functions do this:
x = 18.2378;
floor(x); %Returns 18
ceil(x); %Returns 19
floor(18.2378) will return 18 i.e. the previous nearest integer.
ceil(18.2378) will return 19 i.e. the next nearest integer
You can use round or floor or ceil in Matlab to turn decimal numbers into integers. Round will round up or down depending on the decimal value, floor rounds toward minus infinity, and ceil rounds toward positive infinity.
Here is an example of how this could work:
n=18.2378;
F=floor(n);
C=ceil(n);
TF=F<n<C;
F returns 18. C returns 19. TF will return 1 if the number is between the floor and the ceiling--But, if you do it this way the number will always be between its floor and ceiling--and 0 if it is not. You can do this iteratively in a loop as many times as you need.

Random number generation - code not working as it should

So I have to generate a random number (called 'p' here) between 0 and 90 whose frequency distribution is a cosine function (i.e I should have more numbers between 0 and 45 than numbers between 45 and 90).
I am working on matlab
The code is as follows -
flag = 1;
while flag == 1
candidate = randi([0,90]);
if rand < cosd( candidate )
p = candidate;
flag = 2;
end
end
I am generating 20 such numbers but always I get most of the numbers towards the higher end (45-90).
From those 20 numbers, there is hardly 1-2 numbers < 45.
Is my code wrong?
EDIT: Okay, so I got the answer. I tried running the code separately as follows-
for i = 1:20
flag = 1;
while flag == 1
candidate = randi([0,90]);
if rand < cosd( candidate )
p = candidate;
flag = 2;
disp(p);
end
end
end
And I'm getting most of the values of p between 0 and 45. My original code had an external 'if' condition which was the reason for only accepting higher values of 'p'. I used a while loop and the number of iterations were much more than 20 to get 20 values of 'p'.
Here is my original code snippet -
while zz <=20
d = randi([0,359]);
flag = 1;
while flag == 1
c = randi([0,90]);
x = rand(1);
if x < cosd(c)
p = c;
flag = 2;
end
end
if 'external condition'
strike(zz) = d;
dip(zz) = p;
slip(zz) = round(i);
zz= zz+1;
end
end
If you just want to get answer, read the last line. But if you want to know that why that answer is right, read the explanation.
Assume that you have a distinct distribution function like this:
f(0)=1;
f(1.5)=10;
f(4)=9;
So the cumulative function is:
F(0)=1;
F(1.5)=11;
F(4)=20;
No we want to have a relative cumulative function, as F(4)=20 (4 is the last item), we divide cumulative function by 20. So it would be:
F'(0)=0.05
F'(1.5)=0.55
F'(4)=1.00
Now, we generate a random number between 0 and 1. Every time we generate a random number, we generate a value for F'(x) and if F'(x) does not have that value anywhere, we use nearest bigger number (like y) which for some x, F(x)=y. For my example, based on relative cumulative function:
If the random number was less than 0.05, our distribution-based random number is 1.5
If the random number was between 0.05 and 0.55, our distribution-based random number is 2,
If was more than 0.55, our distribution-based random number is 4
We should do a similar work with continuous distribution functions. The difference is that in continuous world, we use integral instead of cumulative function. So for your question, we have:
f(x)=cos(x) , 0<=x<=90
F(x)=sin(x)-sin(0)=sin(x) , 0<=x<=90
F'(x)=cos(x) , 0<=x<=90 (Because F(90)=1)
Now we generate a random number between 0 and 1 (like r). So we have:
F'(x)=r => sin(x)=r => x=arcsin(r)
Actually, you just need to generate a random number between 0 and 1 and calculate the arcsin of that.

What is the meaning of number 1e5?

I have seen in some codes that people define a variable and assign values like 1e-8 or 1e5.
for example
const int MAXN = 1e5 + 123;
What are these numbers? I couldn't find any thing on the web...
1e5 is a number expressed using scientific notation and it means 1 multiplied by 10 to the 5th power (the e meaning 'exponent')
so 1e5 equals 1*100000and is equal to 100000, the three notations are interchangeable meaning the same.
1e5 means 1 × 105.
Similarly, 12.34e-9 means 12.34 × 10−9.
Generally, AeB means A × 10B.
this is scientific notation for 10^5 = 100000
1e5 is 100000. 5 stand for the amount of zeros you add in behind that number. For example, lets say I have 1e7. I would put 7 zeros behind 1 so it will become 10,000,000. But lets say that the number is 1.234e6. You would still add 6 zeros at the end of the number so it's 1.234000000, but since there is that decimal, you would have to move it to the right 6 times since it's e6.
The values like:
1e-8 or 1e5
means;
1e-8 = 1 * 10^(-8)
And
1e5 = 1 * 10

access columns of row at index matlab

I have a text file A with N rows and 8 columns (example below):
1 2 0.02 0.28 0.009 0.04 0.03 0.16
2 4 0.04 0.21 0.4 0.04 0.03 0.13
if my variables x=2 and y=4 (I get during the program run -values change with every run.)
I know the index of the row I need to get:
rIndex = find((A{1}==x)&(A{2}==y));
here rindex = 2.
I need to access row at rIndex and do operation with columns 3 to 8 in that row. i.e. i get values from another file based on x and y and divide those values by column values at rIndex row.
x_No = 5, y_No = 6;
B = horzcat((x_No-y_No)./A{3}(1),(x_No-y_No))./A{4}(1),(x_No-y_No)./A{5}(1),(x_No-y_No)./A{6}(1),(x_No-y_No)./A{7}(1),(x_No-y_No)./A{8}(1));
What B does right now is operates on all rows from A. I need only at particular rIndex.
Its still not really clear what happens, but I think you can try something like this:
for r = 1:numel(rIndex)
t=rIndex(r);
result(r,:) = horzcat((x_No-y_No)./A{3}(t),(x_No-y_No))./A{4}(t),(x_No-y_No)./A{5}(t),(x_No-y_No)./A{6}(t),(x_No-y_No)./A{7}(t),(x_No-y_No)./A{8}(t));
end
I may be doing too much actually, but hopefully this helps.