Expression to calculate a field within a loop - algorithm

I basically have a few variables
0 < na < 250
0 < max <= 16
nb = (na + max - 1) / max
n has the following characterstics
0 <= i < nb - 1 => n = max
i = nb - 1 => n = na - i * max
Is there an easy way to do this without the ternary operator?
for (i = 0; i<nb;i++) {
n = ((i + 1) * max > na ? na - (i * max) : max);
}
Examples
na = 5
max = 2
nb = 3
i = 0 => n = 2
i = 1 => n = 2
i = 2 => n = 1
na = 16
max = 4
nb = 4
i = 0 => n = 4
i = 1 => n = 4
i = 2 => n = 4
i = 3 => n = 4
na = 11
max = 3
nb = 4
i = 0 => n = 3
i = 1 => n = 3
i = 2 => n = 3
i = 3 => n = 2

The question is not very clear. Perhaps you're looking for something like this:
for (i=0;i < nb;++i)
{
n = i < nb - 1 ? max : (na - 1) % max + 1;
}

You don't need to calculate nb. This is one way you could do it (C#):
int na = 11;
int max = 4;
for (int i = 0, x = 0; x < na; i++, x += max)
{
int n = Math.Min(max, na - x);
Console.WriteLine("i = {0}, n = {1}", i, n);
}
Output:
i = 0, n = 4
i = 1, n = 4
i = 2, n = 3

Just to add more confusion to the thread:
If only you print max in the first two cases, then you could do something like: (not in any particular language)
//for 0
printf("i = %d, n = %d\n",i,max)
//for 1
printf("i = %d, n = %d\n",i,max)
//for the rest
for (i = 2; i<nb;i++) {
printf("i = %d, n = %d\n",i,na - (i * max));
}
You can avoid the operator doing two for loops
for (i = 0; (i + 1) * max) > na AND i < nb;i++) {
printf("i = %d, n = %d\n",i,0);
}
for (; i<nb;i++) {
printf("i = %d, n = %d\n",i,na - (i * max));
}

Related

Understanding Spark correlation algorithm

I was reading Spark correlation algorithm source code and while going through the code, I coulddn't understand this particular peace of code.
This is from the file : org/apache/spark/mllib/linalg/BLAS.scala
def spr(alpha: Double, v: Vector, U: Array[Double]): Unit = {
val n = v.size
v match {
case DenseVector(values) =>
NativeBLAS.dspr("U", n, alpha, values, 1, U)
case SparseVector(size, indices, values) =>
val nnz = indices.length
var colStartIdx = 0
var prevCol = 0
var col = 0
var j = 0
var i = 0
var av = 0.0
while (j < nnz) {
col = indices(j)
// Skip empty columns.
colStartIdx += (col - prevCol) * (col + prevCol + 1) / 2
av = alpha * values(j)
i = 0
while (i <= j) {
U(colStartIdx + indices(i)) += av * values(i)
i += 1
}
j += 1
prevCol = col
}
}
}
I do not know Scala and that could be the reason I could not understand it. Can someone explain what is happening here.
It is being called from Rowmatrix.scala
def computeGramianMatrix(): Matrix = {
val n = numCols().toInt
checkNumColumns(n)
// Computes n*(n+1)/2, avoiding overflow in the multiplication.
// This succeeds when n <= 65535, which is checked above
val nt = if (n % 2 == 0) ((n / 2) * (n + 1)) else (n * ((n + 1) / 2))
// Compute the upper triangular part of the gram matrix.
val GU = rows.treeAggregate(new BDV[Double](nt))(
seqOp = (U, v) => {
BLAS.spr(1.0, v, U.data)
U
}, combOp = (U1, U2) => U1 += U2)
RowMatrix.triuToFull(n, GU.data)
}
The correlation is defined here:
https://en.wikipedia.org/wiki/Pearson_correlation_coefficient
The final goal is to understand the Spark correlation algorithm.
Update 1: Relevent paper https://stanford.edu/~rezab/papers/linalg.pdf

