Converstion from SOP to POS using boolean algebra - digital-logic

The question is this:
wx'y'+wyz'+w'x'z
I tried this technique but got stuck:
w(x'y'+yz')+w'x'z
(w+x'z)(w'+x'y'+yz')
(w+x')(w+z)(w'+x'y'+yz')
but this is not correct since it should end with 4 pos terms.
How can I convert this from sum of products to product of sums correctly?

From this SOP (Sum Of Products) expression, wx'y' + wyz' + w'x'z, get this K-MAP (Karnaugh MAP):
\ yz
\ 00 01 11 10
wx \
00 0 0 1 1
01 0 0 0 0
11 0 0 0 1
10 1 1 0 1
From that K-MAP, get this POS (Product Of Sums) expression: (w+y)(w+x')(x'+y)(w'+y'+z'). Alternatively, you could use boolean algebra, but I think K-MAPs are usually easier and/or less error prone.

Related

Speed up code to compare fields in a struct

I have the struct Trajectories with field uniqueDate, dateAll, label: I want to compare the fields uniqueDate and dateAll and, if there is a correspondence, I will save in label a value from an other struct.
I have written this code:
for k=1:nCols
for j=1:size(Trajectories(1,k).dateAll,1)
for i=1:size(Trajectories(1,k).uniqueDate,1)
if (~isempty(s(1,k).places))&&(Trajectories(1,k).dateAll(j,1)==Trajectories(1,k).uniqueDate(i,1))&&(Trajectories(1,k).dateAll(j,2)==Trajectories(1,k).uniqueDate(i,2))&&(Trajectories(1,k).dateAll(j,3)==Trajectories(1,k).uniqueDate(i,3))
for z=1:24
if(Trajectories(1,k).dateAll(j,4)==z)&&(size(s(1,k).places.all,2)>=size(Trajectories(1,k).uniqueDate,1))
Trajectories(1,k).label(j)=s(1,k).places.all(z,i);
else if(Trajectories(1,k).dateAll(j,4)==z)&&(size(s(1,k).places.all,2)<size(Trajectories(1,k).uniqueDate,1))
for l=1:size(s(1,k).places.all,2)
Trajectories(1,k).label(l)=s(1,k).places.all(z,l);
end
end
end
end
end
end
end
end
E.g
Trajectories(1,4).dateAll=[1 2004 8 1 14 1 15 0 0 0 1 42 13 2;596 2004 8 1 16 20 14 0 0 0 1 29 12 NaN;674 2004 8 1 18 26 11 0 0 0 1 20 38 1;674 2004 8 2 10 7 40 0 0 0 14 26 5 3;674 2004 8 2 11 3 29 0 0 0 1 54 3 3;631 2004 8 2 11 57 56 0 0 0 0 30 8 2;1 2004 8 2 12 4 35 0 0 0 1 53 21 2;631 2004 8 2 12 52 58 0 0 0 0 20 36 2;631 2004 8 2 13 5 3 0 0 0 1 49 40 2;631 2004 8 2 14 0 20 0 0 0 1 56 12 2;631 2004 8 2 15 2 0 0 0 0 1 57 39 2;631 2004 8 2 16 1 4 0 0 0 1 55 53 2;1 2004 8 2 17 9 15 0 0 0 1 48 41 2];
Trajectories(1,4).uniqueDate= [2004 8 1;2004 8 2;2004 8 3;2004 8 4];
it runs but it's very very slow. How can I modify it to speed up?
Let's work from the inside out and see where it gets us.
Step 1: Simplify your comparison condition:
if (~isempty(s(1,k).places))&&(Trajectories(1,k).dateAll(j,1)==Trajectories(1,k).uniqueDate(i,1))&&(Trajectories(1,k).dateAll(j,2)==Trajectories(1,k).uniqueDate(i,2))&&(Trajectories(1,k).dateAll(j,3)==Trajectories(1,k).uniqueDate(i,3))
becomes
if (~isempty(s(1,k).places)) && all( Trajectories(1,k).dateAll(j,1:3)==Trajectories(1,k).uniqueDate(i,1:3) )
Then we want to remove this from a for-loop. The "intersect" function is useful here:
[ia i1 i2]=intersect(Trajectories(1,k).dateAll(:,1:3),Trajectories(1,k).uniqueDate(:,1:3),'rows');
We now have a vector i1 of all rows in dateAll that intersect with uniqueDate.
Now we can remove the loop comparing z using a similar approach:
[iz iz1 iz2] = intersect(Trajectories(1,k).dateAll(i1,4),1:24);
We have to be careful about our indices here, using a subset of a subset.
This simplifies the code to:
for k=1:nCols
if isempty(s(1,k).places)
continue; % skip to the next value of k, no need to do the rest of the comparison
end
[ia i1 i2]=intersect(Trajectories(1,k).dateAll(:,1:3),Trajectories(1,k).uniqueDate(:,1:3),'rows');
[iz iz1 iz2] = intersect(Trajectories(1,k).dateAll(i1,4),1:24);
usescalarlabel = (size(s(1,k).places.all,2)>=size(Trajectories(1,k).uniqueDate,1);
if (usescalarlabel)
Trajectories(1,k).label(i1(iz1)) = s(1,k).places.all(iz,i2(iz1));
else
% you will need to check this: I think here you were needlessly repeating this step for every match
Trajectories(1,k).label(i1(iz1)) = s(1,k).places.all(iz,:);
end
end
But wait! That z loop is exactly the same as using indexing. So we don't need that second intersect after all:
for k=1:nCols
if isempty(s(1,k).places)
continue; % skip to the next value of k, no need to do the rest of the comparison
end
[ia i1 i2]=intersect(Trajectories(1,k).dateAll(:,1:3),Trajectories(1,k).uniqueDate(:,1:3),'rows');
usescalarlabel = (size(s(1,k).places.all,2)>=size(Trajectories(1,k).uniqueDate,1);
label_indices = Trajectories(1,k).dateAll(i1,4);
if (usescalarlabel)
Trajectories(1,k).label(label_indices) = s(1,k).places.all(label_indices,i2);
else
% you will need to check this: I think here you were needlessly repeating this step for every match
Trajectories(1,k).label(label_indices) = s(1,k).places.all(label_indices,:);
end
end
You'll need to check the indexing in this - I'm sure I've made a mistake somewhere without having data to test against, but that should give you an idea on how to proceed removing the loops and using vector expressions instead. Without seeing the data that's as far as I can optimise. You may be able to go further if you can reformat your data into a set of 3d matrices / cells instead of using structs.
I am suspicious of your condition which I have called "usescalarlabel" - it seems like you are mixing two data types. Also I would strongly recommend separating the dateAll matrices into separate "date" and "data" matrices as the row indices 4 onwards don't seem to be dates. Also the example you copy/pasted in seems to have an extra value at row index 1? In that case you'll need to compare Trajectories(1,k).dateAll(:,2:4) instead of Trajectories(1,k).dateAll(:,1:3).
Good luck.

Convert binary values to a decimal matrix

Suppose that I have a matrix a= [1 3; 4 2], I convert this matrix to binary format using this code:
a=magic(2)
y=dec2bin(a,8)
e=str2num(y(:))';
The result is :
y =
00000001
00000100
00000011
00000010
e =
Columns 1 through 17
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 18 through 32
0 0 0 0 1 0 0 0 0 1 1 1 0 1 0
Now when I want to get back my original matrix I inverse the functions :
s=num2str(e(:))';
r=bin2dec(s)
The results I got is:
r =
1082
What can I do to get the orignal matrix? not a number
Thank you in advance
You are doing extra processes which destroyed the original structure:
a=magic(2)
y=dec2bin(a,8)
r=bin2dec(y)
Here r is your answer since y has removed the matrix structure of a. To recreate your matrix, you need to:
originalmatrix = reshape(r,size(a))
originalmatrix =
1 3
4 2
I finally got the right solution for my problem and I want to share it in case anyone need it :
a_back=reshape(bin2dec(num2str(reshape(e, 4, []))), 2, 2)
a =
1 3
4 2

GAMS, matrix direct assignment

I want to assign values to a 3-D table in GAMS. But it seems it doesn't work as in Matlab.....Any luck ? Code is as followed and the problem is at the last few lines:
Sets
n nodes / Sto , Lon , Par , Ber , War , Mad , Rom /
i scenarios / 1 * 4 /
k capacity level / L, N, H / ;
alias(n,m);
Table balance(n,i) traffic balance for different nodes
1 2 3 4
Sto 50 50 -50 -50
Lon -40 40 -40 40
Par 0 0 0 0
Ber 0 0 0 0
War 40 -40 40 -40
Mad 0 0 0 0
Rom -50 -50 50 50 ;
Scalar r fluctuation rate of the capacity level
/0.15/;
Parameter p(k) probability of each level
/ L 0.25
N 0.5
H 0.25 / ;
Table nor_cap(n,m) Normal capacity level from n to m
Sto Lon Par Ber War Mad Rom
Sto 0 11 14 25 30 0 0
Lon 11 0 21 0 0 14 0
Par 14 21 0 22 0 31 19
Ber 25 0 22 0 26 0 18
War 30 0 0 26 0 18 22
Mad 0 14 31 0 18 0 15
Rom 0 0 19 18 22 15 0 ;
Table max_cap(n,m,k) capacity level under each k
max_cap(n,m,'N')=nor_cap(n,m)
max_cap(n,m,'L')=nor_cap(n,m)*(1-r)
max_cap(n,m,'H')=nor_cap(n,m)*(1+r);
The final assignment to a 3-D matrix should be done with PARAMETER as opposed to TABLE. In general I would also note that TABLE is very restrictive (2 dimensional, text input inside the code). You might want to consider $GDXIN (or EXECUTE_LOAD) and some of the GAMS utilities for loading xls or csv files.
As a user of both MATLAB and GAMS I would note that GAMS depends on "indices" for every array, but otherwise they can be quite similar. In your case max_cap(n,m,k) would be something like the maximum capacity between from_city and to_city under each capacity level scenario. Your matrix needs to be declared as a PARAMETER which can be any n-dimensional (indexed) matrix, including even a SCALAR.
Also, try the GAMS mailing list if you really need an answer quickly, the number of proficient GAMS users globally can't be more than a few thousand, so it might be hard to find a quick answer on StackOverflow - awesome as it is for the more common languages.

Graph representation

Given graph, how could i represent it using adj matrix?. I have read lots of tutorials, post, slides, etc but i cant get my head round it, i just need that little push.
Here's my attempt for the first horizontal line of the maze:
A0 A1 A2 A3 A4 A5 A6 A7
A0 0 1 0 0 0 0 0 0
A1 1 0 0 0 0 0 0 0
A2 0 0 0 1 0 0 0 0
A3 0 0 1 0 0 0 0 0
A4 0 0 0 0 0 1 0 0
A5 0 0 0 0 1 0 0 0
A6 0 0 0 0 0 0 0 0
A7 0 0 0 0 0 0 0 0
So you can see from this that your going to end up with a symmetrical matrix due to the undirected nature of your edges and that its going to be sparsely populated.
EDIT: Matrix vs Lists
The wikipedia entry for adjacency list has some good points on the algorithmic benefits of each.
EDIT:
Wikipedia entry for Adjacency Matrix :+)
Every letter-number combination is one node in your graph, i.e., from A0, A1, A2, ... to F5, F6, F7. Your graph has 48 (8 columns times 6 rows in your maze) nodes, so you'll need a 48x48 matrix. If you treat it as boolean, you'll set all fields to false except the ones where there is a connection between two nodes, e.g. A0 to A1 would mean that the A0 row has a true value in the A1 column, and vice versa (because your graph is undirected).
Another way would be to have 2 boolean matrices named Hor and Ver to track the possibility of horizontal and vertical movement respectively.
Hor Matrix: Dimension:6x9
[X,YZ] represents the possiblity of a horizontal movement from [X,Y] to [X,Z] on the real board.
-1 represents the boundary
example: [A,01] is true and so is [F,-10]. But [B,23] is false.
-10 01 12 23 34 45 56 67 7-1
A
B
C
D
E
F
Similarly
Ver Matrix: Dimension: 7x8
[XY,Z] represents the possiblity of a vertical movement from [X,Z] to [Y,Z] on the real board.
Capital o in the row represent boundary.
example: [DE,0] is true and so is [BC,7]. But [CD,0] is false.
0 1 2 3 4 5 6 7
OA
AB
BC
CD
DE
EF
FO

How can I draw a triangle in an image in MATLAB?

I need to draw a triangle in an image I have loaded. The triangle should look like this:
1 0 0 0 0 0
1 1 0 0 0 0
1 1 1 0 0 0
1 1 1 1 0 0
1 1 1 1 1 0
1 1 1 1 1 1
But the main problem I have is that I do not know how I can create a matrix like that. I want to multiply this matrix with an image, and the image matrix consists of 3 parameters (W, H, RGB).
You can create a matrix like the one in your question by using the TRIL and ONES functions:
>> A = tril(ones(6))
A =
1 0 0 0 0 0
1 1 0 0 0 0
1 1 1 0 0 0
1 1 1 1 0 0
1 1 1 1 1 0
1 1 1 1 1 1
EDIT: Based on your comment below, it sounds like you have a 3-D RGB image matrix B and that you want to multiply each color plane of B by the matrix A. This will have the net result of setting the upper triangular part of the image (corresponding to all the zeroes in A) to black. Assuming B is a 6-by-6-by-3 matrix (i.e. the rows and columns of B match those of A), here is one solution that uses indexing (and the function REPMAT) instead of multiplication:
>> B = randi([0 255],[6 6 3],'uint8'); % A random uint8 matrix as an example
>> B(repmat(~A,[1 1 3])) = 0; % Set upper triangular part to 0
>> B(:,:,1) % Take a peek at the first plane
ans =
8 0 0 0 0 0
143 251 0 0 0 0
225 40 123 0 0 0
171 219 30 74 0 0
48 165 150 157 149 0
94 96 57 67 27 5
The call to REPMAT replicates a negated version of A 3 times so that it has the same dimensions as B. The result is used as a logical index into B, setting the non-zero indices to 0. By using indexing instead of multiplication, you can avoid having to worry about converting A and B to the same data type (which would be required to do the multiplication in this case since A is of type double and B is of type uint8).

Resources