Convert decimal fractions to binary using sum of power of 2 method - numbers

How to convert the following decimal fractions to binary?
1/2=0.1
1/4= 0.01
1/8=0.001
How can these be assigned??
Please explain...

In the decimal numeration, the digits have the following weights:
... 10000 1000 100 10 1 comma 1/10 1/100 1/1000 1/10000 ...
so that
23.51d is 2 x 10 + 3 x 1 + 5 x 0.1 + 1 x 0.01
Similarly, in the binary numeration, the weights are
... 16 8 4 2 1 comma 1/2 1/4 1/8 1/16 ...
so that
11.01b is 1 x 2 + 1 x 1 + 0 x 1/2 + 1 x 1/4 = 3.25d
And
0.1b is 1/2
0.01b is 1/4
0.001b is 1/8
...

Related

Why Int8.max &+ Int8.max equals to "-2"?

Following Swift Standard Library documentation, &+ discards any bits that overflow the fixed width of the integer type. I just did not get why adding two maximum values, 8-bit signed integer can hold results in -2:
/// Two max Int8 values (127 each, 8-bit group)
let x6 = Int8.max
let x7 = Int8.max
/// Prints `1 1 1 1 1 1 1`
String(Int8.max, radix: 2)
/// Here we get `-2` in decimal system
let x8 = x6 &+ x7
/// Prints `-1 0`
String(x8, radix: 2)
If we break down the binary calculation we will get this:
1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1
-----------------------------
1 1 1 1 1 1 1 0
Which is -126, as the leftmost bit is a negative sign.
Why does Swift discards any bits except the rightmost two (1 and 0). Did I miss some overflow rules? I've read some pieces of knowledge in the web, but did not get closed to cracking this one.
Swift (and every other programming language I know) uses 2's complement to represent signed integers, rather than sign-and-magnitude as you seem to assume.
In the 2's complement representation, the leftmost 1 does not represent "a negative sign". You can think of it as representing -128, so the Int8 value of -2 would be represented as 1111 1110 (-128 + 64 + 32 + 16 + 8 + 4 + 2).
OTOH, -126 would be represented as 1000 0010 (-128 + 2).

Faster way to transpose each row of a matrix and multiply the resulting vector by some other matrix?