positional sum of 2 numbers

How to sum 2 numbers digit by digit with pseudo code?
Note: You don't know the length of the numbers - if it has tens, hundreds, thousands...
Units should be add to units, tens to tens, hundreds to hundreds.....
If there is a value >= 10 in adding the units you need to put the value of that ten with "the tens"....
I tried
Start
Do
Add digit(x) in A to Sum(x)
Add digit(x) in B to Sum(x)
If Sum(x) > 9, then (?????)
digit(x) = digit(x+1)
while digit(x) in A and digit(x) in B is > 0
How to show the result?
I am lost with that.....
Please help!
Try this,
n = minDigit(a, b) where a and b are the numbers.
let sum be a number.
m = maxDigit(a,b)
allocate maxDigit(a,b) + 1 memory for sum
carry = 0;
for (i = 1 to n)
temp = a[i] + b[i] + carry
// reset carry
carry = 0
if (temp > 10)
carry = 1
temp = temp - 10;
sum[i] = temp
// one last step to get the leftover carry
if (digits(a) == digits(b)
sum[n + 1] = carry
return
if (digits(a) > digits(b)
toCopy = a
else
toCopy = b
for (i = n to m)
temp = toCopy[i] + carry
// reset carry
carry = 0
if (temp > 10)
carry = 1
temp = temp - 10;
sum[i] = temp
Let me know if it helps
A and B are the integers you want to sum.
Note that the while loop ends when all the three integers are equal to zero.
carry = 0
sum = 0
d = 1
while (A > 0 or B > 0 or carry > 0)
tmp = carry + A mod 10 + B mod 10
sum = sum + (tmp mod 10) * d
carry = tmp / 10
d = d * 10
A = A / 10
B = B / 10

Index Exceeds Matrix Dimensions - Canny Edge Detection

I am using the following lines of code for edge detection using canny edge detector :
I=imread('bradd.tif');
figure,imshow(I);
IDtemp = im2double(I);
[r c]=size(I);
ID(r,c) = 0;
IDx(r,c) = 0;
IDfil(r,c) = 0;
IDxx(r,c) = 0;
IDy(r,c) = 0;
IDyy(r,c) = 0;
mod(r,c) = 0;
for i= 1 : r+4
for j = 1:c+4
if(i<=2 || j<=2 || i>=r+3 || j>=c+3)
ID(i,j) = 0;
else
ID(i,j) = IDtemp(i-2,j-2);
end;
end
end
%figure,imshow(ID);
filter=[2 4 5 4 2;4 9 12 9 4;5 12 15 12 5;4 9 12 9 4;2 4 5 4 2];
for i=1:5
for j=1:5
filter(i,j)=filter(i,j)/159;
end
end
%figure,imshow(filter);
for v = 3 : r
for u = 3 : c
sum = 0;
for i = -2 : 2
for j = -2 : 2
sum = sum + (ID(u+i, v+j) * filter(i+3, j+3));
end
end
IDx(u,v) = sum;
end
end
%figure,imshow(IDx);
IDxtemp = IDx;
for i= 1 : r+2
for j = 1:c+2
if(i<=1 || j<=1 || i>=r || j>=c)
IDfil(i,j) = 0;
else
IDfil(i,j) = IDxtemp(i-1,j-1);
end;
end
end
%figure,imshow(IDfil);
Mx = [-1 0 1; -2 0 2; -1 0 1]; % Sobel Mask in X-Direction
My = [-1 -2 -1; 0 0 0; 1 2 1]; % Sobel Mask in Y-Direction
for u = 2:r
for v = 2:c
sum1 = 0;
for i=-1:1
for j=-1:1
sum1 = sum1 + IDfil(u + i, v + j)* Mx(i + 2,j + 2);
end
end
IDxx(u,v) = sum1;
end;
end
%figure,imshow(IDxx);
for u = 2:r
for v = 2:c
sum2 = 0;
for i=-1:1
for j=-1:1
sum2 = sum2 + IDfil(u + i, v + j)* My(i + 2,j + 2);
end
end
IDyy(u,v) = sum2;
end
end
%figure,imshow(IDyy);
for u = 1:r
for v = 1:c
mod(u,v) = sqrt(IDxx(u,v)^2 + IDyy(u,v)^2) ;
%mod(u,v) = sqrt(IDxx(u,v)^2 + IDyy(u,v)^2);
end
end
%figure,imshow(mod);
modtemp = mod;
for i= 1 : r+2
for j = 1:c+2
if(i<=1 || j<=1 || i>=r || j>=c)
mod(i,j) = 0;
else
mod(i,j) = modtemp(i-1,j-1);
end;
end
end
%figure,imshow(mod);
theta(u,v) = 0;
supimg(u,v) = 0;
ntheta(u,v) = 0;
for u = 2 : r
for v = 2 : c
theta(u,v) = atand(IDyy(u,v)/IDxx(u,v));
if ((theta(u,v) > 0 ) && (theta(u,v) < 22.5) || (theta(u,v) > 157.5) && (theta(u,v) < -157.5))
ntheta(u,v) = 0;
end
if ((theta(u,v) > 22.5) && (theta(u,v) < 67.5) || (theta(u,v) < -112.5) && (theta(u,v) > -157.5))
ntheta(u,v) = 45;
end
if ((theta(u,v) > 67.5 && theta(u,v) < 112.5) || (theta(u,v) < -67.5 && theta(u,v) > 112.5))
ntheta(u,v) = 90;
end
if ((theta(u,v) > 112.5 && theta(u,v) <= 157.5) || (theta(u,v) < -22.5 && theta(u,v) > -67.5))
ntheta(u,v) = 135;
end
if (ntheta(u,v) == 0)
if (mod(u, v) > mod(u, v-1) && mod(u, v) > mod(u, v+1))
supimg(u,v) = mod(u,v);
else supimg(u,v) = 0;
end
end
if (ntheta(u,v) == 45)
if (mod(u, v) > mod(u+1, v-1) && mod(u, v) > mod(u-1, v+1))
supimg(u,v) = mod(u,v);
else supimg(u,v) = 0;
end
end
if (ntheta(u,v) == 90)
if (mod(u, v) > mod(u-1, v) && mod(u, v) > mod(u+1, v))
supimg(u,v) = mod(u,v);
else supimg(u,v) = 0;
end
end
if (ntheta(u,v) == 135)
if (mod(u, v) > mod(u-1, v-1) && mod(u, v) > mod(u+1, v+1))
supimg(u,v) = mod(u,v);
else supimg(u,v) = 0;
end
end
end
end
%figure,imshow(ntheta);
th = 0.2;
tl = 0.1;
resimg(u,v)= 0;
for u = 2 : r-1
for v = 2 : c-1
if(supimg(u,v) > th)
resimg(u,v) = 1;
else
if(supimg(u,v) >= tl && supimg(u,v) <= th )
resimg(u,v) = 1;
else
if (supimg(u,v) < tl)
resimg(u,v) = 0;
end
end
end
if (supimg(u-1,v-1) > th || supimg(u,v-1) > th || supimg(u+1,v-1) > th || supimg(u+1,v) > th || supimg(u+1,v+1) > th || supimg(u,v+1) > th || supimg(u-1,v+1) > th || supimg(u-1,v) > th)
resimg(u,v) = 1;
else
resimg(u,v) = 0;
end
end
end
figure,imshow(supimg);
figure,imshow(resimg);
However, for some of the images it is working fine, while for others it is showing the following error :
Index exceeds matrix dimensions.
Error in canny_edge (line 45)
sum = sum + (ID(u+i, v+j) * filter(i+3, j+3));
Can someone help me sort out this problem ??
Thanks and Regards.
Your loop ranges are in the wrong order leading to the error. If you modify your loop ranges to this
for u = 3 : r
for v = 3 : c
sum = 0;
for i = -2 : 2
for j = -2 : 2
sum = sum + (ID(u+i, v+j) * filter(i+3, j+3));
end
end
IDx(u,v) = sum;
end
end
the problem is solved.
My guess is that the code worked only for square images with c==r.
Note you are not making use of Matlab's vectorization capability, which allows you to shorten the first steps to:
ID = [zeros(2,c+4) ; [zeros(r,2) IDtemp zeros(r,2)]; zeros(2,c+4)];
filter=[2 4 5 4 2;4 9 12 9 4;5 12 15 12 5;4 9 12 9 4;2 4 5 4 2];
filter=filter/159;
for u = 1 : r
for v = 1 : c
IDx(u,v) = sum(reshape(ID(u+[0:4], v+[0:4]).* filter,25,1));
end
end
and this last loop can also be collapsed further but that might make readability an issue.
(edit) The loop can (for instance) be replaced with
IDx = conv2(ID, filter,'same');

How to convert a decimal base (10) to a negabinary base (-2)?

I want to write a program to convert from decimal to negabinary.
I cannot figure out how to convert from decimal to negabinary.
I have no idea about how to find the rule and how it works.
Example: 7(base10)-->11011(base-2)
I just know it is 7 = (-2)^0*1 + (-2)^1*1 + (-2)^2*0 + (-2)^3*1 + (-2)^4*1.
The algorithm is described in http://en.wikipedia.org/wiki/Negative_base#Calculation. Basically, you just pick the remainder as the positive base case and make sure the remainder is nonnegative and minimal.
7 = -3*-2 + 1 (least significant digit)
-3 = 2*-2 + 1
2 = -1*-2 + 0
-1 = 1*-2 + 1
1 = 0*-2 + 1 (most significant digit)
def neg2dec(arr):
n = 0
for i, num in enumerate(arr[::-1]):
n+= ((-2)**i)*num
return n
def dec2neg(num):
if num == 0:
digits = ['0']
else:
digits = []
while num != 0:
num, remainder = divmod(num, -2)
if remainder < 0:
num, remainder = num + 1, remainder + 2
digits.append(str(remainder))
return ''.join(digits[::-1])
Just my two cents (C#):
public static int[] negaBynary(int value)
{
List<int> result = new List<int> ();
while (value != 0)
{
int remainder = value % -2;
value = value / -2;
if (remainder < 0)
{
remainder += 2;
value += 1;
}
Console.WriteLine (remainder);
result.Add(remainder);
}
return result.ToArray();
}
There is a method (attributed to Librik/Szudzik/Schröppel) that is much more efficient:
uint64_t negabinary(int64_t num) {
const uint64_t mask = 0xAAAAAAAAAAAAAAAA;
return (mask + num) ^ mask;
}
The conversion method and its reverse are described in more detail in this answer.
Here is some code that solves it and display the math behind it.
Some code taken from "Birender Singh"
#https://onlinegdb.com/xR1E5Cj7L
def neg2dec(arr):
n = 0
for i, num in enumerate(arr[::-1]):
n+= ((-2)**i)*num
return n
def dec2neg(num):
oldNum = num
if num == 0:
digits = ['0']
else:
digits = []
while num != 0:
num, remainder = divmod(num, -10)
if remainder < 0:
num, remainder = num + 1, remainder + 10
print(str(oldNum) + " = " + str(num) + " * -10 + " + str(remainder))
oldNum = num
digits.append(str(remainder))
return ''.join(digits[::-1])
print(dec2neg(-8374932))
Output:
-8374932 = 837494 * -10 + 8
837494 = -83749 * -10 + 4
-83749 = 8375 * -10 + 1
8375 = -837 * -10 + 5
-837 = 84 * -10 + 3
84 = -8 * -10 + 4
-8 = 1 * -10 + 2
1 = 0 * -10 + 1
12435148

What is the output of this pseudocode?

procedure DoSomething(a_1, ... a_n)
p = a_1
for i = 2 to n
temp = p
for j = 1 to a_i
p = p * temp
DoSomething(10,2,2,2)
We are getting mixed results. One of us got 10^7, the other 10^27.
I Think I found my error... I keep substituting 10 for p every time, instead of the new value for temp.
EDIT: here's my work:
{10, 2, 2, 2}
p = 10
i = 2 to 4
temp = p = 10
j = 1 to 2
p = 10 * 10 = 10^2
p = 10^2 * 10 = 10^3
i = 3 to 4
temp = 10^3
j = 1 to 2
p = 10^3 * 10 = 10^4
p = 10^4 * 10 = 10^5
i = 4 to 4
temp = 10^5
j = 1 to 2
p = 10^5 * 10 = 10^6
p = 10^6 * 10 = 10^7
10^7
It's 10^27 as shown by this bit of python code:
a = [10,2,2,2]
p = a[0]
for i in range(1,len(a)):
temp = p
for j in range(a[i]):
p *= temp
print p
1,000,000,000,000,000,000,000,000,000
The problems with your code as posted are:
in your 10^7 solution, you're always multiplying by 10, not temp (which is increased to the final value of p after the j loop).
You're setting temp to arr[i], not p, in your PHP code (which I'll include here so my answer still makes sense after you edited it out of your question :-).
$arr = array(10, 2, 2, 2);
$p = $arr[0];
$temp = 0;
for($i = 1; $i <= 3; $i++)
{
$temp = $arr[$i];
for($j = 0; $j <= $arr[$i]; $j++)
{
$p = $p * $temp;
}
}
echo $p;
I entered the program into my TI-89 and got an answer of 1e27 for the value of p.
t(a)
Func
Local i,j,p,tmp
a[1]->p
For i,2,dim(a)
p->tmp
For j,1,a[i]
p*tmp->p
EndFor
EndFor
Return p
EndFunc
t({10,2,2,2}) 1.E27
Isn't it ((10^3)^4)^5 = 10 ^ 60 ?
Seems to be a function to calculate
(((a_1^(a_2+1))^(a_3+1))^(a_4+1)...
Thus we get ((10^3)^3)^3 = 10^(3^3) = 10^27
There is an error in your computation for 10^7, See below. The correct answer is 10^27
{10, 2, 2, 2}
p = 10
i = 2 to 4
temp = p = 10
j = 1 to 2
p = 10 * 10 = 10^2
p = 10^2 * 10 = 10^3
i = 3 to 4
temp = 10^3
j = 1 to 2
p = 10^3 * 10 = 10^4 -- p=p*temp, p=10^3 and temp=10^3, hence p=10^3 * 10^3.
p = 10^4 * 10 = 10^5 -- Similarly for other steps.
i = 4 to 4
temp = 10^5
j = 1 to 2
p = 10^5 * 10 = 10^6
p = 10^6 * 10 = 10^7
There's a reason folks have called Python "executable pseudocode":
>>> def doSomething(*args):
... args = list(args);
... p = args.pop(0)
... for i in range(len(args)):
... temp = p
... for j in range(args[i]):
... p *= temp
... return p
...
>>> print doSomething(10,2,2,2)
1000000000000000000000000000
In C:
#include <stdio.h>
double DoSomething(double array[], int count)
{
double p, temp;
int i, j;
p = array[0];
for(i=1;i<count;i++)
{
temp = p;
for(j=0; j<array[i];j++)
{
printf("p=%g, temp=%g\n", p, temp); /* useful to see what's going on */
p = p * temp;
}
}
return p; /* this isn't specified, but I assume it's the procedure output */
}
double array[4] = {10.0,2.0,2.0,2.0};
int main(void)
{
printf("%g\n", DoSomething(array, 4));
return 0;
}
And, as others have indicated, 10e27. Note that the above is very verbose from your pseudo code - it could be simplified in many ways.
I used the Tiny C Compiler - very small, lightweight, and easy to use for simple stuff like this.
-Adam

Resources