bidirectional and deterministic binary decrement - binary

I am wondering whether its possible to implement in pure Prolog alone a binary decrementer which is bidirectional and deterministic. Example runs include and for mode (-,+):
?- dec(X,[0,0,1]).
X = [1,0,1]
?- dec(X,[1,1,1]).
X = [0,0,0,1]
And for mode (+,-):
?- dec([1,0,1],X).
X = [0,0,1]
?- dec([0,0,0,1],X).
X = [1,1,1]
Optionally none of the modes should leave any choice points. But mandatorily the implementation must be in pure Prolog alone, so no cut, no findall, no var, etc...
I already tried a definition as follows dec(X,Y) :- binary_plus([1],Y,X). using the binary adder here. But it doesn't pass the last test case, since I get dec([0,0,0,1],X). X = [1, 1, 1]; X = [1, 1, 1, 0] ; false..

The following two queries test for determinism. They do not succeed. Both run infinitely as is ; and fail with a given N. To indicate that non-termination is intended, the queries are prefixed with :/-&.
:/-& length(Bs,N), dec(Bs, Ds1), dif(Ds1, Ds2), dec(Bs, Ds2).
:/-& length(Ds,N), dec(Bs1, Ds), dif(Bs1, Bs2), dec(Bs2, Ds).
dec([1|Bs],[0|Bs]) :-
nil_or_ends_with_one(Bs).
dec([0|Bs],[1|Ds]) :-
deci(Bs, Ds).
nil_or_ends_with_one([]).
nil_or_ends_with_one([E|Es]) :-
ends_with_one(Es, E).
ends_with_one([], 1).
ends_with_one([E|Es], _) :-
ends_with_one(Es, E).
deci([1],[]).
deci([1|Bs],[0|Bs]) :-
Bs = [B|_],
ends_with_one(Bs, B).
deci([0|Bs],[1|Ds]) :-
deci(Bs, Ds).
The solution is still a bit too general, in that it accepts
?- dec([1,non_digit,1],[0,non_digit,1]).
This can be easily fixed but does not seem to be worth the cost.

I got a different solution which is not targeted towards a deep indexing Prolog, rather a flat indexing Prolog. So far all 4 test cases do not leave any choice point in Jekejeke Prolog which has full flat indexing. :-)
% check binary number
num([]).
num([X|Y]) :- dig(X, Y).
dig(1, []).
dig(T, [X|Y]) :- aux(T, X, Y).
aux(0, X, Y) :- dig(X, Y).
aux(1, X, Y) :- dig(X, Y).
% check binary number and its pseudo decrement
dec([X|Y], Z) :- dig(X, Y, Z).
dig(1, [], []).
dig(T, [X|Y], [U|V]) :- aux(T, U, V, X, Y).
aux(0, 1, Z, X, Y) :- dig(X, Y, Z).
aux(1, 0, [X|Y], X, Y) :- dig(X, Y).
https://gist.github.com/jburse/649f828c330ff3c770834ee8bca250a8#file-tarai-p
But the drawback of full flat indexing is the additional overhead when coding a predicate, to bring it into flat form. Flat form is also popular as the binary_plus/3 example shows. But the best would possibly be to have both flat and deep, and the later in a way that there exists a
deep dec/2 version which never leaves choice points.

Related

erlang max function logic

I have a maximum function. If I use this like: "module:max(6,6)." the result will be 6.
Why not "X = Y. There is no maximum." ?
max(X,Y) when X > Y -> X;
max(X,Y) when X < Y -> Y;
max(X,Y) -> io:fwrite("X = Y. There is no maximum.\n").
As I said your code should work since it works for me.
But try this one
max(X,X) -> io:fwrite("X = Y. There is no maximum.\n");
max(X,Y) when X > Y -> X;
max(X,Y) -> Y.
A function must return something. And better without any side effects. How do you understand that inputs are equal in your case? Especially if it's called like 'max(ok, ok)' or 'max(ok, 0)'.
Erlang max function definition just mimics mathematical one, it's the same in all sensible programming languages.
Works for me.
Are you actually using module:max/2 ?
It looks like you're using erlang:max/2.

