Count the maximum number of condition A within condition B, for a specific lookback - view

I have a piece of code that counts the number of condition A and it resets to 0 when condition B happens.
For example, each time the price crossover the sma(close,14) (this is condition A), the counter increases. Starts at 0, and counts.
But then, when the price crossover the sma(close, 50) (this is condition B), the counter goes back to 0.
When plotting this oscillator, the results shows a line that goes from 0 to count A and then resets when condition B happens.
What I am trying to do is to count the maximum number of condition A within a specific lookback range.
For example, with the last 250 bars, the first wave had 5 times condition A, the second wave had 13 times condition A and the third wave had 2 times the condition A.
I am trying to count the max number of crosses within each wave for the lookback period. In this example, 13 times.
I tried with counters, different sums combination, and ended up trying with arrays but I can't seem to make it happen with the arrays.
I do think there is a way if i could store the counts of each wave into an array, and create new arrays for each new wave within the lookback, but I'm having a hard time to code it.
Any help greatly appreciated!
sma14 = sma(close,14)
sma50 = sma(close,50)
condition_A = crossover(close,sma14)
condition_B = crossover(close,sma50)
if condition_B
counter := 0
if condition_A
counter := counter + 1
if condition_A and condition_B
counter := 0
For i=0 to i_lookback
Count if?

Related

Verilog: Minimal (hardware) algorithm for multiplying a binary input to its delayed form

I have a binary input in (1 bit serial input) which I want to delay by M clock pulses and then multiply (AND) the 2 signals. In other words, I want to evaluate the sum:
sum(in[n]*in[n+M])
where n is expressed in terms of number of clock pulses.
The most straightforward way is to store in a memory buffer in_dly the latest M samples of in. In Verilog, this would be something like:
always #(posedge clock ...)
...
in_dly[M-1:0] <= {in_dly[M-2:0], in};
if (in_dly[M-1] & in)
sum <= sum + 'd1;
...
While this works in theory, with large values of M (can be ~2000), the size of the buffer is not practical. However, I was thinking to take advantage of the fact that the input signal is 1 bit and it is expected to toggle only a few times (~1-10) during M samples.
This made me think of storing the toggle times from 2k*M to (2k+1)*M in an array a and from (2k+1)*M to (2k+2)*M in an array b (k is just an integer used to generalize the idea):
reg [10:0] a[0:9]; //2^11 > max(M)=2000 and "a" has max 10 elements
reg [10:0] b[0:9]; //same as "a"
Therefore, during M samples, in = 'b1 during intervals [a[1],a[2]], [a[3],a[4]], etc. Similarly, during the next M samples, the input is high during [b[1],b[2]], [b[3],b[4]], etc. Now, the sum is the "overlapping" of these intervals:
min(b[2],a[2])-max(b[1],a[1]), if b[2]>a[1] and b[1]<a[2]; 0 otherwise
Finally, the array b becomes the new array a and the next M samples are evaluated and stored into b. The process is repeated until the end of in.
Comparing this "optimized" method to the initial one, there is a significant gain in hardware: initially 2000 bits were stored, and now 220 bits are stored (for this example). However, the number is still large and not very practical..
I would greatly appreciate if somebody could suggest a more optimal (hardware-wise) way or a simpler way (algorithm-wise) of doing this operation. Thank you in advance!
Edit:
Thanks to Alexey's idea, I optimized the algorithm as follows:
Given a set of delays M[i] for i=1 to 10 with M[1]<M[2]<..<M[10], and an input binary array in, we need to compute the outputs:
y[i] = sum(in[n]*in[n+M[i]]) for n=1 to length(in).
We then define 2 empty arrays a[j] and b[j] with j=1,~5. Whenever in has a 0->1 transition, the smallest index empty element a[j] is "activated" and will increment at each clock cycle. Same goes for b[j] at 1->0 transitions. Basically, the pairs (a[j],b[j]) represent the portions of in equal to 1.
Whenever a[j] equals M[i], the sum y[i] will increment by 1 at each cycle while in = 1, until b[j] equals M[i]. Once a[j] equals M[10], a[j] is cleared. Same goes for b[j]. This is repeated until the end of in.
Based on the same numerical assumptions as the initial question, a total of 10 arrays (a and b) of 11 bits allow the computation of the 10 sums, corresponding to 10 different delays M[i]. This is almost 20 times better (in terms of resources used) than my initial approach. Any further optimization or idea is welcomed!
Try this:
make array A,
every time when in==1 get free A element and write M to it.
every clock decrement all non-zero A elements,
once any decremented element becomes zero, test in, if in==1 - sum++.
Edit: algorithm above intended for input like
- 00000000000010000000100010000000, while LLDinu realy needs
- 11111111111110000000011111000000, so here is modified algorithm:
make array (ring buffer) A,
every time when in toggles, get free A element and write M to it.
every clock decrement all non-zero A elements,
every clock test in, if in==1 and number of non-zero A elements is even - sum++.

