classification with four classes by matlab - matlab

I have a classification problem with four classes of input vector.The four classes are
A = [1 , 1; 1 ,2];
B = [2,2; -1,0];
C = [-1,-2;2,1];
D = [-1,-2; -1,-2];
I wan Implement this problem by Matlab, I Use this code :
C = [-1,-2;2,1];
A = [1 , 1; 1 ,2];
B = [2,2; -1,0];
D = [-1,-2; -1,-2];
hold on
grid on
plot(A(1,:),A(2,:),'bs')
plot(B(1,:),B(2,:),'r+')
plot(C(1,:),C(2,:),'go')
plot(D(1,:),D(2,:),'m*')
a = [0 1]';
b = [1 1]';
c = [1 0]';
d = [0 0]';
P = [A B C D];
T = [repmat(a,1,length(A)) repmat(b,1,length(B)) repmat(c,1,length(C)) repmat(d,1,length(D)) ];
net = perceptron;
E = 1;
net.adaptParam.passes = 1;
linehandle = plotpc(net.IW{1},net.b{1});
n = 0;
while (sse(E))
n = n+1;
[net,Y,E] = adapt(net,P,T);
linehandle = plotpc(net.IW{1},net.b{1},linehandle);
drawnow;
end
but My Code does'nt work I have No idea why, please Help me....

