Method does not update the current object MATLAB - matlab

I'm writing a code using Matlab OO programming. I came across a problem trying to write a method that changes the value of a matrix inside the same object.
I've tested my method and it does exactly what I want it to do but it does not save back the results.
Here is my code:
Take a look on : function obj = initCC(obj)
%% searchDat picks values for the object properties in a fite
%% Importa a função searchDat()
%%
classdef methExpl
%Classe de Metodos Explicitos
% Detailed explanation goes here
properties
%Declara Altura da Placa, Largura, Nós em X, Nós em Y, K, Matriz
%com a solução do passo atual, matriz com a solução do passo
%Variáveis Geométricas
%Altura e Largura
Height
Length
%Variáveis da Malha
%Número de nós em X e Número de nós em Y
%Passo de tempo
NodeX
NodeY
timeStep
%Propriedades Físicas
%Condutividade Térmica, Temperatura no Contorno
%Temperatura Inicial uniforme na chapa
kTerm
boundaryTemp
initTemp
%Soluções parciais
%Matriz com a solução da iteração atual
%Matriz com a solução da iteração passada
curMat
lastMat
end
properties (SetAccess = private)
%Arma
funTermMAT
erro = {}
end
methods
function obj = methExpl()
%Construtor da Classe
%Inicializa as variaveis com os valores no arquivo input.dat
%Inicializa a matriz
obj.Height = searchDat('[Height]','input.dat');
obj.Length = searchDat('[Length]','input.dat');
obj.NodeX = searchDat('[NodesX]','input.dat');
obj.NodeY = searchDat('[NodesY]','input.dat');
obj.kTerm = searchDat('[ThermalConductivity]','input.dat');
obj.boundaryTemp = searchDat('[BoundaryTemperature]','input.dat');
obj.initTemp = searchDat('[InitalTemperature]','input.dat');
obj.curMat = zeros(obj.NodeX,obj.NodeY);
%inicializa a matriz com a temperatura do contorno:
obj.initCC();
obj.lastMat = zeros(obj.NodeX,obj.NodeY);
end
function obj = initCC(obj)
%initCC Inicializa a matriz com a condição de contorno de
%temperatura
lim = size(obj.curMat);
for (i =1 : lim(1))
for (j = 1 : lim(2))
if (i==1) || (i == lim(1))
obj.curMat(i,j) = obj.boundaryTemp;
elseif (j==1) || (j ==lim(2))
obj.curMat(i,j) = obj.boundaryTemp
end
end
end
obj.curMat
end
end
end
Before quitting the initCC and get:
ans =
3 3 3 3 3 3 3 3 3 3 3
3 0 0 0 0 0 0 0 0 0 3
3 0 0 0 0 0 0 0 0 0 3
3 0 0 0 0 0 0 0 0 0 3
3 0 0 0 0 0 0 0 0 0 3
3 0 0 0 0 0 0 0 0 0 3
3 0 0 0 0 0 0 0 0 0 3
3 0 0 0 0 0 0 0 0 0 3
3 0 0 0 0 0 0 0 0 0 3
3 0 0 0 0 0 0 0 0 0 3
3 3 3 3 3 3 3 3 3 3 3
Which is exactly what I want.
If I call it from the outside after initializing it I get:
ans =
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
As if the result of the method I have created has been destroyed.

Just to put expand on the suggestions in the comments, you basically have two options. Firstly, you could simply capture the return of your initCC method which does correctly return the modified object, like so:
myObj = initCC(myObj);
Note that because of MATLAB's "copy on write" behaviour, this does not in fact incur any expensive copies of data.
The other option is to declare your class to be a handle, like so:
classdef methExpl < handle
...
end
then you don't need the return from initCC.

Related

MATLAB - Get rid of leading zeros in each row of matrix, 1 at a time?