Transforming set of arbitrary intervals into set of continuous intervals, where possible

I have a practical situation, where I need to minimize amount of data.
Let's say I'm given a set of intervals of normal numbers.
e.g. N1 = {(0,1],(1,2],(3,4]};
I would like to minimize this set to:
N2 = {(0,2],(3,4]};
So basically what I need is to combine multiple small intervals into continuous intervals, where it is possible.
Is there any clever/efficient algorithms for doings this? Because I would like to avoid inefficient for-each-ing.
*If this problem have some wide-known name, please name it in the comments.
This is a sweep-line algorithm.
Split the intervals into start and end points.
Sort the points.
Let count = 0.
Iterate through the points:
Whenever you encounter an end point:
Decrement the count.
If the count = 0, record this point.
Whenever you encounter a start point.
If the count = 0, record this point.
Increment the count.
As a technical note, when sorting, if both a start point and an end point have the same value, put the start point first, otherwise you may record that as a gap, as opposed to a continuous interval.
Example:
(0,1],(1,2],(3,4]
Split 0 start, 1 start, 1 end, 2 end, 3 start, 4 end
Count 1 2 1 0 1 0
Record (0 N/A N/A 2] (3 4]
Getting the recorded values gives us {(0,2], (3,4]}.

n nested for loops in fortran90

