Tracking the point of intersection of a simulated time series with a specific value over many runs in OpenBUGS - winbugs

I have an OpenBUGS model that uses observed data (y.values) over time (x.values) to simulate many runs (~100000) with new estimates of y-values (y.est) for each run. The observed data exhibit a pronounced decline from a maximum value.
I want to keep track of the length of time it takes for each run to decline from the maximum abundance (T.max) to 10% of the maximum abundance (T.10%). Because the maximum abundance value changes from run to run, 10% of that maximum will also vary from run to run, and thus T.10% will vary from run to run.
Setting a parameter to store T.max is easy enough, that doesn't vary from run to run because the maximum value is sufficiently greater than any other value.
What I can't figure out, is how to store the intersection of the y-est values and T.10%.
My first attempt was to determine whether each y-est value is above or below T.10% using the step() function:
above.below[i] <- step(T.10% - y.est[i])
This generates a string of ones and zeros for each y.est value (e.g., 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, etc.) If each run simply declined continuously from a maximum to a minimum, I could use the rank() function to determine how many above.below[i] values occur above T.10%:
decline.length <- rank(above.below[1:N], 0)
In this example, decline.length would be equal to the number of '0's in the string above, which is 9. Unfortunately, the y-est values occasionally display periods of growth following their decline below T.10%. So, the vector of above.below values can look like this: 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, etc. Thus, decline.length would equal 14 rather than 9, given the subsequent 0s in the vector.
What I want to do, is figure out how to store only the number of '0's in above.below prior to the first '1'; above.below[1:10] rather than above.below[1:N]. Unfortunately, it's not always the 10th time step in which the first '1' occurs, so I need to make the maximum extent of the range of above.below vary from run to run during the simulation.
I'm struggling to accomplish this in OpenBUGS since it's a non-procedural language, but I think it can be done, I just don't know the trick to do it. I'm hoping someone more familiar with the step() and rank() functions can lend some expert advice.
Any guidance is much appreciated!

Two solutions offered to me:
1) Calculate the cumulative sum up to each time step:
for (i in 1:N){
above.below[i] <- step(T.10% - y.est[i])
cum.above.below[i] <- sum(above.below[1:i])
}
decline.length <- rank(cum.above.below[1:N], 0)
2) Calculate whether each year is above or below the threshold directly, without 1s and 0s:
for(i in 1:N){
above.below[i] <- step(T.10% - y.est[i])
dummy[i] <- above.below[i] * i + (1 - above.below[i]) * (N+1)
}
decline.length <- ranked(dummy[], 1)
So dummy is i when above.below is 1, and dummy is N+1 when above.below is 0.

Related

How to create a deterministic finite automata for the "regular" function where states lead to more than one state depending on the value of an int

the manual of Minizinc says that we can pass an array to the "regular" function that represent the transitions between states of a DFA. For this state machine:
It puts this example:
array[STATE,SHIFT] of int: t =
[| 2, 3, 1 % state 1
| 4, 4, 1 % state 2
| 4, 5, 1 % state 3
| 6, 6, 1 % state 4
| 6, 0, 1 % state 5
| 0, 0, 1|]; % state 6
Where the row indicates the state, the first two rows indicate the value of "d" and "n", and the last one is the state that it leads to. However, it doesn't have any examples of how to aproach it if we need to make a state machine where the state can lead to more than one states, or where the variables of excitation aren't boolean. For instance:
I can't find it in the manual or in Google, thanks.
I am not familiar with Minizinc, but your first question does not depend on that: You are dealing with a deterministic automaton, so each input value can only lead to one other state, otherwise it would be non-deterministic.
As to your second question, if the possible values for x are restricted to 0, 1, 2, and 3, then you could re-phrase this as booleans: in analogy to the d/n/o example, the first column would give the state for x = 0, the second one for x = 1, etc. This does become unwieldy when x can have many values, but should work for your example.

Palindrome Explanation