I have an input matrix X with dimensions N_rows x N_cols. I also have a sparse, tridiagonal matrix M which is square of size N_rows x N_rows. These are created as follows:
N_rows = 3;
N_cols = 6;
X = rand(N_rows,N_cols);
mm = 10*ones(N_cols,1); % Subdiagonal elements
dd = 20*ones(N_cols,1); % Main diagonal elements
pp = 30*ones(N_cols,1); % Superdiagonal elements
M = spdiags([mm dd pp],-1:1,N_cols,N_cols);
and look like the following:
>> X
X =
0.4018 0.1233 0.4173 0.9448 0.3377 0.1112
0.0760 0.1839 0.0497 0.4909 0.9001 0.7803
0.2399 0.2400 0.9027 0.4893 0.3692 0.3897
full(M)
ans =
2 3 0 0 0 0
1 2 3 0 0 0
0 1 2 3 0 0
0 0 1 2 3 0
0 0 0 1 2 3
0 0 0 0 1 2
I would like to take each row of X, and do a matrix multiplication with M, and piece the obtained rows back together to obtain an output Y. At the moment, I achieve this successfully with the following:
Y = (M*X.').';
The example above is for a 3x6 matrix for X, but in reality I need to do this for a matrix with dimensions 500 x 500, about 10000 times, and the profiler says that this operation in the bottleneck in my larger code. Is there a faster way to do this row-by-row matrix multiplication multiplication?
On my system, the following takes around 20 seconds to do this 10000 times:
N_rows = 500;
N_cols = 500;
X = rand(N_rows,N_cols);
mm = 10*ones(N_cols,1); % Subdiagonal elements
dd = 20*ones(N_cols,1); % Main diagonal elements
pp = 30*ones(N_cols,1); % Superdiagonal elements
M = spdiags([mm dd pp],-1:1,N_cols,N_cols);
tic
for k = 1:10000
Y = (M*X.').';
end
toc
Elapsed time is 18.632922 seconds.
You can use X*M.' instead of (M*X.').';. This saves around 35% of time on my computer.
This can be explained because transposing (or permuting dimensions) implies rearranging the elements in the internal (linear-order) representation of the matrix, which takes time.
Another option is using conv2:
Y = conv2(X, [30 20 10], 'same');
Explanation:
There is a tridiagonal matrix that all elements on each diagonal are identical to each other:
M =
2 3 0 0 0 0
1 2 3 0 0 0
0 1 2 3 0 0
0 0 1 2 3 0
0 0 0 1 2 3
0 0 0 0 1 2
Suppose you want to multiply the matrix by a vector:
V = [11 ;12 ;13 ;14 ;15 ;16];
R = M * V;
Each element of the vector R is computed by sum of products of each row of M by V:
R(1):
2 3 0 0 0 0
11 12 13 14 15 16
R(2):
1 2 3 0 0 0
11 12 13 14 15 16
R(3):
0 1 2 3 0 0
11 12 13 14 15 16
R(4):
0 0 1 2 3 0
11 12 13 14 15 16
R(5):
0 0 0 1 2 3
11 12 13 14 15 16
R(6):
0 0 0 0 1 2
11 12 13 14 15 16
It is the same as multiplying a sliding window of [1 2 3] by each row of M. Basically convolution applies a sliding window but first it reverses the direction of window so we need to provide the sliding window in the reversed order to get the correct result. Because of that I used Y = conv2(X, [30 20 10], 'same'); instead of Y = conv2(X, [10 20 30], 'same');.

MATLAB: building gradient between two columns in greyscale image

I have two images, one of which is a greyscale image (orig), the other is a binary image of the same size with vertical lines (mask). Where the binary value is 1 I would like on the grey scale to create a gradient from the two columns of values on either side of the binary line. For example:
binary: old greyscale: new greyscale:
0 0 1 1 1 0 0 x 10 x x x 6 x x 10 9 8 7 6 x
0 0 1 1 1 0 0 x 1 x x x 5 x x 1 2 3 4 5 x
0 0 1 1 1 0 0 x 5 x x x 13 x x 5 7 9 11 13 x
0 0 1 1 1 0 0 x 10 x x x 2 x x 10 8 6 4 2 x
I have the following code so far...not sure if its of any value...it runs through and finds the x location of the start of a vertical streak in vectempa, width in vectempb, and then the value from the greyscale on either side in vectemp1 and vectemp2. Current plan is to take the absolute value of difference of each column in vectemp1 and vectemp2, divide by that column in vectempb (width), and then use that to increment the gradient...somehow accounting for direction of the gradient. Does this make sense or is there a much better/easier way to do this?
vectempa=[];
vectempb=[];
vectemp1=[];
vectemp2=[];
q=1;
r=1;
for i=1:x
if mask(1,i)==0 && mask(1,(i+1))==1
vectempa(end+1)=i;
vectemp1(1:z,q)=orig((1:z),i);
q=q+1;
elseif mask(1,i)==1 && mask(1,(i+1))==0
vectempb(end+1)=i-vectempa(end);
vectemp2(1:z,r)=orig((1:z),i);
r=r+1;
end
end
Thanks!
Is it possible you are looking for roifill?
new = roifill( old, mask );

Find Value at a given Orientation in Matrix

In Matlab I've matrix where, in a previous stage of my code, an specific element was chosen. From this point of the matrix I would like to find a maximum, not just the maximum value between all its surounding neighbours for a given radius, but the maximum value at a given angle of orientation. Let me explain this with an example:
This is matrix A:
A =
0 1 1 1 0 0 9 1 0
0 2 2 4 3 2 8 1 0
0 2 2 3 3 2 2 1 0
0 1 1 3 2 2 2 1 0
0 8 2 3 3 2 7 2 1
0 1 1 2 3 2 3 2 1
The element chosen in the first stage is the 4 in A(2,4), and the next element should be the maximum value with, for example, a 315 degrees angle of orientation, that is the 7 in A(5,7).
What I've done is, depending on the angle, subdivide matrix A in different quadrants and make a new matrix (an A's submatrix) with only the values of that quadrant.
So, for this example, the submatrix will be A's 4th quadrant:
q_A =
4 3 2 8 1 0
3 3 2 2 1 0
3 2 2 2 1 0
3 3 2 7 2 1
2 3 2 3 2 1
And now, here is my question, how can I extract the 7?
The only thing I've been able to do (and it works) is to find all the values over a threshold value and then calculate how those points are orientated. Then, saving all the values that have a similar orientation to the given one (315 degrees in this example) and finally finding the maximum among them. It works but I guess there could be a much faster and "cleaner" solution.
This is my theory, but I don't have the image processing toolbox to test it. Maybe someone who does can comment?
%make (r,c) the center by padding with zeros
if r > size(A,1)/2
At = padarray(A, [size(A,1) - r], 0, 'pre');
else
At = padarray(A, [r-1], 0 'post');
if c > size(A,2)/2
At = padarray(At, [size(A,2) - c], 0, 'pre');
else
At = padarray(At, [c-1], 0 'post');
%rotate by your angle (maybe this should be -angle or else 360-angle or 2*pi-angle, I'm not sure
Ar = imrotate(At,angle, 'nearest', 'loose'); %though I think nearest and loose are defaults
%find the max
max(Ar(size(Ar,1)/2, size(Ar,2)/2:end); %Obviously you must adjust this to handle the case of odd dimension sizes.
Also depending on your array requirements, padding with -inf might be better than 0
The following is a relatively inexpensive solution to the problem, although I found wrapping my head around the matrix coordinate system a real pain, and there is probably room to tidy it up somewhat. It simply traces all matrix entries along a line around the starting point at the supplied angle (all coordinates and angles are of course based on matrix index units):
A = [ 0 1 1 1 0 0 9 1 0
0 2 2 4 3 2 8 1 0
0 2 2 3 3 2 2 1 0
0 1 1 3 2 2 2 1 0
0 8 2 3 3 2 7 2 1
0 1 1 2 3 2 3 2 1 ];
alph = 315;
r = 2;
c = 4;
% generate a line through point (r,c) with angle alph
[nr nc] = size(A);
x = [1:0.1:nc]; % overkill
m = tan(alph);
b = r-m*c;
y = m*x + b;
crd = unique(round([y(:) x(:)]),'rows');
iok = find((crd(:,1)>0) & (crd(:,1)<=nr) & (crd(:,2)>0) & (crd(:,2)<=nc));
crd = crd(iok,:);
indx=sub2ind([nr,nc],crd(:,1),crd(:,2));
% find max and position of max
[val iv]=max(A(indx)); % <-- val is the value of the max
crd(iv,:) % <-- matrix coordinates (row, column) of max value
Result:
val =
7
iv =
8
ans =
5 7

find and replace zeros with a function in matlab

Once again, sorry if this has been asked before and if its too specific but I'm very stuck and can't quite find a solution.
I have a matrix of say 3 members of a structure called 2, 4 and 16 (in column 1) that have values along their relative distance e.g. member 2 has values at the start, 0m, then at 0.5m then the end of its length 1.5m, where member 4 starts at 0m etc. So that my matrix looks like this:
2 0 125
2 0.5 25
2 1.5 365
4 0 25
4 0.6 57
16 0 354
16 0.2 95
16 0.8 2
and I want to create a matrix that has the overall distance along all the members 2, 4 and 16 combined:
2 0 125
2 0.5 25
2 1.5 365
4 1.5 25
4 2.1 57
16 2.1 354
16 2.3 95
16 3.1 2
is there any way to do this in matlab? Like possibly locating the first zero and adding the value above it to all the rest of the values below then find the next zero value and so on?
Please tell me if this isn't clear, I realise it's a bit confusing but not too sure how to explain it better!
I came up with the following:
idx = find(diff(M(:,1)));
v = zeros(size(M,1),1);
v(idx+1) = M(idx,2);
M(:,2) = M(:,2) + cumsum(v);
The result:
M =
2 0 125
2 0.5 25
2 1.5 365
4 1.5 25
4 2.1 57
16 2.1 354
16 2.3 95
16 2.9 2
Note the last value in the second column disagrees with what you described (2.9 vs 3.1). Either you had a typo, or I'm still not getting it...
data = [2 0 125;
2 0.5 25;
2 1.5 365;
4 0 25;
4 0.6 57;
16 0 354;
16 0.2 95;
16 0.8 2];
idx0 = find(data(:,2)==0);
idx0 = idx0(2:end); %ignore first zero of first member, doesn't need an offset
offset = data(idx0-1,2);
N = size(data,1);
for ii=1:numel(idx0)
idxs = 1:N>=idx0(ii);
data(idxs,2) = data(idxs,2) + offset(ii);
end