Minizinc constraint against recursive function - minizinc

I want to use a function like this:
function int: nextr(var int: n)
if n <= 1
2
elseif n <= 8
n + 5
elseif n <= 68
n + 13
elseif n <= 509
n + 34
elseif n <= 3611
n + 89
else n + 233
in a constraint that variable must satisfy any value in nextr(n), nextr(nextr(n)), nextr(next(nextr(n))), and so on.
Is there a way to specify such constraint in minizinc? If not possible generally, I'm OK with explicit recursion limit, but without tedious enumeration of all the steps?

Example:
The value of y is constrained to be equal
next(x) \/ next(next(x)) \/ ...
up to K levels of nesting.
function var int: nextr(var int: n) =
if n <= 1 then
2
elseif n <= 8 then
n + 5
elseif n <= 68 then
n + 13
elseif n <= 509 then
n + 34
elseif n <= 3611 then
n + 89
else
n + 233
endif;
int: K = 10;
var int: x;
var int: y;
array[1..K] of var int: rec_up_to_k;
constraint forall (i in 1..K) (
if i == 1 then
rec_up_to_k[i] = nextr(x)
else
rec_up_to_k[i] = nextr(rec_up_to_k[i-1])
endif
);
constraint exists (i in 1..K) (
y = rec_up_to_k[i]
);
constraint x >= 0;
solve satisfy;
outputs:
x = 3612;
y = 3845;
rec_up_to_k = array1d(1..10, [3845, 4078, 4311, 4544, 4777, 5010, 5243, 5476, 5709, 5942]);
----------

Related

How can I vectorize the following calculation?

Suppose there is a value n input from a user and it goes in to the following for loop code. Is there a way to vectorize the following code?
A = 1:n
B = [1 1;1 1]
for i = 1:n
B = B + A(i)*B;
end
Let's have a look at a specific example:
n = 5;
A = 1:n;
B = [1 1; 1 1];
for i = 1:n
B = B + A(i) * B;
end
B
The result is:
B =
720 720
720 720
First of all, I would re-write the loop:
n = 5;
A = 1:n;
B = [1 1; 1 1];
for i = 1:length(A)
B = B * (A(i) + 1);
end
B
That way, it's more obvious, that your loop variable i simply iterates all elements in A.
Also: B + A(i) * B is the same as B * (A(i) + 1).
Now, we see, that inside the loop, you're basically calculating:
B = B * (A(1) + 1) * (A(2) + 1) * (A(3) + 1) ...
The product over all elements in A (or here: A + 1) can be simplified by using MATLAB's prod function:
n = 5;
A = 1:n;
B = [1 1; 1 1];
B = B * prod(A + 1)
Let's check the result:
B =
720 720
720 720
In that very special case for A = 1:n, the product prod(A + 1) is simply the factorial of n + 1, such that we could also use MATLAB's factorial function:
n = 5;
B = [1 1; 1 1];
B = B * factorial(n + 1)

Scala tail recursive method has an divide and remainder error

