An Iteration for particular combinations on SAS - loops

The table below lists each possibility for each variable 'A', 'B' and 'C', and the probability of that combination occurring. I already know all the probabilities.
Row # | A | B | C | Probability
============================================================
0 | ... | ... | ... | P0
------------------------------------------------------------
1 | ... | ... | ... | P1
------------------------------------------------------------
. | ... | . | . | .
------------------------------------------------------------
. | ... | . | . | .
------------------------------------------------------------
10 | ... | ... | ... | P10
------------------------------------------------------------
I would like to write an iteration within a combination of variables 'A', 'B' and 'C':
start from Row = 0, keep increasing
for Row = i.
If P(Row >= i) * 300 - P(Row < i) * 600 > 0
do
i = i+1;
until P(Row >= i) * 300 - P(Row < i) * 600 <= 0 or i =10.
It will stop and output i for a combination of 'A', 'B' and 'C'. And i is what I need for a combination of (A / B / C). Which is regarded as 'Threshold' in my problem.
How could I write this kind of code since there are many combinations of variables 'A', 'B' and 'C'.
Example:
When i = 0, P(Row >= 0) * 300 - P(Row < 0) * 600 = 1* 300 - 0* 600 = 300 > 0 Hence, i = 0+1 = 1
When i = 1, P(Row >= 1) * 300 - P(Row < 1) * 600 = 0.95* 300 - 0.05* 600 = 255 > 0 i = 1+1 = 2
When i = 2, P(Count >= 2) * 300 - P(Row < 2) * 600 = 0.85* 300 - 0.15* 600 = 165 > 0 i = 2+1 = 3
When i = 3, P(Row >= 3) * 300 - P(Row < 3) * 600 = 0.70* 300 - 0.30* 600 = 30 > 0 i = 3+1 = 4
When i = 4, P(Row >= 4) * 300 - P(Row < 4) * 600 = 0.50* 300 - 0.50* 600 = -150 < 0
we stop and output i =4 for this combination of 'A', 'B' and 'C'.
Thank you!

Observing that P(Row >= i) * 300 - P(Row < i) * 600 > 0 is the same as P(Row >= i) > 2 * P(Row < i), we simply sum P(Row<i) until it's greater than half of the current element.
double sum = 0;
auto it = data.begin();
while(it != data.end() && *it > 2*sum) {
sum += *it;
++it;
}

Related

Multiplying a sparse matrix by an array without copying

