Nand2tetris ALU implementation without using Muxes - alu

i am trying to implement Hack ALU without using muxes but i cant upload the hdl into the simulator. Any help would be appreciated. Thanks
CHIP ALU {
IN
x[16], y[16], // 16-bit inputs
zx, // zero the x input?
nx, // negate the x input?
zy, // zero the y input?
ny, // negate the y input?
f, // compute out = x + y (if 1) or x & y (if 0)
no; // negate the out output?
OUT
out[16], // 16-bit output
zr, // 1 if (out == 0), 0 otherwise
ng; // 1 if (out < 0), 0 otherwise
PARTS:
// Put you code here:
//To zero x or not
Not(in=zx, out=notzx);
And16(a=x, b[0..15]=notzx, out=zerox);
//To zero y or not
Not(in=zy, out=notzy);
And16(a=y, b[0..15]=notzy, out=zeroy);
//Negate x or not
Xor16(a=zerox, b[0..15]=nx, out=negatex);
//Negate y or not
Xor16(a=zeroy, b[0..15]=ny, out=negatey);
Not(in=f, out=fnot);
//"and" or "add" x?
And16(a=negatex, b[0..15]=f, out=addx);
And16(a=negatex, b[0..15]=fnot, out=andx);
//"and" or "add" y
And16(a=negatey, b[0..15]=f, out=addy);
And16(a=negatey, b[0..15]=fnot, out=andy);
//adding x and y
Add16(a=addx, b=addy, out=sum);
//anding x and y
And16(a=andx, b=andy, out=outxandy);
//output of adding or anding
Or16(a=sum, b=outxandy, out=out1);
//Negating using "Xor"
Xor16(a=out1, b[0..15]=no, out=out2);
Not(in=out2[15], out=ng);
Or8Way(in=out2[0..7], out=zr1);
Or8Way(in=out2[8..15], out=zr2);
Or(a=zr1, b=zr2, out=zr);
And16(a=out2, b=out2, out=out);

Inputs like b[0..15]=notzx are not valid in HDL because the two sides of the assignment do not have the same width. The only values that have variable width are true and false.
You might try something like:
And16(a=x, b[0]=notzx, b[1]=notzx, ... , b[15]=notzx, out=zerox);

Related

Minimize difference between indicator variables in Matlab

I'm new to Matlab and want to write a program that chooses the value of a parameter (P) to minimize the difference between two vectors, where each vector is a variable in a dataframe. The first vector (call it A) is a predetermined vector of 1s and 0s, and the second vector (call it B) has each of its entries determined as an indicator function that depends on the value of the parameter P and other variables in the dataframe. For instance, let C be a third variable in the dataset, so
A = [1, 0, 0, 1, 0]
B = [x, y, z, u, v]
where x = 1 if (C[1]+10)^0.5 - P > (C[1])^0.5 and otherwise x = 0, and similarly, y = 1 if (C[2]+10)^0.5 - P > (C[2])^0.5 and otherwise y = 0, and so on.
I'm not really sure where to start with the code, except that it might be useful to use the fminsearch command. Any suggestions?
Edit: I changed the above by raising to a power, which is closer to the actual example that I have. I'm also providing a complete example in response to a comment:
Let A be as above, and let C = [10, 1, 100, 1000, 1]. Then my goal with the Matlab code would be to choose a value of P to minimize the differences between the coordinates of the vectors A and B, where B[1] = 1 if (10+10)^0.5 - P > (10)^0.5 and otherwise B[1] = 0, and similarly B[2] = 1 if (1+10)^0.5 - P > (1)^0.5 and otherwise B[2] = 0, etc. So I want to choose P to maximize the likelihood that A[1] = B[1], A[2] = B[2], etc.
I have the following setup in Matlab, where ds is the name of my dataset:
ds.B = zeros(size(ds,1),1); % empty vector to fill
for i = 1:size(ds,1)
if ((ds.C(i) + 10)^(0.5) - P > (ds.C(i))^(0.5))
ds.B(i) = 1;
else
ds.B(i) = 0;
end
end
Now I want to choose the value of P to minimize the difference between A and B. How can I do this?
EDIT: I'm also wondering how to do this when the inequality is something like (C[i]+10)^0.5 - P*D[i] > (C[i])^0.5, where D is another variable in my dataset. Now P is a scalar being multiplied rather than just added. This seems more complicated since I can't solve for P exactly. How can I solve the problem in this case?
EDIT 1: It seems fminbnd() isn't optimal, likely due to the stairstep nature of the indicator function. I've updated to test the midpoints of all the regions between indicator function flips, plus endpoints.
EDIT 2: Updated to include dataset D as a coefficient of P.
If you can package your distance calculation up in a single function based on P, you can then search for its minimum.
arraySize = 1000;
ds.A = double(rand([arraySize,1]) > 0.5);
ds.C = rand(size(ds.A));
ds.D = rand(size(ds.A));
B = #(P)double((ds.C+10).^0.5 - P.*ds.D > ds.C.^0.5);
costFcn = #(P)sqrt(sum((ds.A-B(P)).^2));
% Solving the equation (C+10)^0.5 - P*D = C^0.5 for P, and sorting the results
BCrossingPoints = sort(((ds.C+10).^0.5-ds.C.^0.5)./ds.D);
% Taking the average of each crossing point with its neighbors
BMidpoints = (BCrossingPoints(1:end-1)+BCrossingPoints(2:end))/2;
% Appending endpoints onto the midpoints
PsToTest = [BCrossingPoints(1)-0.1; BMidpoints; BCrossingPoints(end)+0.1];
% Calculate the distance from A to B at each P to test
costResult = arrayfun(costFcn,PsToTest);
% Find the minimum cost
[~,lowestCostIndex] = min(costResult);
% Find the optimum P
optimumP = PsToTest(lowestCostIndex);
ds.B = B(optimumP);
semilogx(PsToTest,costResult)
xlabel('P')
ylabel('Distance from A to B')
1.- x is assumed positive real only, because with x<0 then complex values show up.
Since no comment is made in the question it seems reasonable to assume x real and x>0 only.
As requested, P 'the parameter' a scalar, P only has 2 significant states >0 or <0, let's see how is this:
2.- The following lines generate kind-of random A and C.
Then a sweep of p is carried out and distances d1 and d2 are calculated.
d1 is euclidean distance and d2 is the absolute of the difference between A and and B converting both from binary to decimal:
N=10
% A=[1 0 0 1 0]
A=randi([0 1],1,N);
% C=[10 1 1e2 1e3 1]
C=randi([0 1e3],1,N)
p=[-1e4:1:1e4]; % parameter to optimize
B=zeros(1,numel(A));
d1=zeros(1,numel(p)); % euclidean distance
d2=zeros(1,numel(p)); % difference distance
for k1=1:1:numel(p)
B=(C+10).^.5-p(k1)>C.^.5;
d1(k1)=(sum((B-A).^2))^.5;
d2(k1)=abs(sum(A.*2.^[numel(A)-1:-1:0])-sum(B.*2.^[numel(A)-1:-1:0]));
end
figure;
plot(p,d1)
grid on
xlabel('p');title('d1')
figure
plot(p,d2)
grid on
xlabel('p');title('d2')
The only degree of freedom to optimise seems to be the sign of P regardless of |P| value.
3.- f(p,x) has either no root, or just one root, depending upon p
The threshold funtion is
if f(x)>0 then B(k)==1 else B(k)==0
this is
f(p,x)=(x+10)^.5-p-x^.5
Now
(x+10).^.5-p>x.^.5 is same as (x+10).^.5-x.^.5>p
There's a range of p that keeps f(p,x)=0 without any (real) root.
For the particular case p=0 then (x+10).^.5 and x.^.5 do not intersect (until Inf reached = there's no intersection)
figure;plot(x,(x+10).^.5,x,x.^.5);grid on
[![enter image description here][3]][3]
y2=diff((x+10).^.5-x.^.5)
figure;plot(x(2:end),y2);
grid on;xlabel('x')
title('y2=diff((x+10).^.5-x.^.5)')
[![enter image description here][3]][3]
% 005
This means the condition f(x)>0 is always true holding all bits of B=1. With B=1 then d(A,B) turns into d(A,1), a constant.
However, for a certain value of p then there's one root and f(x)>0 is always false keeping all bits of B=0.
In this case d(A,B) the cost function turns into d(A,0) and this is A itself.
4.- P as a vector
The optimization gains in degrees of freedom if instead of P scalar, P is considered as vector.
For a given x there's a value of p that switches B(k) from 0 to 1.
Any value of p below such threshold keeps B(k)=0.
Equivalently, inverting f(x) :
g(p)=(10-p^2)^2/(4*p^2)>x
Values of x below this threshold bring B closer to A because for each element of B it's flipped to the element value of A.
Therefore, it's convenient to consider P as a vector, not a ascalar, and :
For all, or as many (as possible) elements of C to meet c(k)<(10-p^2)^2/(4*p^2) in order to get C=A or
minimize d(A,C)
5.- roots of f(p,x)
syms t positive
p=[-1000:.1:1000];
zp=NaN*ones(1,numel(p));
sol=zeros(1,numel(p));
for k1=1:1:numel(p)
p(k1)
eq1=(t+10)^.5-p(k1)-t^.5-p(k1)==0;
s1=solve(eq1,t);
if ~isempty(s1)
zp(k1)=s1;
end
end
nzp=~isnan(zp);
zp(nzp)
returns
=
620.0100 151.2900 64.5344 34.2225 20.2500 12.7211
8.2451 5.4056 3.5260 2.2500 1.3753 0.7803
0.3882 0.1488 0.0278

How to fix the difference in precision between double data type and uint64

I'm in the process of implementing Three Fish block cipher using MATLAB. At first, I implemented the algorithm on uint8 numbers to validate my code. Every thing was OK and the decryption was successful. But when I replaced the numbers to uint64 the plain text did not retrieved correctly.
I traced the rounds results again and over again to find the reason, but I couldn't find it so far. There is difference in the first four digits between encryption and decryption, that is, along the rounds x encrypted as 9824265115183455531, but it decrypts as 9824265115183455488.
I think the reason behind this difference is in the functions AddMod64 and SubMod64 to find arithmetic modulo 2 to the power 64. but really I could not fix it so far.
I know that
double(2^64) = 18446744073709552000
and
uint64(2^64) = 18446744073709551615 % z = ( x + y ) % 2^64
function z = AddMod64(x , y)
m = uint64(2^64);
z = double(mod(mod(double(x),m)+mod(double(y),m),m));
end
% z = (x - y ) % 2^64
function z = SubMod64(x , y)
m = uint64(2^64);
z = double(mod(mod(double(x),m) - mod(double(y),m),m));
end
double(2^64) is already the wrong result, the double type can hold only up to 2^52-1 as an integer without rounding.
Also, when you do uint64(2^64), the power is computed using double, giving the wrong result, which you then cast to uint64. And because the maximum value that a uint64 van hold is 2^64-1, that whole operation is wrong.
Use maxint instead:
m = maxint('uint64');
To do modulo addition in MATLAB is rather tricky, because MATLAB does saturated arithmetic with integers. You need to test for overflow before doing the computation.
if x > m - y
x = y - (m - x + 1);
else
x = x + y
end

Applying threshold to an image

I am trying to write a function that thresholds a grey-level image F and a threshold value t (0 ≤ t ≤ 255) such that r = 0 for r < t and r = 255 otherwise.
I have tried to implement this, but imshow(r) does not produce an output.
function f = imgThreshold(img, t)
f = img;
if (f < t)
f = 0;
else
f = 1;
end
img = imread('https://i.stack.imgur.com/kP0u2.png');
t = 20;
r = imgThreshold(img, t);
imshow(r);
This should threshold this image. However, it does not do so. What am I doing wrong?
Best would be to use logical indexing:
f(f<t)=0; % set all elements of f<t to 0
f(~(f==0))=1; % Set all elements where f is not 0 (i.e. the rest) to 1
f<t nicely produces a logical matrix adhering to the condition, but subsequently you do either f=1 or f=0, meaning that you set the entirety of f to be a scalar (one or zero), which of course just plots a black or white square. Instead, use the logical matrix as indexing operation into the matrix itself, then assigning the desired value to each true entry, like above.
Also a function definition either goes in its own file, or on the bottom of the script. Thus either you save the function as imgThreshold.m and leave the rest for the script, or first call the script and place function f = imgThreshold(img, t) etc after the call to imshow

How can I create a probability density function in Matlab?

I have a table with two sets of values.
And I want to create equally sized bins of x, count the number of values of y in each bin and then plot it.
How can I do it?
Data
x y
0 0.0023243872
815.54065 0.0021484715
1111.9492 0.0023388069
1378.9236 0.0021542402
1631.0813 0.0021254013
1927.4899 0.0023618778
2194.3323 0.0021484711
2223.8984 0.0023157364
2446.6221 0.0022868966
2490.8728 0.0023388073
2743.0305 0.0024801167
3009.7410 0.0021917303
3262.1626 0.0022955481
3306.2815 0.0021052146
3335.8479 0.0023330392
3558.5713 0.0024772326
3602.6660 0.0023474589
3825.1497 0.0022292205
4121.6904 0.0021023308
4374.1118 0.0024916520
4447.7969 0.0023935998
4640.5586 0.0022522912
4714.5371 0.0023705289
4937.0991 0.0022263369
5233.6396 0.0021773111
5262.8101 0.0024656970
5455.9673 0.0024339736
5559.7461 0.0024455092
5752.5078 0.0021167498
5752.5078 0.0027021724
5826.4863 0.0023936001
6019.4819 0.0027021721
6048.7842 0.0021686594
6271.3760 0.0024368572
6345.5889 0.0022321043
6567.9165 0.0021167498
6612.3291 0.0022205692
6835.0225 0.0027165920
7131.4312 0.0027483148
7160.6016 0.0023849490
7427.3418 0.0020042793
7457.5381 0.0022032652
7650.2212 0.0021109823
7724.2002 0.0023301556
7724.2783 0.0022090334
7724.2783 0.0021801949
7947.1040 0.0028059918
7947.1040 0.0027425468
8242.3545 0.0019927442
8243.3809 0.0029588358
8465.4980 0.0024455097
8465.4980 0.0022032652
8510.5107 0.0029213454
8539.2910 0.0022148010
8539.2910 0.0020734922
8762.1709 0.0021686594
8762.1709 0.0026070056
8762.7764 0.0028232955
8805.9531 0.0020042795
8806.0313 0.0020590730
I am not sure to understand how we need y.
Is this what you are looking for ?
N = 100 ;
x = rand(N, 1) ;
M = hist(x) ;
plot(M) ;
I don't think the y matters. You just want to count the number of references to the x, which represent the y. You can use the hist(x, bins) method where x is the vector of data, your x, and bins is the number of bins you would like to put them in.
See http://www.mathworks.com/help/matlab/ref/hist.html

linear combination of curves to match a single curve

I have a set of vectors (length of 50, essentially a set of curves) that i want to try to match another single curve(vector) and obtain the coefficients of each of the vectors in the first set to match the second curve. The coefficients need to be >= 0.0 . I.e, a linear combination of the first set of curves to match the single curve. Any help in which direction I should go would be helpful.
If I understand correctly, you have a set of curves
each of which you want to multiply with a scaling factor, so that it reproduces some target curve
as closely as possible.
This is easily done with a linear least squares approximation.
%# create some sample curves
x = -10:0.1:10;
g1 = exp(-(x-3).^2/4);
g2 = exp(-(x-0).^2/4);
g3 = exp(-(x+2).^2/4);
%# make a target curve, corrupt with noise
y = 2*g1+4*g2+g3+randn(size(x))*0.2;
%# use the `ldivide` operator to solve an equation of the form
%# A*x=B
%# so that x (=fact here) is x=A^-1*B or, in Matlab terms, A\B
%# note the transposes, A should be a n-by-3 array, B a n-by-1 array
%# so that x is a 3-by-1 array of factors
fact = [g1;g2;g3]'\y'
fact =
1.9524
3.9978
1.0105
%# Show the result
figure,plot(x,y)
hold on,plot(x,fact(1)*g1+fact(2)*g2+fact(3)*g3,'m')
so thats what he meant!..
mathematica version..
x = Table[i, {i, -10, 10, .1}];
basis = {
Exp[-(# - 3)^2/4] & /# x,
Exp[-(# - 0)^2/4] & /# x,
Exp[-(# + 2)^2/4] & /# x
};
Show[
ListPlot[Table[{x[[i]], #[[i]]}, {i, Length[x]}] ,
Joined -> True , PlotStyle -> Hue [Random[]]] & /# basis ]
y = Table [ 2 basis[[1, i]] + 4 basis[[2, i]] + basis[[3, i]] +
RandomReal[{.5, .5}] ,{i, Length[x]}];
dataplot = ListPlot[Table[{x[[i]], y[[i]]}, {i, Length[x]}] ]
mathematica does not magically do least squares if you simply solve an underdetermined system, so find a least squres result explicitly:
coefs = FindMinimum[
Total[(#^2 & /# (Sum[a[k] basis[[k]] , {k, Length[basis]}]-y) )],
Array[a, Length[basis]]][[2]]
Show[dataplot,
ListPlot[i = 0; {x[[++i]], #} & /#
(Sum[a[k] basis[[k]] , {k, 3}] /. coefs),
Joined -> True]]
note if you want ot restrict the coefficents to be >= 0 as stated you can simply square the values in the formulation like this:
coefs = FindMinimum[
Total[(#^2 & /#
(Sum[a[k]^2 basis[[k]] , {k, Length[basis]}]-y) )],
Array[a, Length[basis]]][[2]]
Show[dataplot,
ListPlot[i = 0; {x[[++i]], #} & /#
(Sum[a[k]^2 basis[[k]] , {k, 3}] /. coefs),
Joined -> True]]
you will get predictably poor results if the actual best fit wants to have a negative value.