I encountered the following in a leetcode article to determine whether an integer is a palindrome
Now let's think about how to revert the last half of the number. For number 1221, if we do 1221 % 10, we get the last digit 1, to get the second to the last digit, we need to remove the last digit from 1221, we could do so by dividing it by 10, 1221 / 10 = 122. Then we can get the last digit again by doing a modulus by 10, 122 % 10 = 2, and if we multiply the last digit by 10 and add the second last digit, 1 * 10 + 2 = 12, it gives us the reverted number we want. Continuing this process would give us the reverted number with more digits.
Now the question is, how do we know that we've reached the half of the number?
Since we divided the number by 10, and multiplied the reversed number by 10, when the original number is less than the reversed number, it means we've processed half of the number digits.
Can someone explain the last two sentences please?! Thank you!
Here is the enclosed C# code:
public class Solution {
public bool IsPalindrome(int x) {
// Special cases:
// As discussed above, when x < 0, x is not a palindrome.
// Also if the last digit of the number is 0, in order to be a palindrome,
// the first digit of the number also needs to be 0.
// Only 0 satisfy this property.
if(x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
int revertedNumber = 0;
while(x > revertedNumber) {
revertedNumber = revertedNumber * 10 + x % 10;
x /= 10;
}
// When the length is an odd number, we can get rid of the middle digit by revertedNumber/10
// For example when the input is 12321, at the end of the while loop we get x = 12, revertedNumber = 123,
// since the middle digit doesn't matter in palidrome(it will always equal to itself), we can simply get rid of it.
return x == revertedNumber || x == revertedNumber/10;
}
}
The reason is due to the original given input, x will be decreasing by 1 digit while the reverted string increases by 1 digit at the same time. The process keeps on going until x is less than or equal to the reverted string. Hence due to the change length changes, when it terminates, we would approximately reach half of the string.
Let's visit a few examples with positive numbers to understand the process. I would write (x,y) as the (original number, reverted string). The third example is purposely designed to show that it need not be exactly half though but the code would still work.
The first example is 1221, where there are even number of digits. It will go from (1221, 0) to (122, 1) to (12, 12), at this stage, the two terms are equal and hence the process terminates and we can conclude that it is a palindrome.
The next example is 1223, where there are even number of digits. It will go from (1223, 0) to (122, 3) to (12, 32), at this stage, the termination condition holds and hence the process terminates and we can conclude that it is not a palindrome.
Now, the third example is 1211,then the sequence is (1211,0), (121, 1), (12,11), (1,112), after which we terminates from the string and it would conclude that it is not a palindrome
Now, let's make the number consists of odd number of digits:
For 12321. It will go from (12321, 0) to (1232, 1) to (123, 12) to (12, 123) and at this point, the condition breaks. We then divide the reverted string by 10 and we end up with (12,12) and we can conclude that it is a palindrome.
For 12323. It will go from (12323, 0) to (1232, 3) to (123, 32) to (12, 323) and at this point, the condition breaks. We then divide the reverted string by 10 and we end up with (12,32) and we can conclude that it is not a palindrome.
For 12311. It will go from (12311, 0) to (1231, 1) to (123, 11) to (12, 113) and at this point, the condition breaks. We then divide the reverted string by 10 and we end up with (12,11) and we can conclude that it is not a palindrome.
I hope these examples would help you to understand what the post mean.

How to merge two tensors at the beginning of a network in Torch?

Given the following beginning of a network
local net = nn.Sequential()
net:add(SpatialConvolution(3, 64, 4, 4, 2, 2, 1, 1))
with an input tensor input
local input = torch.Tensor(batchSize, 3, 64, 64)
// during training
local output = net:forward(input)
I want to modify the network to accept a second tensor cond as input
local cond = torch.Tensor(batchSize, 1000, 1, 1)
// during training
local output = net:forward({input, cond})
I modified the network by adding a JoinTable before the SpatialConvolution is added, like so:
local net = nn.Sequential()
net:add(nn.JoinTable(2, 4))
net:add(SpatialConvolution(3, 64, 4, 4, 2, 2, 1, 1))
This is not working because both tensors have different sizes in dimensions 2, 3, and 4. Giving the cond tensor as size of (batchSize, 1000, 64, 64) is not an option since its a waste of memory.
Is there any best practise for merging two different tensors at the beginning of a network to be feed into the first layer.
There is no such thing as "merging" tensors which do not have compatible shapes. You should simply pass a table of tensors and start your network with SelectTable operation and work with nngraph, not simple Sequential. In particular - how would you expect Spatial Convolution to work on such odd "tensor" which "narrows down" to your cond? There is no well defined operation in mathematics for such use case, thus you have to be more specific (which you will achieve with nngraph and SelectTable).

How to put numbers into an array and sorted by most frequent number in java

I was given this question on programming in java and was wondering what would be the best way of doing it.
The question was on the lines of:
From the numbers provided, how would you in java display the most frequent number. The numbers was: 0, 3, 4, 1, 1, 3, 7, 9, 1
At first I am thinking well they should be in an array and sorted first then maybe have to go through a for loop. Am I on the right lines. Some examples will help greatly
If the numbers are all fairly small, you can quickly get the most frequent value by creating an array to keep track of the count for each number. The algorithm would be:
Find the maximum value in your list
Create an integer array of size max + 1 (assuming all non-negative values) to store the counts for each value in your list
Loop through your list and increment the count at the index of each value
Scan through the count array and find the index with the highest value
The run-time of this algorithm should be faster than sorting the list and finding the longest string of duplicate values. The tradeoff is that it takes up more memory if the values in your list are very large.
With Java 8, this can be implemented rather smoothly. If you're willing to use a third-party library like jOOλ, it could be done like this:
List<Integer> list = Arrays.asList(0, 3, 4, 1, 1, 3, 7, 9, 1);
System.out.println(
Seq.seq(list)
.grouped(i -> i, Agg.count())
.sorted(Comparator.comparing(t -> -t.v2))
.map(t -> t.v1)
.toList());
(disclaimer, I work for the company behind jOOλ)
If you want to stick with the JDK 8 dependency, the following code would be equivalent to the above:
System.out.println(
list.stream()
.collect(Collectors.groupingBy(i -> i, Collectors.counting()))
.entrySet()
.stream()
.sorted(Comparator.comparing(e -> -e.getValue()))
.map(e -> e.getKey())
.collect(Collectors.toList()));
Both solutions yield:
[1, 3, 0, 4, 7, 9]

Average saved output from multiple runs of function

I have a function that has 11 input parameters.
MyFunction(40, 40, 1, 1, 1, 5, 0, 1, 0, 1500, 'MyFile');
The input parameter 'MyFile' when passed through the MyFunction saves a text file using the save command that is 6 columns by the 10th input parameter of rows (e.g. 1500). I usually then load this files back into MATLAB when I am ready to analyze different runs.
I'd like to run MyFunction m times and ultimately have the 'MyFile' be a measure of central tendency (e.g. mean or median) of those m runs.
m=10
for i = 1:m;
MyFunction(40, 40, 1, 1, 1, 5, 0, 1, 0, 1500, 'MyFile');
end;
I could use the for-loop to generate a new 'MyFile' name for each iteration (e.g. MyFile1, MyFile2,...,MyFileM) with something like MyFile = sprintf('MyFile%m'); and then load all of the MyFiles back into MATLAB and then take their average and save it as a UltimateMyFile, but this seems cumbersome. Is their a better method to average these output files more directly? Should I store the files as an object, use dlmwrite, or -append?
Thanks.
since you are trying to find median, you need access to all the data.
you can define a 3 dimension array say
data = zeros(1500,6,m);
and then at each step of for loop update it:
data(:,:,i) = MyFunction(40, 40, 1, 1, 1, 5, 0, 1, 0, 1500);
of course you will need to redefine your function to get the right output.
However if you need to access the data at some other time, then you are better of writing it to a file and reading it from there.
in case you are only interested in the average, you can keep a running total as each case is analyzed and then then just divide it by number of cases (m).