I have a 1d array (vector of size M), a pretty large one, and I definitely don't want to be copying it in memory. I also have a sparse matrix of window N (arbitrary size, basically all elements except the diagonal & N pseudo diagonals are zero).
I want to multiply this sparse matrix by the vector, without having to copy the vector in memory. What's the easiest and most efficient way of doing this? There has to be a neat solution, but I don't know the proper literature and I'm not educated enough to figure this out.
There is a solution for N=1 (where matrix is: a on the diagonal, and b on two closest pseudo diagonals). The solution looks smth like this (e.g., in python):
tmp2 = array[0]
i = 1
while (i < len(array) - 1):
tmp1 = b * (array[i - 1] + array[i + 1]) + a * array[i]
array[i - 1] = tmp2
i += 1
tmp2 = b * (array[i - 1] + array[i + 1]) + a * array[i]
array[i - 1] = tmp1
i += 1
But I can't manage to generalize this for an arbitrary N.
Notes: I absolutely don't want to be copying the size M vector in memory. However, using a temporary array of size 2N+1 is ok, since M >> N. I'm looking for an actual algorithm description, not a smart custom library that does the job.
Thanks in advance!
Consider the matrix
[
1 2 3 0 0 0
2 1 2 4 0 0
3 2 1 2 5 0
0 7 2 1 2 6
0 0 8 2 1 2
0 0 0 9 2 1
]
and the vector v [1,2,3,4,5,6]
For each row, below the involves coeff of v:
[1,2,3]
[1,2,3,4]
[1,2,3,4,5]
[ 2,3,4,5,6]
[ 3,4,5,6]
[ 4,5,6]
As you have noticed, you just need to keep track of a window of v.
That window is originally [1,2,3,4,5] (for i = 0, 1, 2)
Then you shift that window to the right every i (and eventually truncate it for the last rows not to be out of bounds of v...)
Now notice that when you shift to the right, you only need to know the next value from v, and as long as you have not dirtied that value (by writing to v) your new window is valid.
For row i, window is [i-n;i+n] and the coeff which will be modified is v[i]. For the next window, you need to know v[i+n+1] which has not been dirtied. So all good.
So algo be like
window = circularbuffer(2n+1) //you push to the right, and if length > 2n+1, you remove first elem
for i = 0; i<v.size()
v[i] = prod(row_i, window) // only for the row_i coeffs...
if i >= n && < M-3
window.push(v[i+n+1])
else if i>= M-3
window.shift() // just remove the first value
const N = 2
const M_SIZE = 10
function toString(M){
return M.map(x=>x.join(' ')).join('\n')
}
const { M, v } = (_ => {
const M = Array(M_SIZE).fill(0).map(x=>Array(M_SIZE).fill(0))
let z = 1
for(let i = 0; i<M_SIZE; ++i){
for(let j = -N; j<=N; ++j){
if(i+j >= 0 && i+j <M_SIZE){
M[i][i+j] = (z++ % (N*2))+1
}
}
}
const v = Array(M.length).fill(0).map((x,i)=>i)
return { M, v}
})()
function classic(M, v){
return M.map(r => r.reduce((acc, x, j) => acc + v[j]*x, 0))
}
function inplace(M, v){
// captn inefficiency
const circBuf = (init => {
let buf = init
return {
push (x) {
buf.push(x)
buf.shift()
},
shift() {
buf.shift()
},
at (i) { return buf[i] },
toString() {
return buf.join(' ')
}
}
})(v.slice(0, 2 * N + 1))
const sparseProd = (row, buf) => {
let s = 0
row.forEach((x, j) => s += x * buf.at(j))
return s
}
const sparseRows = M.map(r => r.filter(x => x !== 0))
sparseRows.forEach((row, i) => {
v[i] = sparseProd(row, circBuf)
if (i >= sparseRows.length - 3 ) {
circBuf.shift()
} else {
if (i >= N) {
circBuf.push(v[i + N + 1])
}
}
})
}
console.log('classic prod', classic(M, v))
inplace(M, v)
console.log('inplace prod', v)
So I ended up doing something like this. It seems like a generalization of what was done for the N=1 case.
In general, my weights are basically the non-zero components of the central row in my sparse matrix. I.e. if the matrix looks like this (as was noted in the comments, it's usually symmetric, but not necessarily):
| a b c 0 0 ... 0 0 0 0 0 |
| b a b c 0 ... 0 0 0 0 0 |
| c b a b c ... 0 0 0 0 0 |
| 0 c b a b ... 0 0 0 0 0 |
| 0 0 c b a ... 0 0 0 0 0 |
| ... ... ... |
| 0 0 0 0 0 ... a b c 0 0 |
| 0 0 0 0 0 ... b a b c 0 |
| 0 0 0 0 0 ... c b a b c |
| 0 0 0 0 0 ... 0 c b a b |
| 0 0 0 0 0 ... 0 0 c b a |
then the weights vector is simply [c, b, a, b, c] (i.e., N = 2).
So for the general case where N = ntimes I ended doing something like this:
def sparse_multiply(array, weights):
ntimes = (len(weights) - 1) / 2
# reduced dot product
def product(a_, i_, w_):
dot = 0.0
for k, j in enumerate(range(i_ - ntimes, i_ + ntimes + 1)):
if (j >= 0 and j < len(a_)):
dot += a_[j] * w_[k]
return dot
tmp = np.zeros(ntimes + 1)
for i in range(ntimes):
tmp[i] = array[i]
i = ntimes
while (i <= len(array)):
for t in range(-1, ntimes):
tmp[t] = product(array, i, w)
array[i - ntimes] = tmp[t + 1]
i += 1
return array
The only sacrifice you make, is the temporary array of size O(N), which is fine, because as I said, N << M.
Yes, yes, I know some of the operations (like the reduced dot product) could have been done with some python magic. But my point was to transfer this into old school C/Fortran, so that wouldn't help much.
Applications
Actually the application I was interested was to apply a gaussian filter: a_i = 0.5 * a_i + 0.25 * (a_{i-1} + a_{i+1}) to an array N times without having to do N passes and without having to copy the whole array.
So what you can do, is you can raise the sparse matrix of 0.5 on diagonals, and 0.25 on pseudo diagonals to the Nth power, and you will end up with the weights vector and a matrix that looks like the one I showed earlier (but with N nonzero pseudo diagonals). Then you can apply these weights to the array using the method above, so that you don't modify a_i before having to use it for other components, but at the same time get away without copying the whole array.
PS. Unfortunately I did not quite follow #grodzi's answer. A bit more explanation would certainly help.

Accessing an array with Pointer this way? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
Its basically passing an array to a function via pointer. Then it prints out each element in the array. Im trying to understand a very specific line of pointers since my class has never done a example like this before. After finishing intro I never encountered this in the pointers topic, hence why Im confused. thank you.
main( )
{
inta[3][4] = {
1, 2, 3, 4,
5, 6, 7, 8,
9, 0, 1, 6
} ;
display ( a, 3, 4 ) ;
show ( a, 3, 4 ) ;
print ( a, 3, 4 ) ;
}
display ( int*q, introw, intcol )
{
inti, j ;
for ( i= 0 ; i< row ; i++ )
{
for ( j = 0 ; j < col ; j++)
printf("%d ",*(q+i*col+j)); // THIS is the line Im trying to understand
printf( "\n" ) ;
}
printf("\n" ) ;
}
Let's view the 2D array as a single array:
-------------------------------------------------
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | 1 | 6 |
-------------------------------------------------
^
index 0
And if we take a closer look at the expression (q+i*col+j):
q + (0 * 4) + 0 = 0th index
q + (0 * 4) + 1 = 1st index
q + (0 * 4) + 2 = 2nd index
q + (0 * 4) + 3 = 3rd index
^ ^
i j
After the first row has been printed, i becomes 1:
-------------------------------------------------
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | 1 | 6 |
-------------------------------------------------
^
4th index
q + (1 * 4) + 0 = 4
q + (1 * 4) + 1 = 5
q + (1 * 4) + 2 = 6
q + (1 * 4) + 3 = 7
^ indices
As you can see, this points to the next row.
i becomes 2:
-------------------------------------------------
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | 1 | 6 |
-------------------------------------------------
^
q + (2 * 4) + 0 = 8
q + (2 * 4) + 1 = 9
q + (2 * 4) + 2 = 10
q + (2 * 4) + 3 = 11
^ indices
And so on. Hope this helps
*(q+i*col+j) is equivalent to q[i*col+j].
When using pointer arithmetic, adding a number x to a pointer evaluates to an address x bytes times the size of the pointer type ahead of the initial address (offset).

Assigning through random generated indexes

I'm trying to write a function that assign N elements to M players. Here's what I wrote:
void assignElements(Player *p, Tab *t, int n) {
int i = 0, nRand, flagElements = 0;
do {
do {
nRand = MINRANDT + rand() % (MAXRANDT - MINRANDT + 1);
} while(t[nRand].type != Terrain && t[nRand].idProp != -1);
if (i == n) {
i = 0; //this makes "i" reset when it reaches the number of players
}
t[nRand].idProp = i;
p[i].numTerrains++;
i++;
flagElements++;
} while (flagElements != NELEMENTS);
}
So, if I try to run this function, it's not respecting the condition of the second while (maybe the problem is the condition.): in fact, it also assign to t elements that are not of type Terrain (this is an enum). The condition to do the actions under the nRand do / while, is that nRand have to be an index of a t element that is of type Terrain, and that its idProp is -1 (this mean it has not been assigned yet). Hope anyone can help. :)
t[nRand].type != Terrain | t[nRand].idProp != -1 | &&
-------------------------+-----------------------+---
0 | 0 | 0
0 | 1 | 0
1 | 0 | 0
1 | 1 | 1
Meaning that the loop will exit for 3 conditions and repeat only when both sub-conditions are met
Try ||
t[nRand].type != Terrain | t[nRand].idProp != -1 | ||
-------------------------+-----------------------+---
0 | 0 | 0
0 | 1 | 1
1 | 0 | 1
1 | 1 | 1

Nested loops result

I really don't know how to find out the result of nested loops.
For example in the following pseudo-code, I can't sort out what will be given at the end of execution. I'll be so glad if anyone gives me a simple solution.
r <- 0
for i <- 1 to n do
for j <- 1 to i do
for k <- j to i+j do
r <- r + 1
return r
Question is:
What is the result of the code and give the result r in terms of n?
I write it but every time I get confused.
In your pseudo-code, Inner most loop, k <- j to i+j can be written as k <- 0 to i (this is by removing j). Hence your code can be simplified as follows:
r <- 0
for i <- 1 to n do
for j <- 1 to i do
for k <- 0 to i do // notice here `j` removed
r <- r + 1
return r
Based on this pseudo-code, I have written a C program(as below) to generate sequence for N = 1 to 10. (you originally tagged question as java but I am writing c code because what you wants is independent of language constraints)
#include<stdio.h>
int main(){
int i =0, k =0, j =0, n =0;
int N =0;
int r =0;
N =10;
for (n=1; n <= N; n++){
// unindented code here
r =0;
for (i=1; i<=n; i++)
for (j=1; j<=i; j++)
for (k=0; k<=i; k++)
r++;
printf("\n N=%d result = %d",n, r);
}
printf("\n");
}
Output of this program is something like:
$ ./a.out
N=1 result = 2
N=2 result = 8
N=3 result = 20
N=4 result = 40
N=5 result = 70
N=6 result = 112
N=7 result = 168
N=8 result = 240
N=9 result = 330
N=10 result = 440
Then, Tried to explore, How does it work? with some diagrams:
Execution Tree For N=1:
1<=i<=1, (i=1)
|
1<=j<=i, (j=1)
/ \
0<=k<=i, (K=0) (K=1)
| |
r=0 r++ r++ => r = 2
( 1 + 1 )
That is (1*2) = 2
Tree For N=2:
1<=i<=2, (i=1)-----------------------(i=2)
| |---------|------|
1<=j<=i, (j=1) (j=1) (j=2)
/ \ / | \ / | \
0<=k<=i, (K=0) (K=1) (K=0)(K=1)(k=2) (K=0)(K=1)(k=2)
| | | | | | | |
r=0 r++ r++ r++ r++ r++ r++ r++ r++ => 8
-------------- ---------------------------------
( 1 + 1) ( 3 + 3 )
That is (1 + 1) + (3 + 3) = 8
Similarly I drawn a tree for N=3:
1<=i<=3, (i=1)-----------------------(i=2)--------------------------------------------(i=3)
| |---------|------| |----------------------|----------------------|
1<=j<=3, (j=1) (j=1) (j=2) ( j=1 ) ( j=2 ) ( j=3 )
/ \ / | \ / | \ / | | \ / | | \ / | | \
0<=k<=i, (K=0) (K=1) (K=0)(K=1)(k=2) (K=0)(K=1)(k=2) / | | \ / | | \ / | | \
| | | | | | | | (K=0)(K=1)(k=2)(k=3) (K=0)(K=1)(k=2)(k=3) (K=0)(K=1)(k=2)(k=3)
r=0 r++ r++ r++ r++ r++ r++ r++ r++ r++ r++ r++ r++ r++ r++ r++ r++ r++ r++ r++ r++
That is (1 + 1) + (3 + 3) + (4 + 4+ 4)= 20
N = 1, (1 + 1) = 2
N = 2, (1 + 1) + (3 + 3) = 8
N = 3, (1 + 1) + (3 + 3) + (4 + 4 + 4)= 20
N = 4, (1 + 1) + (3 + 3) + (4 + 4 + 4) + (5 + 5 + 5 + 5) = 40
N = 5, (1 + 1) + (3 + 3) + (4 + 4 + 4) + (5 + 5 + 5 + 5) + (6 + 6 + 6 + 6 + 6) = 70
N = 6, (1 + 1) + (3 + 3) + (4 + 4 + 4) + (5 + 5 + 5 + 5) + (6 + 6 + 6 + 6 + 6) + (7 + 7 + 7 + 7 + 7 + 7)= 112
For N=6 we can also be write above sequence as:
(1*2) + (2*3) + (3*4) + (4*5) + (5*6) + (6*7)
Finally, I could understand that sum of N in three loop is:
(1*2) + (2*3) + (3*4) + (4*5) + (5*6) + ... + (N * (N+1))
With help from math.stackexchange.com, I could simplify this equation:
I asked here: How to simplify summation equation in terms of N?
So as I commented to your question, Result in term of N is ( ((N) * (N+1) * (N+2)) / 3 ).
And, I think its correct. I cross checked it as follows:
N = 1, (1 * 2 * 3)/3 = 2
N = 2, (2 * 3 * 4)/3 = 8
N = 3, (3 * 4 * 5)/3 = 20
N = 4, (4 * 5 * 6)/3 = 40
N = 5, (5 * 6 * 7)/3 = 70
Try using some code like this to work it out... i.e. code up what it is and what you think it should be and test it.
EDIT: updated based on comment above.
public class CountLoop{
public static void main(String[] args){
for(int i=1;i<=10;i++)
System.out.println("It's "+run(i)+" and I think "+guess(i));;
}
public static int run(int n){
int r = 0;
for(int i=1;i<=n;i++)
for(int j=1; j <= i;j++)
for(int k=j; k <= i+j; k++)
r += 1;
return r;
}
public static int guess(int n){
// taken from the comments
int r = ((n * (n+1) * (n+2)) /3);
return r;
}
}
Running this gets
It's 2 and I think 2
It's 8 and I think 8
It's 20 and I think 20
It's 40 and I think 40
It's 70 and I think 70
It's 112 and I think 112
It's 168 and I think 168
It's 240 and I think 240
It's 330 and I think 330
It's 440 and I think 440
so we're happy.
I am getting it something like this :
n = 1: r = 2
n = 2: r = 8
n = 3: r = 20
n = 4: r = 40
n = 5: r = 70
n = 6: r = 112
n = 7: r = 168
n = 8: r = 240
n = 9: r = 330
n = 10: r = 440
lets say for n = 10,
r = 2 + 6 + 12 + 20 + 30 + 42 + 56 + 72 + 90 + 110 = 440
=> r = 2(1 + 3 + 6 + 10 + 15 + 21 + 28 + 36 + 45 + 55)
Intuitively, I think
n = sum(n-1) + n * (n + 1).
where
sum(n-1) = value of r for n-1

A puzzle related to nested loops

For a given input N, how many times does the enclosed statement executes?
for i in 1 … N loop
for j in 1 … i loop
for k in 1 … j loop
sum = sum + i ;
end loop;
end loop;
end loop;
Can anyone figure out an easy way or a formula to do this in general. Please explain.
First, I written a C code to generate sum:
int main(){
int i =0, k =0, j =0, n =0;
int N =0;
int sum =0;
N =10;
for (n=1; n <= N; n++){
// unindented code here
sum =0;
for (i=1; i<=n; i++)
for (j=1; j<=i; j++)
for (k=1; k<=j; k++)
sum++;
printf("\n N=%d sum = %d",n, sum);
}
printf("\n");
}
Simple compile and generate result for N=1 to N=10 :
$ gcc sum.c
$ ./a.out
N=1 sum = 1
N=2 sum = 4
N=3 sum = 10
N=4 sum = 20
N=5 sum = 35
N=6 sum = 56
N=7 sum = 84
N=8 sum = 120
N=9 sum = 165
N=10 sum = 220
Then, Tried to explore How this works? with some diagrams:
For, N=1:
i<=N, (i=1)
|
j<=i, (j=1)
|
k<=j, (K=1)
|
sum=0. sum++ ---> sum = 1
That is (1) = 1
For, N=2:
i<=N, (i=1)-------(i=2)
| |-----|-----|
j<=i, (j=1) (j=1) (j=2)
| | |----|----|
k<=j, (K=1) (K=1) (K=1) (K=2)
| | | |
sum=0, sum++ sum++ sum++ sum++ --> sum = 4
That is (1) + (1 + 2) = 4
For, N=3:
i<=N, (i=1)-------(i=2)--------------------(i=3)
| |-----|-----| |---------|-------------|
j<=i, (j=1) (j=1) (j=2) (j=1) (j=2) (j=3)
| | |----|----| | |----|----| |-----|-----|
k<=j, (K=1) (K=1) (K=1) (K=2) (K=1) (K=1) (K=2) (K=1) (K=2) (K=3)
| | | | | | | | | |
sum=0, sum++ sum++ sum++ sum++ sum++ sum++ sum++ sum++ sum++ sum++
--> sum = 10
That is (1) + (1 + 2) + ( 1 + 2 + 3 ) = 10
N = 1, (1) = 1
N = 2, (1) + (1 + 2) = 4
N = 3, (1) + (1 + 2) + (1 + 2 + 3) = 10
N = 4, (1) + (1 + 2) + (1 + 2 + 3) + (1 + 2 + 3 + 4) = 20
N = 5, (1) + (1 + 2) + (1 + 2 + 3) + (1 + 2 + 3 + 4) + (1 + 2 + 3 + 4 + 5) = 35
Finally, I could understood that sum of N in three loop is:
(1) + (sum 0f 1 to 2) + ... + (sum of 1 to (N-2)) + (sum of 1 to (N-1) ) + (sum of 1 to N)
or we can write it as:
=> (1) + (1 + 2) + ...+ (1 + 2 +....+ i) + ... + (1 + 2 + ....+ N-1) + (1 + 2 + ....+ N)
=> ( N * 1 ) + ( (N-1) * 2) + ( (N-2) * 3) +...+ ( (N -i+1) * i ) +... + ( 1 * N)
You can refer here for simplification calculations: (I asked HERE )
[YOUR ANSWER]
= ( ((N) * (N+1) * (N+2)) / 6 )
And, I think its correct. I checked as follows:
N = 1, (1 * 2 * 3)/6 = 1
N = 2, (2 * 3 * 4)/6 = 4
N = 3, (3 * 4 * 5)/6 = 6
N = 4, (4 * 5 * 6)/6 = 10
N = 5, (5 * 6 * 7)/6 = 35
Also, The complexity of this algorithm is O(n3)
EDIT:
The following loop also has same numbers of count, that is = ( ((N) * (N+1) * (N+2)) / 6 )
for i in 1 … N loop
for j in i … N loop
for k in j … N loop
sum = sum + i ;
end loop;
end loop;
end loop;

Resources