I want to get rid of leading zeros in each row of a matrix, but limit it to eliminating one zero at a time.
This is my current solution, but is there a simpler way of doing it?
a = [ 0 0 0 0 0 0 0 0 0 0
0 0 5 2 3 4 0 0 0 0
0 0 0 1 2 3 4 0 0 0
0 0 1 2 3 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 ]
b=zeros(size(a));
for j=1:size(a,2)
for i=1:size(a,1)
temp=find(a(i,:),1,'first');
candelete=min(2,temp);
b(i,1:end-candelete+1)=a(i,candelete:end);
end
a=b
end
EDIT:
I'm want to print every iteration, so that the first output will only have the first leading zero removed:
0 0 0 0 0 0 0 0 0 0
0 5 2 3 4 0 0 0 0 0
0 0 1 2 3 4 0 0 0 0
0 1 2 3 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
the second will have 2 zeros removed, and so on...
EDIT: Now that the question was clarified, here's a better answer using circshift:
index = (a(:, 1) == 0) & any(a, 2);
while any(index)
a(index, :) = circshift(a(index, :), -1, 2);
disp(a);
index = (a(:, 1) == 0) & index;
end

Neural network with matlab

I'm trying to make a neural network that can make a facial recognition. I have a database of 15 pictures each person. And 5 pictures each person that needs to be recognized without being in the database.
The first part is the function generate_input
function[NNinput]=generate_input(image,imagesize)
imag_in=imread(image); %inlezen van de afbeelding
imgray=rgb2gray(imag_in); %Omzetting van rgb naar grijswaardenafbeelding
imag_double=double(imgray); %casting naar een double
inverse_gray=abs(imag_double -255); %inverteren van de grijswaarden
imag_int=uint8(inverse_gray); %double naar int
imag_resize=imresize(imag_int,[imagesize imagesize]);
[row,col]=size(imag_resize);
NNinput=zeros(1,(row*col));
NNindex=1;
for rowcounter=1:row
for colcounter=1:col
NNinput(1,NNindex)=imag_resize(rowcounter,colcounter);
NNindex=NNindex+1;
end
end
NNinput=log10(abs(fft(NNinput)));
The second part is the where the network is created
clear all;
persons=10; %aantal personen
trainingset=15; %grootte van de trainingset per persoon
imsize=50; %grootte van de nieuwe (te analyseren) afbeeldingen
NNinput=zeros(imsize^2,1);
targets=zeros(10,1);
inputrange=zeros(imsize^2,2);
targetrange=zeros(persons,2);
%generating NNinputs (NNinputs is the input database of all the pictures
%Generating targets
for personcounter=1:trainingset
S1_im =cat(2,'S1_' ,num2str(personcounter),'.jpg');
S2_im =cat(2,'S2_' ,num2str(personcounter),'.jpg');
S3_im =cat(2,'S3_' ,num2str(personcounter),'.jpg');
S4_im =cat(2,'S4_' ,num2str(personcounter),'.jpg');
S5_im =cat(2,'S5_' ,num2str(personcounter),'.jpg');
S6_im =cat(2,'S6_' ,num2str(personcounter),'.jpg');
S7_im =cat(2,'S7_' ,num2str(personcounter),'.jpg');
S8_im =cat(2,'S8_' ,num2str(personcounter),'.jpg');
S9_im =cat(2,'S9_' ,num2str(personcounter),'.jpg');
S10_im=cat(2,'S10_',num2str(personcounter),'.jpg');
S1_mat =generate_input(S1_im ,imsize);
S2_mat =generate_input(S2_im ,imsize);
S3_mat =generate_input(S3_im ,imsize);
S4_mat =generate_input(S4_im ,imsize);
S5_mat =generate_input(S5_im ,imsize);
S6_mat =generate_input(S6_im ,imsize);
S7_mat =generate_input(S7_im ,imsize);
S8_mat =generate_input(S8_im ,imsize);
S9_mat =generate_input(S9_im ,imsize);
S10_mat=generate_input(S10_im,imsize);
if (personcounter == 1)
NNinput(:,personcounter+0)=S1_mat';
targets(:,personcounter+0)=[1 0 0 0 0 0 0 0 0 0]';
NNinput(:,personcounter+1)=S2_mat';
targets(:,personcounter+1)=[0 1 0 0 0 0 0 0 0 0]';
NNinput(:,personcounter+2)=S3_mat';
targets(:,personcounter+2)=[0 0 1 0 0 0 0 0 0 0]';
NNinput(:,personcounter+3)=S4_mat';
targets(:,personcounter+3)=[0 0 0 1 0 0 0 0 0 0]';
NNinput(:,personcounter+4)=S5_mat';
targets(:,personcounter+4)=[0 0 0 0 1 0 0 0 0 0]';
NNinput(:,personcounter+5)=S6_mat';
targets(:,personcounter+5)=[0 0 0 0 0 1 0 0 0 0]';
NNinput(:,personcounter+6)=S7_mat';
targets(:,personcounter+6)=[0 0 0 0 0 0 1 0 0 0]';
NNinput(:,personcounter+7)=S8_mat';
targets(:,personcounter+7)=[0 0 0 0 0 0 0 1 0 0]';
NNinput(:,personcounter+8)=S9_mat';
targets(:,personcounter+8)=[0 0 0 0 0 0 0 0 1 0]';
NNinput(:,personcounter+9)=S10_mat';
targets(:,personcounter+9)=[0 0 0 0 0 0 0 0 0 1]';
else
NNinput=cat(2,NNinput,S1_mat');
targets=cat(2,targets,[1 0 0 0 0 0 0 0 0 0]');
NNinput=cat(2,NNinput,S2_mat');
targets=cat(2,targets,[0 1 0 0 0 0 0 0 0 0]');
NNinput=cat(2,NNinput,S3_mat');
targets=cat(2,targets,[0 0 1 0 0 0 0 0 0 0]');
NNinput=cat(2,NNinput,S4_mat');
targets=cat(2,targets,[0 0 0 1 0 0 0 0 0 0]');
NNinput=cat(2,NNinput,S5_mat');
targets=cat(2,targets,[0 0 0 0 1 0 0 0 0 0]');
NNinput=cat(2,NNinput,S6_mat');
targets=cat(2,targets,[0 0 0 0 0 1 0 0 0 0]');
NNinput=cat(2,NNinput,S7_mat');
targets=cat(2,targets,[0 0 0 0 0 0 1 0 0 0]');
NNinput=cat(2,NNinput,S8_mat');
targets=cat(2,targets,[0 0 0 0 0 0 0 1 0 0]');
NNinput=cat(2,NNinput,S9_mat');
targets=cat(2,targets,[0 0 0 0 0 0 0 0 1 0]');
NNinput=cat(2,NNinput,S10_mat');
targets=cat(2,targets,[0 0 0 0 0 0 0 0 0 1]');
end
end
%Generating inputrange
for inputrangecounter=1:imsize^2
inputrange(inputrangecounter,:)=[0 255];
end
%Generating targetrange
for targetrangecounter=1:persons
targetrange(targetrangecounter,:)=[0 1];
end
%Creating the neural network
net = feedforwardnet(100,'trainscg');
net = configure(net,inputrange,targetrange);
net.trainParam.epochs = 10000;
net.trainParam.max_fail =400;
net=trainscg(net,NNinput,targets,'useGPU','only');
and the last part of the file is testing the network by inserting a picture in the network
test_im=cat(2,'S5_2.jpg'); %Name of the picture
test_mat=generate_input(test_im,imsize); %Create inputvector from picture
Output=net(test_mat); %put inputvector in the network
plot(Output) %plot the output
It doesn't matter which input I give, the output stays the same.

Interpolation inside a matrix. Matlab

I have a matrix looks like:
0 0 0 0 0
1 0 0 0 0
0 2 0 0 0
0 0 2 0 0
0 0 0 1 0
1 0 0 0 1
0 4 0 0 0
0 0 3 0 0
6 0 0 4 0
0 3 0 0 2
0 0 5 0 0
It is 11x5 matrix.
I want to interpolate between the values vertically for each column.
Any help ?
Thanks.
M =[0 0 0 0 0
1 0 0 0 0
0 2 0 0 0
0 0 2 0 0
0 0 0 1 0
1 0 0 0 1
0 4 0 0 0
0 0 3 0 0
6 0 0 4 0
0 3 0 0 2
0 0 5 0 0];
xi = 1:size(M,1)
for colIdx = 1:size(M,2)
col = M(:,colIdx);
x = xi(~~col); %// Note that ~~col is a logical vector of elements that are not equal to zero. i.e. it's the same as col ~= 0
y = col(~~col);
M(:,colIdx) = interp1(x,y,xi);
end
then if you want the outer points to be 0 add this line after the loop:
M(isnan(M)) = 0;

Find all possible paths in a graph using Matlab Brute Force Search

I need to find all paths with a graph, and save these paths. My starting nodes are A, B or C, and the final node is G. My graphs have maximum 16 unweighted vertices.
I made the Matlab code below, but this has problems with bifurcations. Also, I don't know how to impose the starting and the final nodes. Can anyone help me with this?
path = cell(1,10) ; % initialize
% one_graph ={'AH','BO','CN','EG','EN','EO','HO','KN'} % (Graph example)
one_graph ={'AH','BN','DH','DN','GN'} % (Graph example)
for p = 1:length(one_graph)
edge = one_graph(p);
% In each graph there is only 1:1 conections
% detect node 1
existing_node1 = edge{1}(1) ;
Index_existing_node1 = strfind(allnodes, existing_node1) ;
[row1,col1] = find(ismember(allnodes, existing_node1));
% detect node 2
existing_node2 = edge{1}(2) ;
Index_existing_node2 = strfind(allnodes, existing_node2);
[row2,col2] = find(ismember(allnodes, existing_node2));
path_nonz = path(~cellfun('isempty',path)) ;
t = length(path_nonz) ;
if t>0 % save the first 2 nodes in the path
ttt = strcmp(allnodes(row1), path{t});
ttt2 = strcmp(allnodes(row2), path{t});
end;
if t==0
path{t+1} = allnodes{row1} ;
path{t+2} = allnodes{row2} ;
elseif ttt == 1
% disp('connect right')
path{t+1} = allnodes{row2} ;
elseif ttt2 == 1
% disp('connect right')
path{t+1} = allnodes{row1} ;
else
disp('Not next vertex')
end
end
For example, for
one_graph ={'AH','BN','DH','DN','GN'} % (Graph example)
I should save the following paths:
path1 = AHDNG
path2 = BNG
and for
one_graph ={'AH','BO','CN','EG','EN','EO','HO','KN'} % (Graph example)
I should save the following paths:
path1 = AHOEG
path2 = BOEG
path3 = CNEG
UPDATE 1:
From the adjacency matrix B(:,:,1)
B =
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
I derive the proper adjacency list:
Asparse = sparse(B(:,:,1));
Asparse =
(8,1) 1
(14,2) 1
(8,4) 1
(14,4) 1
(14,7) 1
(1,8) 1
(4,8) 1
(2,14) 1
(4,14) 1
(7,14) 1
Then, I tried to use the BFS algorithm found on Matlab Website
[distances,times,pred] = bfs(Asparse,1);
But, this doesn't save the paths. It just saves the previous node of each current node (in pred) and the distance from the initial node to each node (in distances). Any idea, how to save each path?
I've had to write a custom function to do this since 1) most BFS/DFS functions stop when the goal is reached and 2) they explicitly ignore cycles, which are required for multiple paths to the same target.
I believe this will get you what you need. I've made a slight modification to the adjacency matrix in your example to create an edge from {2,7} and {7,2} so that there would be two paths from 2 to 14. Note that this is a recursive function, so if you get around 500 nodes or so you're going to have problems and we'll have to come up with a version that uses an explicit stack.
function paths = findpaths(Adj, nodes, currentPath, start, target)
paths = {};
nodes(start) = 0;
currentPath = [currentPath start];
childAdj = Adj(start,:) & nodes;
childList = find(childAdj);
childCount = numel(childList);
if childCount == 0 || start == target
if start == target
paths = [paths; currentPath];
end
return;
end
for idx = 1:childCount
currentNode = childList(idx);
newNodes = nodes;
newNodes(currentNode) = 0;
newPaths = findpaths(Adj, newNodes, currentPath, currentNode, target);
paths = [paths; newPaths];
end
end
If you call this function like this:
A =[
0 0 0 0 0 0 0 1 0 0 0 0 0 0;
0 0 0 0 0 0 1 0 0 0 0 0 0 1;
0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 1 0 0 0 0 0 1;
0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 1 0 0 0 0 0 0 0 0 0 0 0 1;
1 0 0 1 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 1 0 1 0 0 1 0 0 0 0 0 0 0];
unusedNodes=ones(1,size(A,1));
start=2;
target=14;
emptyPath=[];
allPaths = findpaths(A, unusedNodes, emptyPath, start, target)
the output should be:
allPaths =
{
[1,1] =
2 7 14
[2,1] =
2 14
}
Naturally, you need to call this for each starting node.
Actually, you don't have to call this multiple times. There was one more tip I forgot to tell you. If your graph has n nodes and you introduce a new node n+1 that has edges only to your candidate start nodes, you can call the function once with the new node as the start.
So if I add node 15 to the graph above with edges:
{15,1}, {15,2}
%// I wouldn't bother with {1,15} and {2,15}, they're totally unnecessary
and call the function with start = 15, here's what I get:
allPaths =
{
[1,1] =
15 1 8 4 14
[2,1] =
15 2 7 14
[3,1] =
15 2 14
}
You now have all of the paths with one call, although you need to remove the new node 15 from the head of each path.

matlab's imfill function seems bugged?

I need to work with imfill in Matlab (Version 2010b, 7.11.0). I now think there is a bug in the program.
The most simple example that i found here is following: (Fills the Image background (0) beginning at the position [4 3])
BW = [ 0 0 0 0 0 0 0 0;
0 1 1 1 1 1 0 0;
0 1 0 0 0 1 0 0;
0 1 0 0 0 1 0 0;
0 1 0 0 0 1 0 0;
0 1 1 1 1 0 0 0;
0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0];
imfill(BW,[4 3])
According to the specifications this should work IMHO, but I always get following message. Can anyone tell me what I am doing wrong?
??? Error using ==> iptcheckconn at 56
Function IMFILL expected its second input argument, CONN,
to be a valid connectivity specifier.
A nonscalar connectivity specifier must be 3-by-3-by- ...
-by-3.
Error in ==> imfill>parse_inputs at 259
iptcheckconn(conn, mfilename, 'CONN', conn_position);
Error in ==> imfill at 124
[I,locations,conn,do_fillholes] = parse_inputs(varargin{:});
Error in ==> test at 9
imfill(BW,[4 3])
That does not explain the problem but converting BW to a logical array does work. I'm not sure as to why it's like this though:
clear
close all
clc
BW = [ 0 0 0 0 0 0 0 0
0 1 1 1 1 1 0 0
0 1 0 0 0 1 0 0
0 1 0 0 0 1 0 0
0 1 0 0 0 1 0 0
0 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
BW2 = imfill(logical(BW),[4 3])
BW2 =
0 0 0 0 0 0 0 0
0 1 1 1 1 1 0 0
0 1 1 1 1 1 0 0
0 1 1 1 1 1 0 0
0 1 1 1 1 1 0 0
0 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
As you have already seen in the other solution by #Benoit_11, that most probably that input wasn't of logical class, which was throwing an error at you. So, you are set there!
Now, I would like to put forth a tiny bit of bonus suggestion here.
Let's suppose you have a set of seed points with their row and column IDs and you would like to fill an image with those seed points in one go. For that case,
you need to use those IDs as column vectors. Thus, if you have the row and column IDs as -
row_id = [4 3];
col_id = [3 7];
You can fill image with this -
BW = imfill(BW,[row_id(:) col_id(:)])
But, the following code would throw error at you -
BW = imfill(BW,[row_id col_id])