I am using MATLAB version R2011a, a friend of mine is using R2014b which contains the function "Flip", which flips the order of elements, this function is vital to our program that compares Matrix'es.
My problem is R2011a does not have this function, it has fliplr,flipud and flipdim. I have tried using fliplr and then flipud to try and recreate the same function but eventually it doesn't work since i'm using the function corr which requires using that it's two arguments be the same dimensions.
I need advise on how to create the flip function that is available on R2014b.
The function that is problematic:
%This function gets the DNA signiture with the relative freq of each perm at
%the refernce text, the DNA signiture with the relative freq of each perm at
%the compare text, and the MaxPerm, and return the relative editor distance
%between the 2 texts.
function [distance]=EditorDistance2 (RefDNAWithFreq,CmpDNAWithFreq,MaxPerm)
if MaxPerm>2
MaxPerm=2;
end
str='Editor Distance compare begun';
disp(str);
distance=[];
for PermLength=1:MaxPerm
freq=sum(0:PermLength);
PermInitial=freq+1;
permEnd=freq+PermLength;
%create an ordered matrix of all the perms with length "PermLength"
%in the ref text
CurRefPerms=RefDNAWithFreq(:,freq:permEnd);
OrderedRefCurPerms=sortrows(CurRefPerms);
OrderedRefCurPerms=flip(OrderedRefCurPerms);
OrderedRefCurPerms(:,1)=[];
OrderedRefCurPerms=ZeroCutter(OrderedRefCurPerms);
%create an ordered matrix of all the perms with length "PermLength"
%in the cmp text
CurcmpPerms=CmpDNAWithFreq(:,freq:permEnd);
OrderedCmpCurPerms=sortrows(CurcmpPerms);
OrderedCmpCurPerms=flip(OrderedCmpCurPerms);
OrderedCmpCurPerms(:,1)=[];
OrderedCmpCurPerms=ZeroCutter(OrderedCmpCurPerms);
len1=size(OrderedRefCurPerms,1);
len2=size(OrderedCmpCurPerms,1);
edit=1;
matrix=zeros(len2,len1);
%initiate first row of the first stirng
for i=2:len1
matrix(1,i)=matrix(1,i-1)+1;
end
%initiate first column of the second stirng
for i=2:len2
matrix(i,1)=matrix(i-1,1)+1;
end
%start algoritem
for i=2:len2
for j=2:len1
if OrderedRefCurPerms(j-1,:)==OrderedCmpCurPerms(i-1,:)
edit=0;
end
if (i>2 & j>2 & OrderedRefCurPerms(j-1,:)==OrderedCmpCurPerms(i-2,:) & RefDNAWithFreq(j-2)==CmpDNAWithFreq(i-1) )
matrix(i,j)= min([matrix(i-1,j)+1,... deletion
matrix(i,j-1)+1,... insertion
matrix(i-2,j-2)+1,... substitution
matrix(i-1,j-1)+edit... transposition
]);
else
matrix(i,j) = min([matrix(i-1,j)+1,... deletion
matrix(i,j-1)+1,... insertion
matrix(i-1,j-1)+edit... substitution
]);
end
edit=1;
end
end
%The Distance is the last elment of the matrix.
if i~=1
tempdistance = matrix( floor( len2 / 3 ) , floor( len1 / 3 ) );
tempdistance=tempdistance/floor(len2/3);
else
tempdistance = matrix( len2,len1 );
tempdistance= tempdistance/len2;
end
tempdistance=1-tempdistance;
distance=[distance tempdistance];
end
end
I will further explain myself, the function which I am trying to use is A=flip(A)
The function that causes me problems is this one
%This function gets the DNA signiture with the relative freq of each perm at
%the refernce text, the DNA signiture with the relative freq of each perm at
%the compare text, and the MaxPerm, and return the corralation between the 2 texts.
function [Corvector]=CorrelationCompare(RefDNAWithFreq,CmpDNAWithFreq,MaxPerm)
str='corraltion compare begun';
disp(str);
%this vector will contain the corralation between the freqs of
%each perms vector(each length)
Corvector=[];
for PermLength=1:MaxPerm
freq=sum(0:PermLength);
PermInitial=freq+1;
permEnd=freq+PermLength;
%Cor is correlation between the 2 texts
refPerms=RefDNAWithFreq(:,freq);
cmpPerms=CmpDNAWithFreq(:,freq);
refPerms=ZeroCutter(refPerms);
cmpPerms=ZeroCutter(cmpPerms);
tempCor=corr(refPerms,cmpPerms);
Corvector =[Corvector tempCor];
% making a graph of the perms, and the relative freq of the texts.
x=ZeroCutter ( RefDNAWithFreq(:,PermInitial:permEnd) );
y1=refPerms;
y2=cmpPerms;
xchars=char(x);
Xcols=size(x,1);
o=ones(Xcols,1);
xco=mat2cell(xchars,o,PermLength);
xaxis=(1:Xcols);
figure
stem(xaxis,y1,'r');
hold
stem(xaxis,y2,'g');
set(gca,'XTick',xaxis)
set(gca,'XTickLabel',xco,'fontname','david');
xlabel('Perms');
ylabel('Perm frequency');
TitleOfGraph=sprintf('comapre between reference text to the compared, %d letters perm\n correlation=%f',PermLength,Corvector(PermLength));
legend('reference','compared');
title(TitleOfGraph);
end
end
The Error that I recieve when using a diffrent flip command is
??? Error using ==> corr at 102
X and Y must have the same number of rows.
Error in ==> CorrelationCompare at 27
tempCor=corr(refPerms,cmpPerms);
I apologize for the long codes but it's hard to explain it all since it's a big project and a lot of it was done by my partner
This should work for you -
function out = flip_hacked(A,dim)
%// Get an array of all possible dimensions
dims = 1:ndims(A);
%// Interchange first dimension and dim
dims(dim) = 1;
dims(1) = dim;
A1 = permute(A,[dims]);
%// Reshape A1 into a 2D matrix and then flip along the first dimension,
%// which would correspond to the flipping along dim and then interchange dim
%// and first dim again to keep the size of data same as input and elements
%// being flipped along dim for the desired output
A2 = reshape(A1,size(A1,1),[]);
out = permute(reshape(A2(end:-1:1,:),size(A1)),dims);
return;
It follows the same syntax as the official flip function that's stated in the official documentation as follows -
B = flip(A,dim) reverses the order of the elements in A along
dimension dim. For example, if A is a matrix, then flip(A,1) reverses
the elements in each column, and flip(A,2) reverses the elements in
each row.
In addition to the generic solution provided by Divakar you could simply use:
flip = #(A) A(end:-1:1, :);
A = flip(A);
To reverse the elements in each column of a matrix A. Even simpler:
A = A(end:-1:1, :);
Related
I have created this code to generate a 1 set of lottery numbers, but I am trying to make it so that the user can enter how many sets they want (input n), and it will print out as one long matrix of size nX6? I was messing around with a few options from online suggestions, but to no avail. I put the initial for i=1:1:n at the beginning, but I do not know how to store each run into a growing matrix. Right now it still generates just 1 set.
function lottery(n)
for i=1:1:n
xlow=1;
xhigh=69;
m=5;
i=1;
while (i<=m)
lottonum(i)=floor(xlow+rand*(xhigh-xlow+1));
flag=0;
for j=1:i-1
if (lottonum(i)==lottonum(j))
flag=1;
end
end
if flag==0
i=i+1;
end
end
ylow=1;
yhigh=26;
m=1;
lottonum1=floor(ylow+rand*(yhigh-ylow+1));
z = horzcat(lottonum, lottonum1);
end
disp('The lotto numbers picked are')
fprintf('%g ',z)
disp (' ')
The problem is that you are not storing or displaying the newly generated numbers, only the last set. To solve this, initialize z with NaNs or zeros, and later index z to store each set in a row of z, by using z(i,:) = lottonum.
However, you are using i as iterator in the while loop already, so you should use another variable, e.g. k.
You can also set z as an output of the function, so you can use this matrix in some other part of a program.
function z = lottery(n)
% init z
z = NaN(n,6);
for k = 1:n
xlow=1;
xhigh=69;
m=5;
i=1;
while (i<=m)
lottonum(i)=floor(xlow+rand*(xhigh-xlow+1));
flag=0;
for j=1:i-1
if (lottonum(i)==lottonum(j))
flag=1;
end
end
if flag==0
i=i+1;
end
end
ylow=1;
yhigh=26;
lottonum1 = floor(ylow+rand*(yhigh-ylow+1));
z(k,:) = horzcat(lottonum, lottonum1); % put the numbers in a row of z
end
disp('The lotto numbers picked are')
disp(z) % prettier display than fprintf in this case.
disp (' ')
end
The nice answer from rinkert corrected your basic mistakes (like trying to modify your loop iterator i from within the loop => does not work), and answered your question on how to store all your results.
This left you with a working code, however, I'd like to propose to you a different way to look at it.
The porposed architecture is to divide the tasks into separate functions:
One function draw_numbers which can draw N numbers randomly (and does only that)
One function draw_lottery which call the previous function as many times as it needs (your n), collect the results and display them.
draw_lottery
This architecture has the benefit to greatly simplify your main function. It can now be as simple as:
function Draws = draw_lottery(n)
% define your draw parameters
xmin = 1 ; % minimum number drawn
xmax = 69 ; % maximum number drawn
nballs = 5 ; % number of number to draw
% pre allocate results
Draws = zeros( n , nballs) ;
for iDraw=1:1:n
% draw "nballs" numbers
thisDraw = draw_numbers(xmin,xmax,nballs) ;
% add them to the result matrix
Draws(iDraw,:) = thisDraw ;
end
disp('The lotto numbers picked are:')
disp (Draws)
disp (' ')
end
draw_numbers
Instead of using a intricated set of if conditions and several iterators (i/m/k) to branch the program flow, I made the function recursive. It means the function may have to call itself a number of time until a condition is satisfied. In our case the condition is to have a set of nballs unique numbers.
The function:
(1) draws N integer numbers randomly, using randi.
(2) remove duplicate numbers (if any). Using unique.
(3) count how many unique numbers are left Nu
(4a) if Nu = N => exit function
(4b) if Nu < N => Call itself again, sending the existing Nu numbers and asking to draw an additional N-Nu numbers to add to the collection. Then back to step (2).
in code, it looks like that:
function draw = draw_numbers(xmin,xmax,nballs,drawn_set)
% check if we received a partial set
if nargin == 4
% if yes, adjust the number of balls to draw
n2draw = nballs - numel(drawn_set) ;
else
% if not, make a full draw
drawn_set = [] ;
n2draw = nballs ;
end
% draw "nballs" numbers between "xmin" and "xmax"
% and concatenate these new numbers with the partial set
d = [drawn_set , randi([xmin xmax],1,n2draw)] ;
% Remove duplicate
drawn_set = unique(d) ;
% check if we have some more balls to draw
if numel(drawn_set) < nballs
% draw some more balls
draw = draw_numbers(xmin,xmax,nballs,drawn_set) ;
else
% we're good to go, assign output and exit funtion
draw = drawn_set ;
end
end
You can have both functions into the same file if you want.
I encourage you to look at the documentation of a couple of Matlab built-in functions used:
randi
unique
I have this piece of code in Matlab which should take an Airfoil profile and increase the number of points so that when I plot the profile in another programme I will get a smoother curve.
clear
%reading an external data file
fid = fopen('NACA0015.txt');
a = fscanf(fid,'%g %g',[2 inf]); % It has two rows now.
a = a'; % matrix transpose
n = input('200') %e.g., n=35
for i=1:n
for j=1:2
fprintf('%12.7f',a(i,j)); %a(i,1) is first column, a(i,2) is 2nd col
end
fprintf('\n');
end
fclose(fid);
for i=1:n
x(i)=a(i,1); %x , y vectors
y(i)=a(i,2);
end
% use spline to create more points
xx=0:0.01:1 % e.g., step =0.01 (number of points = (1-0)/0.01=100)
yy = spline(x,y,xx); % xx and yy are new generated values of Naca0012
fprintf('\n print spline values \n');
plot(xx,yy,'ro')
hold on
plot(x,y,'*')
When I run this I get the error
Undefined function or variable 'x'.
Error in reading_external_data_and_spline (line 26)
yy = spline(x,y,xx); % xx and yy are new generated values of Naca0012
I am at a complete loss as to why this is not working when the x variable is clearly defined in the code, please could someone help me with this
It's how you're using input. The argument in input isn't the default value, it's the prompt text. If you type the command into the console and hit enter, you get this:
>> n = input('200')
200
n =
[]
>>
Input doesn't accept a default. If you really want to have an interactive prompt with a default answer, you want inputdlg:
answer = inputdlg('Enter a number of lines to parse', 'n', 1, '200');
n = str2double(answer);
note that inputdlg returns text always, so you need to convert to a number.
I am trying to write a function transform(A) which when given a matrix A returns a new matrix. The new matrix should be obtained according to following:
if A has more than one row then interchange the first and second row. After this square the elements in the first row.
So far thats what I have written:
function[Anew] = transform(A)
dimension = size(A);
if dimension(1) > 1 %if there is more than 1 row
A([1 2],:)=A([2 1],:);
end
A(1,:,:) = A(1,:,:).^2 %squares elements in the first row
end
I tested my function by invoking it in matlab.
I noticed that because i dont have a semi colon next to A(1,:,:) = A(1,:,:).^2
I still obtain the desired result but not as output of the function.
I obtain A =
instead of Anew =
If i put a semi colon next to A(1,:,:) = A(1,:,:).^2; then I dont get an output at all.
Could you tell me what is wrong and what should I change in my program to obtain output as Anew?
Thank you
To return a value from a function in Matlab, you must directly assign to it.
In your case, you need to assign to Anew at the end of the operation (you could also technically just use that variable all-together).
function [Output1, Output2] = SomeFunction( ... )
% Do Some Work
% Store Output
Output1 = Result1(:,2) %some output
Output2 = Result2(3:end, :) %some other result
end
function[Anew] = transform(A)
dimension = size(A);
Anew = A;
if dimension(1) > 1 %if there is more than 1 row
Anew ([1 2],:)=Anew([2 1],:);
end
Anew(1,:,:) = Anew(1,:,:).^2; %squares elements in the first row
end
I am searching for any matlab code that reads the skeleton text files from the dataset (MSR Daily Activity 3D). I can't figure how to understand how the files are written and what they represent ? Also, don't know how to parse them to extract the features.
this is the matlab code which read the depth sequences.
in each loop of 'for ei = 1:2',it read all the depth data to depth(a 3D matrix) from a bin file.
clear;close all;clc;
binPath = 'MSR Daily Activity 3D dataset\Depth';
for ai = 1:16
for si = 1:10
for ei = 1:2
%%%%%%%%%%%%%
%%%%%%%%%%%%%
[acsr,susr,exsr]=getsr(ai,si,ei);
%%%%%% getsr(ai,si,ei) convert ai,si,ei to double bits
%%%%%% for example, if ai=3, acsr is 03
%%%%%%%%%%%
binfile = [binPath,'\a',acsr,'_s',susr,'_e',exsr,'_depth.bin'];
if ~exist(binfile,'file');
disp('error');
continue;
end;
disp(binfile);
fileread = fopen(binfile);
if fileread<0
disp('no such file.');
return;
end
header = fread(fileread,3,'uint=>uint');
nnof = header(1); ncols = header(2); nrows = header(3);
depths = zeros(ncols, nrows, nnof);
for f = 1:nnof
frame = zeros( ncols, nrows);
for row = 1:nrows
tempRow = fread(fileread, ncols, 'uint=>uint');
tempRowID = fread(fileread, ncols, 'uint8');%%%%%
frame(:,row) = tempRow;
end
depth(:,:,f) = frame;
clear tempRow tempRowID;
end
fclose(fileread);
end
end
end
The site http://research.microsoft.com/en-us/um/people/zliu/ActionRecoRsrc/ tells you exactly how they're organised. They also provide some C++ example loaders.
"The format of the skeleton file is as follows. The first integer is the number of frames. The second integer is the number of joints which is always 20. For each frame, the first integer is the number of rows. This integer is 40 when there is exactly one skeleton being detected in this frame. It is zero when no skeleton is detected. It is 80 when two skeletons are detected (in that case which is rare, we simply use the first skeleton in our experiments). For most of the frames, the number of rows is 40. Each joint corresponds to two rows. The first row is its real world coordinates (x,y,z) and the second row is its screen coordinates plus depth (u, v, depth) where u and v are normalized to be within [0,1]. For each row, the integer at the end is supposed to be the confidence value, but it is not useful."
Hope this helps.
My code works in the following manner:
1.First, it obtains several images from the training set
2.After loading these images, we find the normalized faces,mean face and perform several calculation.
3.Next, we ask for the name of an image we want to recognize
4.We then project the input image into the eigenspace, and based on the difference from the eigenfaces we make a decision.
5.Depending on eigen weight vector for each input image we make clusters using kmeans command.
Source code i tried:
clear all
close all
clc
% number of images on your training set.
M=1200;
%Chosen std and mean.
%It can be any number that it is close to the std and mean of most of the images.
um=60;
ustd=32;
%read and show images(bmp);
S=[]; %img matrix
for i=1:M
str=strcat(int2str(i),'.jpg'); %concatenates two strings that form the name of the image
eval('img=imread(str);');
[irow icol d]=size(img); % get the number of rows (N1) and columns (N2)
temp=reshape(permute(img,[2,1,3]),[irow*icol,d]); %creates a (N1*N2)x1 matrix
S=[S temp]; %X is a N1*N2xM matrix after finishing the sequence
%this is our S
end
%Here we change the mean and std of all images. We normalize all images.
%This is done to reduce the error due to lighting conditions.
for i=1:size(S,2)
temp=double(S(:,i));
m=mean(temp);
st=std(temp);
S(:,i)=(temp-m)*ustd/st+um;
end
%show normalized images
for i=1:M
str=strcat(int2str(i),'.jpg');
img=reshape(S(:,i),icol,irow);
img=img';
end
%mean image;
m=mean(S,2); %obtains the mean of each row instead of each column
tmimg=uint8(m); %converts to unsigned 8-bit integer. Values range from 0 to 255
img=reshape(tmimg,icol,irow); %takes the N1*N2x1 vector and creates a N2xN1 matrix
img=img'; %creates a N1xN2 matrix by transposing the image.
% Change image for manipulation
dbx=[]; % A matrix
for i=1:M
temp=double(S(:,i));
dbx=[dbx temp];
end
%Covariance matrix C=A'A, L=AA'
A=dbx';
L=A*A';
% vv are the eigenvector for L
% dd are the eigenvalue for both L=dbx'*dbx and C=dbx*dbx';
[vv dd]=eig(L);
% Sort and eliminate those whose eigenvalue is zero
v=[];
d=[];
for i=1:size(vv,2)
if(dd(i,i)>1e-4)
v=[v vv(:,i)];
d=[d dd(i,i)];
end
end
%sort, will return an ascending sequence
[B index]=sort(d);
ind=zeros(size(index));
dtemp=zeros(size(index));
vtemp=zeros(size(v));
len=length(index);
for i=1:len
dtemp(i)=B(len+1-i);
ind(i)=len+1-index(i);
vtemp(:,ind(i))=v(:,i);
end
d=dtemp;
v=vtemp;
%Normalization of eigenvectors
for i=1:size(v,2) %access each column
kk=v(:,i);
temp=sqrt(sum(kk.^2));
v(:,i)=v(:,i)./temp;
end
%Eigenvectors of C matrix
u=[];
for i=1:size(v,2)
temp=sqrt(d(i));
u=[u (dbx*v(:,i))./temp];
end
%Normalization of eigenvectors
for i=1:size(u,2)
kk=u(:,i);
temp=sqrt(sum(kk.^2));
u(:,i)=u(:,i)./temp;
end
% show eigenfaces;
for i=1:size(u,2)
img=reshape(u(:,i),icol,irow);
img=img';
img=histeq(img,255);
end
% Find the weight of each face in the training set.
omega = [];
for h=1:size(dbx,2)
WW=[];
for i=1:size(u,2)
t = u(:,i)';
WeightOfImage = dot(t,dbx(:,h)');
WW = [WW; WeightOfImage];
end
omega = [omega WW];
end
% Acquire new image
% Note: the input image must have a bmp or jpg extension.
% It should have the same size as the ones in your training set.
% It should be placed on your desktop
ed_min=[];
srcFiles = dir('G:\newdatabase\*.jpg'); % the folder in which ur images exists
for b = 1 : length(srcFiles)
filename = strcat('G:\newdatabase\',srcFiles(b).name);
Imgdata = imread(filename);
InputImage=Imgdata;
InImage=reshape(permute((double(InputImage)),[2,1,3]),[irow*icol,1]);
temp=InImage;
me=mean(temp);
st=std(temp);
temp=(temp-me)*ustd/st+um;
NormImage = temp;
Difference = temp-m;
p = [];
aa=size(u,2);
for i = 1:aa
pare = dot(NormImage,u(:,i));
p = [p; pare];
end
InImWeight = [];
for i=1:size(u,2)
t = u(:,i)';
WeightOfInputImage = dot(t,Difference');
InImWeight = [InImWeight; WeightOfInputImage];
end
noe=numel(InImWeight);
% Find Euclidean distance
e=[];
for i=1:size(omega,2)
q = omega(:,i);
DiffWeight = InImWeight-q;
mag = norm(DiffWeight);
e = [e mag];
end
ed_min=[ed_min MinimumValue];
theta=6.0e+03;
%disp(e)
z(b,:)=InImWeight;
end
IDX = kmeans(z,5);
clustercount=accumarray(IDX, ones(size(IDX)));
disp(clustercount);
Running time for 100 images:Elapsed time is 103.947573 seconds.
QUESTIONS:
1.It is working fine for M=50(i.e Training set contains 50 images) but not for M=1200(i.e Training set contains 1200 images).It is not showing any error.There is no output.I waited for 10 min still there is no output.What is the problem?Where i was wrong?
To answer your second question, you can simply 'save' any generated variable as a .mat file in your working directory (Current folder) which can be accessed later. So in your code, if the 'training eigenfaces' is given by the variable 'u', you can use the following:
save('eigenface.mat','u')
This creates a .mat file with the name eigenface.mat which contains the variable 'u', the eigenfaces. Note that this variable is saved in your Current Folder.
In a later instance when you are trying out with your test data, you can simply 'load' this variable:
load('eigenface.mat')
This automatically loads 'u' into your workspace.
You can also save additional variables in the same .mat file if necessary
save('eigenface.mat','u','v'...)
The answer to the first question is that the code is simply not done running yet. Vectorizing the code (instead of using a for loop), as suggested in the comment section above can improve the speed significantly.
[EDIT]
Since the images are not very big, the code is not significantly slowed down by the first for loop. You can improve the performance of the rest of the code by vectorizing the code. Vectorized operations are faster than for-loops. This link might be useful in understanding vectorization:
http://www.mathworks.com/help/matlab/matlab_prog/vectorization.html
For example, the second for-loop can be replaced by the following vectorized form, as suggested in the comments
tempS = double(S);
meanS = mean(S,1);
stdS = std(S,0,1);
S = (tempS - meanS) ./ stdS;
Use MATLAB's timer functions tic and toc for finding how long the first for-loop alone is taking to execute. Add tic before the for loop and toc after it. If the time taken for 50 images is about 104 seconds, then it would be significantly more for 1200 images.