I'm currently computing the binomial coefficient of two natural numbers by write a tail recursion in Scala. But my code has something wrong with the dividing numbers, integer division by k like I did as that will give you a non-zero remainder and hence introduce rounding errors. So could anyone help me figure it out, how to fix it ?
def binom(n: Int, k: Int): Int = {
require(0 <= k && k <= n)
def binomtail(n: Int, k: Int, ac: Int): Int = {
if (n == k || k == 0) ac
else binomtail(n - 1, k - 1, (n*ac)/k)
}
binomtail(n,k,1)
}
In general, it holds:
binom(n, k) = if (k == 0 || k == n) 1 else binom(n - 1, k - 1) * n / k
If you want to compute it in linear time, then you have to make sure that each intermediate result is an integer. Now,
binom(n - k + 1, 1)
is certainly an integer (it's just n - k + 1). Starting with this number, and incrementing both arguments by one, you can arrive at binom(n, k) with the following intermediate steps:
binom(n - k + 1, 1)
binom(n - k + 2, 2)
...
binom(n - 2, k - 2)
binom(n - 1, k - 1)
binom(n, k)
It means that you have to "accumulate" in the right order, from 1 up to k, not from k down to 1 - then it is guaranteed that all intermediate results correspond to actual binomial coefficients, and are therefore integers (not fractions). Here is what it looks like as tail-recursive function:
def binom(n: Int, k: Int): Int = {
require(0 <= k && k <= n)
#annotation.tailrec
def binomtail(nIter: Int, kIter: Int, ac: Int): Int = {
if (kIter > k) ac
else binomtail(nIter + 1, kIter + 1, (nIter * ac) / kIter)
}
if (k == 0 || k == n) 1
else binomtail(n - k + 1, 1, 1)
}
Little visual test:
val n = 12
for (i <- 0 to n) {
print(" " * ((n - i) * 2))
for (j <- 0 to i) {
printf(" %3d", binom(i, j))
}
println()
}
prints:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
Looks ok, compare it with this, if you want.
Andrey Tyukin's excellent example will fail with larger n, say binom(10000, 2), but can be easily adapted to use BigInt.
def binom(n: Int, k: Int): BigInt = {
require(0 <= k && k <= n)
#annotation.tailrec
def binomtail(nIter: Int, kIter: Int, ac: BigInt): BigInt = {
if (kIter > k) ac
else binomtail(nIter + 1, kIter + 1, (nIter * ac) / kIter)
}
if (k == 0 || k == n) 1
else binomtail(n - k + 1, 1, BigInt(1))
}

Fibonacci function in matlab / octave

Help with Fibonacci function in octave / matlab.
The Fibonacci pattern is http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html
0 : 0
1 : 1
2 : 1
3 : 2
4 : 3
5 : 5
The function I have works but it skips a one how can I fix this so the function correctly follows the list above? Below is what my function creates.
0 : 0
1 : 1
2 : 2
3 : 3
4 : 5
5 : 8
See function below
function f = rtfib(n)
if n<0
multi=-1; %if neg number store neg in multi variable
n=abs(n); %if neg make pos
else
multi=1;
end
if (n == 0)
f = 0;
elseif (n==1)
f=1;
elseif (n == 2)
f = 2;
else
fOld = 2;
fOlder = 1;
for i = 3 : n
f = fOld + fOlder;
fOlder = fOld;
fOld = f;
end
end
f=f*multi; %put sign back
end
Ps: I'm using octave 4.0 which is similar to matlab
Original code found from
Create faster Fibonacci function for n > 100 in MATLAB / octave
The function you provided assumes the 3rd item of the 0-starting Fibonacci sequence is 2, and that is wrong. Just change that.
function f = rtfib(n)
if n<0
multi=-1; %if neg number store neg in multi variable
n=abs(n); %if neg make pos
else
multi=1;
end
if (n == 0)
f = 0;
elseif (n==1)
f=1;
elseif (n == 2)
f = 1; % its 1
else
fOld = 1; % 1 again.
fOlder = 1;
for i = 3 : n
f = fOld + fOlder;
fOlder = fOld;
fOld = f;
end
end
f=f*multi; %put sign back
end
Now it works:
for ii=0:15
r(ii+1)=rtfib(ii);
end
disp(r)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610

Octal number equations

So I'm reading a book on how binary bits are converted into octal numbers.
When trying to explain the concept, they give this equation
N= S(...((d8)2^8+(d7)2^7+(d6)2^6)+((d5)2^5+(d4)2^4+(d3)2^3)+((d2)2^2+(d1)2^1+d0))
or
N= S(...((d8)2^2 +(d7)2+(d6))2^6 + ((d5)2^2 +(d4)2^1 + (d3))2^3 + ((d2)2^2+(d1)2^1+d0))
d represents the digit found within the bit, e.g. if the least significant bit was 1, then (d0) would be 1.
I understand all of this, but they elaborate further saying that the parenthesized expressions ((d8)2^2 +(d7)2+(d6)) are coefficients of base 8 digits, N=S((d2)8^2+(d1)*8+(d0)).
Can someone explain what they mean by the parenthesized expressions being coefficients of base8 digits?
The digits di are the binary digits of the number. We can compute the number from its binary digits like this:
n = ∑ i 2i di = 20 d0 + 21 d1 + 22 d2 + ⋯
(This is in fact what defines “binary”, if we add the condition that the digits are integers and 0 ≤ di < 2 for all i.)
Suppose we name the octal digits of the number oj. We can compute the number from its octal digits like this:
n = ∑ j 8j oj = 80 o0 + 81 o1 + 82 o2 + ⋯
(This is what defines “octal”, if we add the condition that the digits are integers and 0 ≤ oj < 8 for all j.)
Now let's look back at the binary equation. The first step is the trickiest. We will change the way the subscript is used so that each term of the summation uses three binary digits:
n = ∑ j 23 j + 0 d3 j + 0 + 23 j + 1 d3 j + 1 + 23 j + 2 d3 j + 2
Convince yourself that that equation computes the same n as the first equation I gave.
I assume you know that xa + b = xa xb. So we can separate those 23 j + b coefficients like this:
n = ∑ j (23 j 20) d3 j + 0 + (23 j 21) d3 j + 1 + (23 j 22) d3 j + 2
Then we can factor out the 23 j term like this:
n = ∑ j 23 j (20 d3 j + 0 + 21 d3 j + 1 + 22 d3 j + 2)
I assume you also know that xa b = (xa)b. So we can split the 23 j term like this:
n = ∑ j (23)j (20 d3 j + 0 + 21 d3 j + 1 + 22 d3 j + 2)
And we can simplify 23 to 8:
n = ∑ j 8j (20 d3 j + 0 + 21 d3 j + 1 + 22 d3 j + 2)
Compare this to the formula for computing the number from its octal digits, which I repeat here:
n = ∑ j 8j oj
So we can conclude this:
oj = 20 d3 j + 0 + 21 d3 j + 1 + 22 d3 j + 2
For example, let's take j = 2:
o2 = 20 d3×2 + 0 + 21 d3×2 + 1 + 22 d3×2 + 2 = 20 d6 + 21 d7 + 22 d8

Difference between skewness function and skewness formula result

Consider the matrix
c =
1 2
3 4
m = 2;
n = 2;
% mean
% sum1 = uint32(0);
b4 = sum(c);
b5 = sum(b4');
c5 = b5 / ( m * n )
% standard deviation
sum2 = uint32(0);
for i = 1 : m
for j = 1 : n
b = ( double(c(i,j)) - c5 ) ^ 2 ;
sum2 = sum2 + b ;
end
end
sum3 = sum2 / ( m * n );
std_dev = sqrt(double(sum3))
% skewness
sum9 = 0;
for i = 1 : m
for j = 1 : n
skewness_old = ( ( double(c(i,j)) - c5 ) / ( std_dev) )^ 3 ;
sum9 = sum9 + skewness_old ;
end
end
skewness_new = sum9 / ( m * n )
The skewness result is 0
If I use the matlab function skewness,
skewness(c)
c =
1 2
3 4
skewness(c)
ans =
0 0
Why is the function skewness returning two 0's, While the formula returns only one 0
MATLAB function SKEWNESS by default calculates skewness for each column separately. For the whole matrix do skewness(c(:)).