i have read some topics on this, but i don't quite think it answers my question. if it does then please direct me to the correct topic and i will definitely look again.
here is my problem:
i want to write a for loop which will cycle through every possible combination of an array where the array is of length 'n'.
that is, if n = 2 then my for loop would be
do i1 = 1,2
do i2 = 1,2
! do stuff here
enddo
enddo
while if n = 3 then my array would look like
do i1 = 1,3
do i2 = 1,3
do i3 = 1,3
! do stuff here
enddo
enddo
enddo
and so on. how would i go about writing a routine which would do this automatically by simply an an input variable 'n'?
if you write out the indices, what you have is an n-digit number in base n (almost - there's an offset of 1 because you are using 1-based indices in fortran). and what you are asking for is every possible value that number can take.
in other words, if we use 0-based indices for a moment for simplicity, you have:
n=2, values=00,01,10,11 (binary counting from 0 to 3)
n=3, values=000,001,002,010,011,012,020,021,022, 100,101,102,110,111,112,120,121,122, 200,201,202,210,211,212,220,221,222 (ternary(?) counting from 0 to 26)
so what you are asking is how to do this in the general case.
and you can do that by using an array to hold the n digits, starting at [0,0....0]. then, within a "while" loop (which will replace your n nested for loops), try to increment the right-most entry (digit). if that is equal to n, then go back to zero and increment to the left. once you manage to increment a value without reaching n then you are "done" and can use the numbers as your indices.
it's pretty simple - you're just adding 1 each time.
then, for fortran's 1-based indexing, add 1 to each digit. in other words, change the above to start with 1s and move left at n+1.
for example, for n=4:
start with [1,1,1,1]
do your inner loop action
increment rightmost to [1,1,1,2]
do your inner loop action
increment rightmost to [1,1,1,3]
do your inner loop action
increment rightmost to [1,1,1,4]
do your inner loop action
increment rightmost to [1,1,1,5]
the digit you incremented is now at n+1, which means back to 1 and increment digit to left [1,1,2,1]
do your inner loop action
increment rightmost to [1,1,2,2]
do your inner loop action
etc..
I guess you could only do this by collapsing the loops into a single n**n loop, and compute the individual n indices out of the collapsed global index (or simply counting them up with different strides).
Edit: An attempt to put this into sample code:
do i=1,n**n
do j=1,n
ind(j) = mod((i-1)/max((j-1)*n,1),n) + 1
end do
! Some code using ind(1:n)
end do

Algorithm for collecting total events within the last certain time

I am facing an algorithm problem.
We have a task that runs every 10ms and during the running, an event can happen or not happen. Is there any simple algorithm that allows us to keep track of how many time an event is triggered within the latest, say, 1 second?
The only idea that I have is to implement an array and save all the events. As we are programming embedded systems, there is not enough space...
Thanks in advance.
an array of 13 bytes for a second worth of events in 10ms steps.
consider it an array of 104 bits marking 0ms to 104ms
if the event occurs mark the bit and increment to the next time, else just increment to next bit/byte.
if you want ... run length encode after each second to offload the event bits into another value.
or ... treat it as a circular buffer and keep the count available for query.
or both
You could reduce the array size to match the space available.
It is not clear if an event could occur multiple times while your task was running, or if it is always 10ms between events.
This is more-or-less what Dtyree and Weeble have suggested, but an example implementation may help ( C code for illustration):
#include <stdint.h>
#include <stdbool.h>
#define HISTORY_LENGTH 100 // 1 second when called every 10ms
int rollingcount( bool event )
{
static uint8_t event_history[(HISTORY_LENGTH+7) / 8] ;
static int next_history_bit = 0 ;
static int event_count = 0 ;
// Get history byte index and bit mask
int history_index = next_history_bit >> 3 ; // ">> 3" is same as "/ 8" but often faster
uint8_t history_mask = 1 << (next_history_bit & 0x7) ; // "& 0x07" is same as "% 8" but often faster
// Get current bit value
bool history_bit = (event_history[history_index] & history_mask) != 0 ;
// If oldest history event is not the same as new event, adjust count
if( history_bit != event )
{
if( event )
{
// Increment count for 0->1
event_count++ ;
// Replace oldest bit with 1
event_history[history_index] |= history_mask ;
}
else
{
// decrement count for 1->0
event_count-- ;
// Replace oldest bit with 0
event_history[history_index] &= ~history_mask ;
}
}
// increment to oldest history bit
next_history_bit++ ;
if( next_history_bit >= HISTORY_LENGTH ) // Could use "next_history_bit %= HISTORY_COUNT" here, but may be expensive of some processors
{
next_history_bit = 0 ;
}
return event_count ;
}
For a 100 sample history, it requires 13 bytes plus two integers of statically allocated memory, I have used int for generality, but in this case uint8_t counters would suffice. In addition there are three stack variables, and again the use of int is not necessary if you need to really optimise memory use. So in total it is possible to use as little as 15 bytes plus three bytes of stack. The event argument may or may not be passed on the stack, then there is the function call return address, but again that depends on the calling convention of your compiler/processor.
You need some kind of list/queue etc, but a ringbuffer has probably the best performance.
You need to store 100 counters (1 for each time period of 10 ms during the last second) and a current counter.
Ringbuffer solution:
(I used pseudo code).
Create a counter_array of 100 counters (initially filled with 0's).
int[100] counter_array;
current_counter = 0
During the 10 ms cycle:
counter_array[current_counter] = 0;
current_counter++;
For every event:
counter_array[current_counter]++
To check the number of events during the last s, take the sum of counter_array
Can you afford an array of 100 booleans? Perhaps as a bit field? As long as you can afford the space cost, you can track the number of events in constant time:
Store:
A counter C, initially 0.
The array of booleans B, of size equal to the number of intervals you want to track, i.e. 100, initially all false.
An index I, initially 0.
Each interval:
read the boolean at B[i], and decrement C if it's true.
set the boolean at B[i] to true if the event occurred in this interval, false otherwise.
Increment C if the event occurred in this interval.
When I reaches 100, reset it to 0.
That way you at least avoid scanning the whole array every interval.
EDIT - Okay, so you want to track events over the last 3 minutes (180s, 18000 intervals). Using the above algorithm and cramming the booleans into a bit-field, that requires total storage:
2 byte unsigned integer for C
2 byte unsigned integer for I
2250 byte bit-field for B
That's pretty much unavoidable if you require to have a precise count of the number of events in the last 180.0 seconds at all times. I don't think it would be hard to prove that you need all of that information to be able to give an accurate answer at all times. However, if you could live with knowing only the number of events in the last 180 +/- 2 seconds, you could instead reduce your time resolution. Here's a detailed example, expanding on my comment below.
The above algorithm generalizes:
Store:
A counter C, initially 0.
The array of counters B, of size equal to the number of intervals you want to track, i.e. 100, initially all 0.
An index I, initially 0.
Each interval:
read B[i], and decrement C by that amount.
write the number of events that occurred this interval into B[i].
Increment C by the number of events that occurred this interval.
When I reaches the length of B, reset it to 0.
If you switch your interval to 2s, then in that time 0-200 events might occur. So each counter in the array could be a one-byte unsigned integer. You would have 90 such intervals over 3 minutes, so your array would need 90 elements = 90 bytes.
If you switch your interval to 150ms, then in that time 0-15 events might occur. If you are pressed for space, you could cram this into a half-byte unsigned integer. You would have 1200 such intervals over 3 minutes, so your array would need 1200 elements = 600 bytes.
Will the following work for you application?
A rolling event counter that increments every event.
In the routine that runs every 10ms, you compare the current event counter value with the event counter value stored the last time the routine ran.
That tells you how many events occurred during the 10ms window.

Create multiple combinations summing to 100

I would like to be able to create multiple combinations that sum to 100%, given a defined number of "buckets" with a defined 'difference factor'. In the below example, the difference is a factor of 20 to make it simple, but I will probably reduce it to 1 in the final solution.
For example, with 3 "buckets" A, B, C you could have:
A 100 80 80 60 60 ... 0
B 0 20 0 20 40 ... 0
C 0 0 20 20 0 ... 100
Each column is one combination (summing to 100) that I would like to store and do further calculations on.
This is a business problem and not homework.
Please help me come up with a solution. A brute force way would be to create a multi-dimension array for every possible combination, e.g. 100x100x100 and then go through each 1 million combination to see which ones sum to 100. However this looks like it will be way too inefficient.
Much appreciated. I hope I have explained clearly enough.
This problem is known as partitions rather than combinations, which is something different.
First off: the 'difference factor' just turns the problem from finding partitions of 100 to (in your example) finding partitions of 5 (then multiplying by 20).
Next up: If the number of buckets is constant, you can just do (pseudo code):
for i = 0 to n
for j = 0 to n-i
output (i, j, n-(i+j))
If the number of buckets is going to be dynamic, you'd have to be a bit cleverer, but this approach will basically work.
This looks like it would yield well to a bit of cacheing and dynamic programming.
fun partition (partitions_left, value):
if partitions_left == 0
return empty_list
if value == 0:
return list of list of partitions_left 0 elements
return_value = empty_list
for possible_value from value downto 1:
remainder = value-possible_value
children = partition(partitions_left-1, remainder)
for child in children:
append (cons of possible_value and child) to return_value
return return_value
If you also make sure that you serve already-computed values from the cache, "all" you need to then do is to generate all possible permutations of all generated partitions.
Algorithm wise you could make a list of all the numbers between 0 and 100 in steps of 20 in list A, then make a copy of list A to be list B.
Next, compare each of list A's values to list B seeing which values add up to 100 or fewer and store a record of these in list C. Next, do the same to list C again (checking all the values between 0 and 100 with a step of 20) to see which values add up to 100.

Resources