Neural Network Recognising in Scilab - neural-network

I try to run this example, which uses ANN Toolbox for Scilab
https://burubaxair.wordpress.com/2014/03/12/artificial-neural-networks-in-scilab/
This is code:
T = [
1 1 1 1 1
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
]';
U = [
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
0 1 1 1 0
]';
N = [35 10 2];
W = ann_FF_init(N);
x = [1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
0, 1, 1, 1, 0]';
t_t = [1 0]';
t_u = [0 1]';
t = [t_t, t_u];
lp = [0.01, 1e-4];
epochs = 3000;
W = ann_FF_Std_batch(x,t,N,W,lp,epochs);
y = ann_FF_run(x,N,W)
disp(y)
But i receive an error:
-->exec('D:\Учёба\Задачи\Recognition.sce', -1)
!--error 15
Подматрица задана некорректно (Submatrix is incorrect).
at line 37 of function ann_FF_grad_BP called by :
at line 25 of function ann_FF_Std_batch called by :
W = ann_FF_Std_batch(x,t,N,W,lp,epochs);
at line 33 of exec file called by :
exec('D:\Учёба\Задачи\Recognition.sce', -1)
An error may be in T and U matrix, but i don't understand why. Could you tell be what i do wrong? Thank you!

You've made 2 errors in your code:
You should not mix testing and training sets.
Testing input must be a single column.
Your first error was x = [ 1.... ] because it contained a single image, whereas you specified in N that you had two output neurons.
As stated in the example, you should have x = [T,U];
Your second error was to give x as a test to ann_FF_run. This function takes test input as a single column. But since you trained your NN with x just before it was a 5x7 matrix. Just change it to a column vector.
Here a corrected and commented code :
T = [...
1 1 1 1 1 ...
0 0 1 0 0 ...
0 0 1 0 0 ...
0 0 1 0 0 ...
0 0 1 0 0 ...
0 0 1 0 0 ...
0 0 1 0 0 ...
]';
U = [...
1 0 0 0 1 ...
1 0 0 0 1 ...
1 0 0 0 1 ...
1 0 0 0 1 ...
1 0 0 0 1 ...
1 0 0 0 1 ...
0 1 1 1 0 ...
]';
// setting the traing set of two image
xtrain = [T,U];
// so each image as 35 pixels so N(1) is 35
// and we have two images so N($) is 2
N = [35 10 2];
// training the NN
W = ann_FF_init(N);
// The expected response for T : 1 for T, 0 for U
t_t = [1 0]';
// The expected response for T : 1 for T, 0 for U
t_u = [0 1]';
// the overall response
t = [t_t, t_u];
// some parameters
lp = [0.01, 1e-4];
epochs = 3000;
// getting the weight of the trained NN
W = ann_FF_Std_batch(xtrain,t,N,W,lp,epochs);
// testing the traing set.
y = ann_FF_run(xtrain,N,W)
disp('Testing the traing set')
disp(y) //should get something close to t ~ [1 0 ; 0 1]
// testing a distord U
xtest1 = matrix([1, 0, 0, 0, 1;
1, 1, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
0, 1, 1, 1, 1]',-1,1);
y = ann_FF_run(xtest1,N,W)
disp('Testing a distored U')
disp(y) //should get something close to t_u ~ [0 1]
//testing something different from T and U. should get nothing
xtest2 = matrix([1, 0, 0, 0, 1;
1, 1, 0, 0, 1;
1, 0, 1, 0, 1;
1, 0, 1, 0, 1;
0, 0, 1, 1, 1;
0, 0, 1, 0, 1;
0, 1, 1, 1, 1]',-1,1);
y = ann_FF_run(xtest2,N,W)
disp('Testing something neither T nor U')
disp(y)
and the output from scilab's console
Testing the traing set
0.8538757 0.1075397
0.1393287 0.8957439
Testing a distored U
0.1078667
0.9007755
Testing something neither T nor U
0.3433933
0.6306797

Related

MATLAB graph to adjacency matrix?

I can create a graph using the matlab functions but I need to create an adjacency matrix from the graph now.
Here is how I created the graph:
s = roadmap.edges(:,1); % vector [1, 2, 3, 4, ...]
t = roadmap.edges(:,2); % vector [1, 2, 3, 4, ...]
weights = roadmap.edge_lengths'; % vector [1, 2, 3, 4, ...]
G = graph(s, t, weights);
I need to create a adjacency matrix from this data and I want it to look like this:
G = [0 3 9 0 0 0 0;
0 0 0 7 1 0 0;
0 2 0 7 0 0 0;
0 0 0 0 0 2 8;
0 0 4 5 0 9 0;
0 0 0 0 0 0 4;
0 0 0 0 0 0 0;
];

McEliece encryption/decryption algorithm

I'm trying to program the McEliece cryptosystem, but I'm having trouble combining the binary vectors and linsolve section in the decryption step of the algorithm.
I'm expecting the array m to be equal to the message array x after decryption, but I'm getting the wrong result:
x =
1 1 1 1
ciphertext =
1 1 1 1 0 1 1
m =
1.2500 0.5000 0.5000 0.7500
Why does my decrypted result differ from my plain-text message?
Here is what I have so far:
clc;clear all;
n = 7;
k = 4; %Let C be an (n,k)-linear code
g = [ 1 0 0 0 1 1 0
0 1 0 0 1 0 1
0 0 1 0 0 1 1
0 0 0 1 1 1 1]; %Let G be a generator matrix for C.
s = [ 1 1 0 1
1 0 0 1
0 1 1 1
1 1 0 0]; %Alice selects a random (k x k) binary non-singular matrix S
p = [ 0 1 0 0 0 0 0
0 0 0 1 0 0 0
0 0 0 0 0 0 1
1 0 0 0 0 0 0
0 0 1 0 0 0 0
0 0 0 0 0 1 0
0 0 0 0 1 0 0]; %Alice selects a random (n x n) permutation matrix P.
% s , g and p is private key ( alice has a private key )
% g'=s*g*p is public key (alice compute the public key and send to Bob )
gg = s*g*p; %Alice computes the (n x k)matrix g'=s*g*p .
key = mod(gg,2); % public key
x = [ 1 1 1 1 ] %message
t = 1;
e = [ 0 0 0 0 1 0 0 ]; % the erorr
%%the Encryption (( Bob Encrypt the message x by using the public key) )
y = x*key;
y1=mod(y,2);
ciphertext=mod((y+e),2) % ciphertext is Encrypt the message x ( send the ciphertext to Alice)
%%the Decryption ((alice decrypt the ciphertext , the result must equal to the orginal message x ( by using the private key) ))
yy = ciphertext*inv(p);
ee = e*inv(p);
xsg = mod((yy-ee),2);
xs = linsolve(g',xsg');
m = mod((xs' * inv(s)),2) % m must equal to x .
More details on the McEliece cryptosystem can be found here:
http://www-math.ucdenver.edu/~wcherowi/courses/m5410/ctcmcel.html
I tried to implement this example given in the above link:
For an example we shall use the (7,4) Hamming code which corrects all
single errors. A generator matrix for this code is given by (note the
clever choice):
G = [1 0 0 0 1 1 0
0 1 0 0 1 0 1
0 0 1 0 0 1 1
0 0 0 1 1 1 1];
and Bob chooses the scrambler matrix
S = [1 1 0 1
1 0 0 1
0 1 1 1
1 1 0 0];
and the permutation matrix
P = [0 1 0 0 0 0 0
0 0 0 1 0 0 0
0 0 0 0 0 0 1
1 0 0 0 0 0 0
0 0 1 0 0 0 0
0 0 0 0 0 1 0
0 0 0 0 1 0 0];
Bob makes public the generator matrix
G' = SGP = [1 1 1 1 0 0 0
1 1 0 0 1 0 0
1 0 0 1 1 0 1
0 1 0 1 1 1 0];
If Alice wishes to send the message x = (1 1 0 1) to Bob, she first
constructs a weight 1 error vector, say e = (0 0 0 0 1 0 0) and
computes
y = xG' + e
= (0 1 1 0 0 1 0) + (0 0 0 0 1 0 0)
= (0 1 1 0 1 1 0)
which she then sends to Bob.
Upon receiving y, Bob first computes y' = yP^-1, where
P^-1 = [0 0 0 1 0 0 0
1 0 0 0 0 0 0
0 0 0 0 1 0 0
0 1 0 0 0 0 0
0 0 0 0 0 0 1
0 0 0 0 0 1 0
0 0 1 0 0 0 0];
obtaining y' = (1 0 0 0 1 1 1). Now Bob decodes y' by the fast
decoding algorithm (Hamming decoding in this example). The syndrome of
y' is (1 1 1 0)T, so the error occurs in position 7 (details
omitted). Bob now has the code word y'' = (1 0 0 0 1 1 0). Because
of the clever choice for G, Bob knows that xS = (1 0 0 0), and he
can now obtain x by multiplying by the matrix
S-1 = [1 1 0 1
1 1 0 0
0 1 1 1
1 0 0 1];
obtaining
x = (1 0 0 0)S^-1 = (1 1 0 1).
Really I just followed your tutorial link, it seems like you struggled at the end and stopped doing what was in the tutorial? The algorithm is detailed well enough to follow, as below.
The main issue you were having is that you didn't need linsolve at all. The key changes I've made come in the last block of the code - the decryption. Two main things:
Using the forward slash operator is better than using inv(). From the documentation for the back slash operator (equivalent for pre-multiplication):
x = A\b is computed differently than x = inv(A)*b and is recommended for solving systems of linear equations
Using information about how the generator matrix was formed, the algorithm becomes much easier, as noted in your linked tutorial.
[By writing] G in standard form [Ik A], xS would just be the first k positions of xSG
Corrected code with comments:
clc; clear all;
% McEliece Encryption / Decryption, source material for example:
% http://www-math.ucdenver.edu/~wcherowi/courses/m5410/ctcmcel.html
n = 7;
%Let C be an (n,k)-linear code
k = 4;
%Let G be a generator matrix for C.
G = [1 0 0 0 1 1 0
0 1 0 0 1 0 1
0 0 1 0 0 1 1
0 0 0 1 1 1 1];
%Alice selects a random (k x k) binary non-singular matrix S
S = [1 1 0 1
1 0 0 1
0 1 1 1
1 1 0 0];
%Alice selects a random (n x n) permutation matrix P.
P = [0 1 0 0 0 0 0
0 0 0 1 0 0 0
0 0 0 0 0 0 1
1 0 0 0 0 0 0
0 0 1 0 0 0 0
0 0 0 0 0 1 0
0 0 0 0 1 0 0];
% S, G and P are the private key (Alice has a private key)
% GG = S*G*P is public key (Alice computes the public key and sends it to Bob)
GG = S*G*P;
publickey = mod(GG,2); % public key
% --- public key sent from Alice to Bob --- %
% Bob wants to send a message, msg, so encrypts it using Alice's public key
msg = [1 1 0 1] % message
e = [0 0 0 0 1 0 0]; % the weight vector - treated as an error by Alice
% Encryption
y = msg*publickey;
% ciphertext is the encrypted message (send the ciphertext to Alice)
ciphertext = mod((y+e),2)
% --- message sent from Bob to Alice --- %
% Decryption (Alice decrypts the ciphertext by using the private key,
% the result must be equal to the orginal message
% Using a forward slash can be quicker and more accurate than inv()
YY = ciphertext/P;
ee = e/P;
xSG = mod((YY-ee),2);
% Because G was of the form [I_k, A], xS is just the first k positions of
% xSG, and no multiplication is needed. This can be found in source material.
xS = xSG(1:k);
decoded = mod(xS/S,2)
Output:
msg =
1 1 0 1
ciphertext =
0 1 1 0 1 1 0
decoded =
1 1 0 1
Nice example. Added error removal. Tested in Octave
% Further references
% https://www.avoggu.com/posts/an-efficient-algorithm-for-hamming-(74)-decoding-matlab-implementation/
% https://www.tutorialspoint.com/hamming-code-for-single-error-correction-double-error-detection
% https://en.wikipedia.org/wiki/Hamming(7,4)
% http://michael.dipperstein.com/hamming/index.html
n=7;
%% Individual message size
k=4;
%% Generator Matrix
%d1 d2 d3 d4 p1 p2 p3
G = [ 1, 0, 0, 0, 1, 1, 0;... %d1
0, 1, 0, 0, 1, 0, 1;... %d2
0, 0, 1, 0, 0, 1, 1;... %d3
0, 0, 0, 1, 1, 1, 1;]; %d4
%% Parity check
%d1 d2 d3 d4 p1 p2 p3
H = [ 1, 1, 0, 1, 1, 0, 0; %p1
1, 0, 1, 1, 0, 1, 0; %p2
0, 1, 1, 1, 0, 0, 1;];%p3
%% A random invertible scrambler binary random matrix
S=zeros(k);
while ( abs(cond(S)) > 10 )
S = rand(k) > 0.5;
endwhile
%% A random permutation matrix
P = eye(n) (:,randperm(n));
%% Public key
Gprime = mod(S*G*P,2);
%% message
message = [1,1,0,1]
%% error vector
error = [1,0,0,0,0,0,0] (1,randperm(n));
%% encrypted message
encrypted_message = mod(message*Gprime + error,2)
% Decryption
% Undo permutation
encrypted_message = mod(encrypted_message/P,2);
% Remove error
find_error = mod(H*encrypted_message',2);
%% Use a lookup table bit to flip
error_position_table=[5,6,1,7,2,3,4];
error_indicator = (find_error(1))*1 + ...
(find_error(2))*2 + ...
(find_error(3))*4;
if error_indicator > 0
encrypted_message(error_position_table(error_indicator)) +=1;
endif
xSG = mod(encrypted_message,2);
% Due to ordering of columns in G message is in first k columns
xS = xSG(1:k);
decrypted_message = mod(round(xS/S),2)

Matlab identity shift matrix

Is there any inline command to generate shifted identity matrix in MATLAB?
A=[ ...
0, 1, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 1, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 1, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 1, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 1, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 1, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 1, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 1, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
combination of circshift and eye is good however it needs another command to fix it. Any simpler way? (with just one simple syntax)
Try using a diag call in combination with ones. For your case, you have a 10 x 10 identity matrix and want to shift the diagonal to the right by 1.
>> n = 10;
>> shift = 1;
>> A = diag(ones(n-abs(shift),1),shift)
A =
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0
The above code works by first declaring a column vector of all 1s, but we would need n-abs(shift) of them as moving to the right would mean that we would require less 1s to fill things up (more on this later). n-abs(shift) also corresponds to the total number of rows/columns of your matrix and subtracting out as many times you are shifting towards the right. Next, you can use diag where the first parameter is a column vector which creates a zero matrix and places the column vector as coefficients along the diagonal of this matrix. The second parameter (shift in your case) allows you to offset where to place this column. Specifying a positive value means to move the diagonals towards the right, and in our case we are moving this to the right by shift, and hence our output results. As you are essentially truncating the vector for each position towards the right you are moving, you would need to decrease the number of 1s in your vector by this much.
Up to now, I haven't explained why the abs call to shift is required in the last line of code. The reason why the abs call is required is to accommodate for negative shifts. If we didn't have the abs call in the third line of code, n-shift would essentially be adding more 1s to the vector and would thus expand our matrix beyond n x n. Because moving the diagonals to the left also decreases the amount of 1s seen in the result, that's why the abs call is required but you'll notice that the shift constant is left untouched in the second parameter of diag.
Here's a demonstration with a negative shift, shift = -1, and still maintaining the size to be 10 x 10:
A =
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
You can get the desired output with a single call to bsxfun -
n = 10
shift = 1
A = bsxfun(#eq,[1:n].',1-shift:n-shift)
Since you are basically creating a sparse matrix, alternatively you can use sparse -
n = 10
shift = 1
A = full(sparse(1:n-shift,1+shift:n,1,n,n))
way late in this game but let us not forget the simplest solution using linear indexing:
n=10; a=zeros(n);
a(n+1:n+1:end)=1
obviously, that just solves the shift=1 case, but you get the point...
You can use circshift and fix the matrix before passing it to the function:
>> shift = 1;
>> N=10;
>> A=circshift(diag(1:N>shift),-shift)
A =
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0
1:N>shift will be 0 for fist shift number of places and 1 for the remaining.
Here is Another Alternative: (little similar to bsxfun Approach by Divakar)
n=10;
shift = 1;
c = repmat(1-shift:n-shift,n,1,1);
r = repmat((1:n).',1,n,1);
out = r == c
This could also be a one-liner:
out = repmat((1:n).',1,n,1) == repmat(1-shift:n-shift,n,1,1)
Here is another one (also works with negative shifts)
rot90(blkdiag(zeros(abs(shift)),rot90(eye(n))),sign(shift))

how to keep just the upper element from a series same elements and remove the others

The following matrix:
A = [ -1 1 -1 1 -1 1 0 0 0 0 -1 1 0 0 -1 1 -1 1 0 0 ]
Would be like this:
A = [ -1 1 0 0 0 0 -1 1 0 0 -1 1 0 0 ]
Interesting little problem. I believe this works:
A = [-1 1 -1 1 -1 1 0 0 0 0 -1 1 0 0 -1 1 -1 1 0 0]; %# Set up an example vector
I1 = [1, 1, A(1:end-2) - A(3:end)]; %# Index all repetitions of sets of two using zeros
I1(A == 0) = 1; %# Ensure our index doesn't remove any of the 0's from the original vector
Soln = A(I1 ~= 0); %# Obtain solution using nonzero entries of the index

Some problems with accessing individual elements in MATLAB

syms t theta chy sy real;
A = [0 0 0 0; 0 -theta -0.5 0;0 -0.5 0 0;0 0 0 0];
B = [0 theta/2 0.5 0; theta/2 0 0 0;0.5 0 0 0;0 0 0 0];
C = [0 (1-(theta^2))/2 -(theta/2) 0;(1-(theta^2))/2 0 0 0; -(theta/2) 0 0 0;0 0 0 0];
D = sym(zeros(4,4));
CS = cat(3,A,B,C,D);
Now when I type
>> CS(:,1,3)
ans =
[ 0, 1/2 - theta^2/2, -theta/2, 0]
[ 1/2 - theta^2/2, 0, 0, 0]
[ -theta/2, 0, 0, 0]
[ 0, 0, 0, 0]
>> CS(:,:,3)
ans =
[ 0, 1/2 - theta^2/2, -theta/2, 0]
[ 1/2 - theta^2/2, 0, 0, 0]
[ -theta/2, 0, 0, 0]
[ 0, 0, 0, 0]
which is supposed to be different from CS(1,1,3) and CS(:,1,3).
>> CS(1,1,3)
ans =
[ 0, 1/2 - theta^2/2, -theta/2, 0]
[ 1/2 - theta^2/2, 0, 0, 0]
[ -theta/2, 0, 0, 0]
[ 0, 0, 0, 0]
All give the same values. How do I access the first value in that particular matrix. I don't want to use the A/B/C matrices.
It is working fine for me (R2011a):
syms t theta chy sy real;
A = [0 0 0 0; 0 -theta -0.5 0;0 -0.5 0 0;0 0 0 0];
B = [0 theta/2 0.5 0; theta/2 0 0 0;0.5 0 0 0;0 0 0 0];
C = [0 (1-(theta^2))/2 -(theta/2) 0;(1-(theta^2))/2 0 0 0; -(theta/2) 0 0 0;0 0 0 0];
D = sym(zeros(4,4));
CS = cat(3,A,B,C,D);
>> CS(:,1,3)
ans =
0
1/2 - theta^2/2
-theta/2
0
>> CS(:,:,3)
ans =
[ 0, 1/2 - theta^2/2, -theta/2, 0]
[ 1/2 - theta^2/2, 0, 0, 0]
[ -theta/2, 0, 0, 0]
[ 0, 0, 0, 0]
>> CS(1,1,3)
ans =
0
EDIT: As you see, R2011a gives the expected results. However, I've just checked it on R2010a (the OP's version) and also got your results... so you probably need an upgrade :)