Which is the correct way of cufft plan configuration in case of 3d fft's?

Lets say I have a 3 dimensional(x=256+2,y=256,z=128) array and I want to compute the FFT (forward and inverse) using cuFFT. And I have a fftw compatible data layout lets say the padding is in the x direction as shown in the size above(+2). How my plan should be ?
//forward
cufftPlan3d(&plan, z, y, x, CUFFT_R2C)
//or
cufftPlan3d(&plan, x, y, z, CUFFT_R2C)
and for inverse ?
//Inverse
cufftPlan3d(&plan, x, y, z, CUFFT_C2R)
//or
cufftPlan3d(&plan, z, y, x, CUFFT_C2R)
If the data is stored in column major order how is that going to affect the plan creation ?
If you are using cufftPlan3d, the right way to do it would be to use
cufftplan3d(&plan, x, y, z, type);
Here x means the first dimension, y means the second and z means the third.
In your case, you can use them as is without any issue.
All parameters are the same for both forward and inverse, except type which changes from CUFFT_R2C to CUFFT_C2R.
If you are going to use cufftplanMany, you will need to do something like this.
int dims[] = {z, y, x}; // reversed order
cufftPlanMany(&plan, 3, dims, NULL, 1, 0, NULL, 1, 0, type, batch);
cufftPlanMany is useful if you are doing batched operations, or if you working with non contiguous data.

Prolog binary addition without cuts(!)

I am trying to figure out how to add two binary numbers together which are represented as lists. For example:
addNumbers([1,0,1], [1,1,0,0], X). should return X = [1,0,0,0,1].
We are not aloud to use cuts(!) to solve this problem. So I know I have to implement a adder of sorts. Right now I have adding Digits implemented with its needed predicates:
addDigits(A,B,X,Y) :- myXor(A,B,X), myAnd(A,B,Y).
myAnd(A,B,R) :- A == 1, B == 1, R is 1.
myAnd(A,B,R) :- A == 0, B == 0, R is 0.
myAnd(A,B,R) :- A == 1, B == 0, R is 0.
myAnd(A,B,R) :- A == 0, B == 1, R is 0.
myOr(A,B,R) :- A == 0, B == 0, R is 0.
myOr(A,B,R) :- A == 0, B == 1, R is 1.
myOr(A,B,R) :- A == 1, B == 0, R is 1.
myor(A,B,R) :- A == 1, B == 1, R is 1.
This correctly returns X as the sum of the 2 binary digits and Y as the carry. Now I know I need this for my adder. Now to actually implement addDigits is where I am stuck. This is currently what I have but does not work. NOTE: The hint was the start the the LSB's but I currently don't do that.
addNumbers([HA|TA],[HB|TB],X) :- adder(HA,HB,Cin,Sum,Cout,X),
append(Sum, X, X),
addNumbers(TA,TB,X).
adder(X,Y,Cin,Sum,Cout) :- addDigits(X,Y,Sum1,Carry1),
addDigits(Sum1, Cin, Sum, Carry2),
myOr(Carry1, Carry2, Cout).
Any help/suggestions would be appreciated.
Cheers
You are on a good track. Your major problem is to understand typical Prolog recursion.
But first, your binary functions: They are correct, but it's easier and more readable like this (you are missing this one anyway):
myXor(1,0,1).
myXor(0,1,1).
myXor(1,1,0).
myXor(0,0,0).
There is a typo in your myOr in the fourth case: you spelled it with a lower case "o". With this defined, your adder does indeed work correctly!
Now, about the recursion: You really need to start with the LSB, otherwise you can't even know which bits to add, because the numbers are not necessarily the same length. Fortunately, you can do this easily by wrapping the call in reverses:
addNumbers(N1, N2, Sum) :-
reverse(N1, N12),
reverse(N2, N22),
addNumbers(N12, N22, 0, [], Sum0),
reverse(Sum0, Sum).
This is quite a common pattern in Prolog: addNumbers/3 calling addNumbers/5 with more parameters needed for the recursion. The "0" is the initial carry, the [] is the accumulator for the result.
Here is addNumbers/5, with some changes from your version:
addNumbers([HA|TA],[HB|TB],Cin,X0,X) :-
adder(HA,HB,Cin,Sum,Cout),
append(X0, [Sum], X1),
addNumbers(TA,TB,Cout,X1,X).
First, note that you need to receive Cin as an input parameter here! Also, we have X0 as an "accumulator" variable, that is, it grows longer with each recursive call. The final call will have the result, so it can make it into the output variable. For that, you also need the base cases:
addNumbers([],B,Cin,X0,X) :- % TODO: Respect Cin
append(X0,B,X).
addNumbers(A,[],Cin,X0,X) :- % TODO: Respect Cin
append(X0,A,X).
See how the result of append is not X1 (another intermediate variable) as above, but X? This is because its the final result, and it will be unified with the same X all the way down the call stack, and this way it becomes the output of the whole addNumbers/5 call!
I left it unfinished though, so that there is some (little) work for you left: Also the base cases need to take Cin into account...