As has been suggested by thewaywewalk, the trouble is your while-loop and the fact that you do not provide an adequate check for the statement you wish to evaluate.
Replace your while-statement with these two lines:
ACCEPTABLE_ERROR = 3.0;
while (sse(E)>ACCEPTABLE_ERROR)
And you should see your script terminate after three iterations. You can play with the ACCEPTABLE_ERROR variable to check which solution works best for you. If you set it too small, your while loop will not exit, because the statement will not be false.
An explanation to your original while-statement:
All you ever evaluated if sse(e) returned a results - which it did in each case. That's why it never stopped.
To the question of sse requires more than one input argument:
That depends on what input arguments you provide.
The documentation says:
perf = sse(net,t,y,ew) takes these input arguments and optional function parameters,
net: Neural network
t: Matrix or cell array of target vectors
y: Matrix or cell array of output vectors
ew: Error weights (default = {1})
and returns the sum squared error.
However, it is not necessary, to provide the error weights, ew, as the source code reveals:
Only the first three arguments are required. The default error weight is {1}, which weights the importance of all targets equally.
In your case you should, based on the documentation, call sse like this:
sse(net,T,Y)
Without being mentioned in the documentation (or I haven't found it), this is equivalent to what you have done, by providing simply the network errors, E as provided from adapt:
sse(E)
Both give the same results.

Related

Why I am getting matrix dimension error in the line while calculating n?

Can you please tell me what's wrong with the following code?
function [n]=calculate_n(p,delta)
e = 1.6*power(10,-19);
k = 1.38*power(10,-23);
T = 298;
co = 3.25*power(10,13)*e*power(10,4);
er=12.5;
eo=1.0;
Nv=3*power(10,13);
us = log((p*e)/sqrt(2*k*T*er*eo*Nv))*2*k*T;
tmp = delta+(e*e*p)/co+us;
n = 1/(exp((tmp))+1);
end
I am getting matrix dimension error while calculating n. Please help me.
Caller:
e = 1.6*power(10,-19);
x = logspace(13,18);
y=calculate_n(x,0.2*e);
semilogx(x,y,'-s');
grid on;
Just replace n = 1/(exp((tmp))+1); with n = 1./(exp(tmp)+1);. But beware, tmp is so small for these values that exp(tmp) will always be 1. Also, there is a surplus bracket around tmp, you might want to check if you put them correctly.
Edit:
The reason is that A/B tries to solve the system of linear equations A*x = B for x which is not what you wanted. It threw an error because it requires both variables to have the same number of columns. A./B performs element-wise matrix division which is what you wanted. However, if A and B are singular A/B = A./B. See the documentation for more info.

Error using matlab parfor

I am trying to parallelize pagerank using matlab parfor command as shown below.
However, the line which is marked by ** ** and is also written below:
p_t1(L{j,i}) = p_t1(L{j,i}) +constant;
is causing this error:
"Undefined function 'p_t1' for input arguments of type 'int32'."
When I comment it out, the code works. When I replace the parfor with a normal for, it works again. What is the problem?
Thanks
S='--------------------------------------------------';
n = 6;
index=1;
a = [2 6 3 4 4 5 6 1 1];
b = [1 1 2 2 3 3 3 4 6];
a = int32(a);
b=int32(b);
a=transpose(a);
b=transpose(b);
vec_len=length(a);
%parpool(2);
for i=1:vec_len
G(1,i)=a(i);
G(2,i)=b(i);
con_size(i)=0;
end
%n=916428
for j = 1:vec_len
from_idx=a(j);
con_size(from_idx)=con_size(from_idx)+1;
L{from_idx,con_size(from_idx)}=b(j);
end
% Power method
max_error=100;
p = .85;
delta = (1-p)/n;
p_t1 = ones(n,1)/n;
p_t0 = zeros(n,1);
cnt = 0;
tic
while max_error > .0001
p_t0 = p_t1;
p_t1 = zeros(n,1);
parfor j = 1:n
constant=p_t0(j)/con_size(j);
constant1=p_t0(j)/n;
if con_size(j) == 0
p_t1 = p_t1 + constant1;
else
for i=1:con_size(j)
**p_t1(L{j,i}) = p_t1(L{j,i}) +constant;**
end
end
end
p_t1;
sum(p_t1);
p_t1 = p*p_t1 + delta;
cnt = cnt+1;
max_error= max(abs(p_t1-p_t0));
%disp(S);
end
toc
%delete(gcp)
Each variable inside parfor loop must be classified into one of several categories. Your p_t1 variable cannot be classified as any. It appears that you are trying to accumulate result in this variable across multiple iterations, which can be done using reduction variables. This is possible only if the result does not depend on the order of iterations (which appears to be the case in your example), but as you can see from the documentation, only certain types of expressions are allowed for reduction variables - mostly just simple assignments. In particular, you cannot index into a reduction variable - neither on the left-hand side, nor on the right-hand side of the assignment.
Matlab should be also producing plenty of warnings and M-Lint (statical code analyzer) warnings to highlight this issue.
You need to re-write your code so that Matlab could clearly classify each variable used inside parfor into one of the allowed categories.

MATLAB - accessing python lists and tuples

I have a python function, Foo, which returns a tuple of 3 lists. Each list contains points I would like to manipulate and plot in matlab. Current I can retrieve my data with
data = py.Foo.main(args)
Plotting the output proved difficult. Matlab sees "data" as a python object. I was previously in a rush and my quick work around was
function [r] = convertToVector(c)
%make sure everything is numeric so I can plot it
r = [];
for i = 1:length(c)
if isnumeric(c{i})
r = [r c{i}];
end
end
filler = data.cell()
a = convertToVector(filler{1}.cell())
b = convertToVector(filler{1}.cell())
c = convertToVector(filler{1}.cell())
This works okay but for c I have something like
filler.cell{3}.cell = [0] [-1] [-1] [-1] [0.22] [0.13] [0.08]
When I run convertToVector everything is either 0 or -1. I have no idea what is going on. If I play around in the console I can get something like
r = [];
z = filler.cell{3}.cell;
r = [r z{1}] >>> r = 0
r = [r z{2}] >>> r = 0 -1
r = [r z{5}] >>> r = 0 -1 0
Why is this happening? If I replace z{1} z{2} z{5} with 0 -1 0.22 respectively, I get the results I would expect: r = 0 -1 0.22. I don't use matlab regularly and I have no idea what may cause this. I was trying to plug the results of an analysis done in python into a pre-existing matlab gui, otherwise I would avoid interfacing the two as such.
Edit: Under further inspection utilizing whos r the class is int64 when adding z{1} to z{4} first and double when adding z{5} first. The class then changes from double to int64 if I add z{1} to z{4}
As per your edit, it seems the problem is that the initial integers in each cell (which are stored as ints or maybe numpy.uint64 types in python) are not automatically cast to double, and this seems reasonable. If you concatenate doubles to the uint64 array, the doubles will be cast to uint64 and not the other way around. This is only surprising since MATLAB very heavily defaults to using doubles whenever possible, so you might not expect this.
Simple python-free demonstration:
a = uint64([3, 4, 5]);
b = [a, 6];
c = [b, 7.3];
after this all three arrays will have uint64 class. Well, the example is a bit redundant, since class(6) is double, so if there was any typecasting, it would've already happened for b.
The solution is simple: explicitly cast to double in your function,
function [r] = convertToVector(c)
%make sure everything is numeric so I can plot it
r = [];
for i = 1:length(c)
if isnumeric(c{i})
r = [r double(c{i})]; %// only change here
end
end

Speeding up symbolic recursion in Matlab

I have a backwards recursion for a binomial tree. At each node an unknown C enters in such a way that at the starting node we get a formula, A(1,1), that depends upon C. The code is as follows:
A=sym(zeros(1,Steps));
B=zeros(1,Steps);
syms C; % The unknown that enters A at every node
tic
for t=Steps-1:-1:1
% Values needed in A and B
Lambda=1-exp(-(1./S(t,1:t).^b).*h);
Q=((1./D(t))./(1-Lambda)-d)/(u-d);
R=normcdf(a0+a1*Lambda);
% the backward recursion for A and B
A(1:t)=D(t)*C+D(t)*...
(Q.*(1-Lambda).*A(1:t) ...
+ (1-Q).*(1-Lambda).*A(2:t+1));
B(1:t)=Lambda.*(1-R)+D(t)*...
(Q.*(1-Lambda).*B(1:t)...
+ (1-Q.*(1-Lambda).*B(2:t+1)));
end
C = solve(A(1,1)==sym(B(1,1)),C);
This code takes around 4 seconds if Steps = 104. If however we remove C and set matrix A to a regular double matrix, it only takes about 0.02 seconds. Using syms thus increases the calculation time by a factor 200. This seems too much to me. Any suggestions into speeding this up?
I am using Matlab 2013b on a MacBook air 13-inch spring 2013. Furthermore, if you're interested in the code before the above part (not sure whether it is relevant):
a0 = 0.9;
a1 = -3.2557;
b = 1.2594;
S0=18.57;
sigma=0.6579;
h=1/104;
T=1;
Steps=T/h;
f=transpose(normrnd(0.04, 0.001 [1 pl]));
D=exp(-h*f); % discount values
pl=T/h; % pathlength - amount of steps in maturity
u=exp(sigma*sqrt(h));
d=1/u;
u_row = repmat(cumprod([1 u*ones(1,pl-1)]),pl,1);
d_row = cumprod(tril(d*ones(pl),-1)+triu(ones(pl)),1);
path = tril(u_row.*d_row);
S=S0*path;
Unless I'm missing something, there's no need to use symbolic math or use an unknown variable. You can effectively assume that C = 1 in your recursion relation and solve for the actual value at the end. Here's the full code with some other improvements:
rng(1); % Always seed your random number generator
a0 = 0.9;
a1 = -3.2557;
b = 1.2594;
S0 = 18.57;
sigma = 0.6579;
h = 1/104;
T = 1;
Steps = T/h;
pl = T/h;
f = 0.04+0.001*randn(pl,1);
D = exp(-h*f);
u = exp(sigma*sqrt(h));
d = 1/u;
u_row = repmat(cumprod([1 u*ones(1,pl-1)]),pl,1);
d_row = cumprod(tril(d*ones(pl),-1)+triu(ones(pl)),1);
pth = tril(u_row.*d_row);
S = S0*pth;
A = zeros(1,Steps);
B = zeros(1,Steps);
tic
for t = Steps-1:-1:1
Lambda = 1-exp(-h./S(t,1:t).^b);
Q = ((1./D(t))./(1-Lambda)-d)/(u-d);
R = 0.5*erfc((-a0-a1*Lambda)/sqrt(2)); % Faster than normcdf
% Backward recursion for A and B
A = D(t)+D(t)*(Q.*(1-Lambda).*A(1:end-1) + ...
(1-Q).*(1-Lambda).*A(2:end));
B = Lambda.*(1-R)+D(t)*(Q.*(1-Lambda).*B(1:end-1) + ...
(1-Q.*(1-Lambda).*B(2:end)));
end
C = B/A
toc
This take about 0.005 seconds to run on my MacBook Pro. There are certainly other improvements you could make. There are many combinations of variables that are used in multiple places (e.g., 1-Lambda or D(t)*(1-Lambda)), that could be calculated once. Matlab may try to optimize this a bit. And you can try moving Lambda, Q, and R out of the loop – or at least calculate parts of them outside and save the results in arrays.

Trouble iterating a function with one input and two outputs on Matlab

I've created a function (name it MyFunction) which, given a matrix A, outputs two matrices B and C i.e. [B C] = MyFunction(A).
I'm trying to create another function which, when given a matrix A, will calculate MyFunction(A) and then calculate MyFunction(B) = [D E] and MyFunction(C) = [F G], and then calculate MyFunction(D), MyFunction(E), MyFunction(F) and MyFunction(G), and so on, until the matrices it outputs start to repeat. I know this process necessarily terminates.
I'm really having difficulty constructing this code. Any advice would be really appreciated.
I think what you're trying to do is binary tree recursion. It's hard to give a good solution without knowing more about the problem, especially without knowing what you want as the output of this process.
I whipped this up to give an example of how you could do this. It's not necessarily the most efficient because it stores all of the results at every step. Given an input matrix A, it calculates a 2-output function [B, C] = MyFunction(A) and looks for either isequal(A, B) or isequal(A, C). When that occurs, it outputs the depth of the tree at that point, i.e. how many iterations had to occur before there was a repetition. The bit with global variables is just so that I could do a simple example with an easy fixed point (the k'th iteration is just A^k). It will iterate a maximum of 10 times.
function depth = myRecursor(A)
global A_orig;
A_orig = A;
depth = 1;
max_depth = 10;
pvs_level = cell(1);
pvs_level{1} = A;
while depth < max_depth,
this_level = cell(2*length(pvs_level), 1);
for ix = 1 : length(pvs_level),
[B, C] = MyFunction(pvs_level{ix})
if isequal(B, A) || isequal(C, A),
return;
end
this_level{2*ix - 1} = B;
this_level{2*ix} = C;
end
depth = depth + 1;
pvs_level = this_level;
end
function [B, C] = MyFunction(A)
global A_orig;
B = A_orig*A;
C = 2*A;
So, for example myRecursor(eye(2)) gives 1 (duh) and myRecursor([0 1; 1 0]) gives 2.
EDIT: rewritten wrong alg
function [list] = newFunction(A) % returns all matrix generated matrix
list{1}=A;
done=0;
ii = 1;
while(~done)
[B C] = myFunction(list{ii});
list = list{list{:}, B, C};
for jj=1:numel(list)-2
if(all(all(list{jj}==B)) || all(all(list{jj}==C)))
done = 1;
end
end
ii=ii+1;
end
end
UPDATE: a more general way to handle an unknown number of outputs is to modify myFunction so that it outputs all matrices within a single cell vector. This way you can concatenate list this way:
[newMat] = myFunctions(list{ii}); % where newMat={B,C,...}
list = {list{:}, newMat{:}}; % or list=cat(2,list,newMat)
for jj=1:numel(list)-numel(newMat)
for nn=1:numel(newMat) % checking for repetitions
if(all(all(list{jj}==newMat{nn})))
done=1;
end
end
end
I think you should use cells:
function [B]=Myfunction(A)
B=cell(1,numel(A)*2);
for n=1:numel(A)
B{n}=func1(A{n}) %%% put some processing here
B{numel(A)+n}=func2(A{n}) %%% put some other processing here
end
end