Error plotting a function of 2 variables

I am trying to plot the function
f(x, y) = (x – 3).^2 – (y – 2).^2.
x is a vector from 2 to 4, and y is a vector from 1 to 3, both with increments of 0.2. However, I am getting the error:
"Subscript indices must either be real positive integers or logicals".
What do I do to fix this error?
I (think) I see what you are trying to achieve. You are writing your syntax like a mathematical function definition. Matlab is interpreting f as a 2-dimensional data type and trying to assign the value of the expression to data indexed at x,y. The values of x and y are not integers, so Matlab complains.
If you want to plot the output of the function (we'll call it z) as a function of x and y, you need to define the function quite differently . . .
f = #(x,y)(x-3).^2 - (y-2).^2;
x=2:.2:4;
y=1:.2:3;
z = f( repmat(x(:)',numel(y),1) , repmat(y(:),1,numel(x) ) );
surf(x,y,z);
xlabel('X'); ylabel('Y'); zlabel('Z');
This will give you an output like this . . .
The f = #(x,y) part of the first line states you want to define a function called f taking variables x and y. The rest of the line is the definition of that function.
If you want to plot z as a function of both x and y, then you need to supply all possible combinations in your range. This is what the line containing the repmat commands is for.
EDIT
There is a neat Matlab function meshgrid that can replace the repmat version of the script as suggested by #bas (welcome bas, please scroll to bas' answer and +1 it!) ...
f = #(x,y)(x-3).^2 - (y-2).^2;
x=2:.2:4;
y=1:.2:3;
[X,Y] = meshgrid(x,y);
surf(x,y,f(X,Y));
xlabel('x'); ylabel('y'); zlabel('z');
I typically use the MESHGRID function. Like so:
x = 2:0.2:4;
y = 1:0.2:3;
[X,Y] = meshgrid(x,y);
F = (X-3).^2-(Y-2).^2;
surf(x,y,F);
xlabel('x');ylabel('y');zlabel('f')
This is identical to the answer by #learnvst. it just does the repmat-ing for you.
Your problem is that the function you are using uses integers, and you are trying to assign a double to it. Integers cannot have decimal places. To fix this, you can make it to where it increases in increments of 1, instead of 0.2

Shading regions/inequalities of a 2D function in MATLAB

I've defined my own function with two input arguments (call it z(x,y) say) and managed to produce a contour plot. What I'd like to do now is to shade the region where, for example, z > 5. The main problem is that z is too complicated to be able to deduce the restrictions on x,y myself. Is there any simple way of doing this?
Did you try to use NaN?
z(condition) = nan;
before calling contour(), where condition can be on any combination of z, x, y, resulting binary matrix, for instance:
z(abs(z) > x - y) = nan;