Error in creating a volcano plot in MATLAB - matlab

I am a complete newbie to MATLAB and the first task I have is to create a volcano plot. I have been using the documentation to understand about it and get started.
I tried to run it on dummy values -
a=[1 2 3]
b=[4.6 2.7 4.5]
c=[0.05 0.33 0.45]
And then I ran -
SigStructure = mavolcanoplot(a, b, c)
My understanding is that a represents the gene expression values for condition 1, b for condition 2, and c is the list of p-values for the 3 data points in a and b.
However running this code gives me the error -
Index exceeds matrix dimensions.
Error in mavolcanoplot (line 127)
appdata.effect = X(paramStruct.goodVals) - Y(paramStruct.goodVals);
Error in volc (line 4)
SigStructure = mavolcanoplot(a, b, c)
Can anyone explain where I am going wrong?

You're encountering an issue because you are using row vectors.
Inside the mavolcanoplot function (you can see the file by typing edit mavolcanoplot in the command window) there is a local function for checking the inputs, called check_inputdata.
Your data passes all of the validation checks, and then encounters this section:
% Here, 'X' and 'Y' are the local names for your inputs 'a' and 'b'
% Below code is directly from mavolcanoplot.m:
% Handle the matrix input. Use its mean values per row
if size(X, 2) > 1
X = mean(X,2);
end
if size(Y, 2) > 1
Y = mean(Y,2);
end
This reduces your inputs to their mean. Later in the main function (line 127) you encounter the error as described, where paramStruct.goodVals is a 3 element array, which is now trying to index a 1 element array and fails!
This is basically a lesson in debugging and reading the documentation, which states
DataX, DataY: If a [...] matrix, each row is a gene, each column is a sample and an average expression value is calculated for each gene.
You should use one of these equivalent methods to create column vector inputs
a=[1 2 3].'; % Using transpose (.') to create a column vector from a row vector
b=[4.6; 2.7; 4.5]; % Creating a column vector using the semi-colon operator to end each row
c=[0.05
0.33
0.45]; % Using actual code layout to create a column vector

Related

Simplify how to find unique rows of a Matlab array

I would like your help to vectorise (or, more generally, make more efficient) a Matlab code where:
Step 1: I construct a matrix C of size sgxR, where each row contains a sequence of ones and zeros, according to whether certain logical conditions are satisfied.
Step 2: I identify the indices of the unique rows of C.
I now describe the code in more details.
Step 1: Creation of the matrix C. I divide this step in 3 sub-steps.
Step 1.a: Create the 1x3 cell U_grid. For j=1,2,3, U_grid{j} is a sg x K matrix of numbers.
clear
rng default
n_U_sets=3; %This parameter will not be changed
sg=4; %sg is usually quite large, for instance 10^6
K=5; %This parameter can range between 3 and 8
Ugrid=cell(n_U_sets,1);
for j=1:n_U_sets
Ugrid{j}=randn(sg,K);
end
Step 1.b: For each g=1,...,sg
Take the 3 rows Ugrid{1}(g,:), Ugrid{2}(g,:), Ugrid{3}(g,:).
Take all possible 1x3 rows that can be formed such that the first element is from Ugrid{1}(g,:), the second element is from
Ugrid{2}(g,:), and the third element is from Ugrid{3}(g,:). There are K^3 such rows.
Create the matrix D{g} storing row-wise all possible pairs of such 1x3 rows. D{g} will have size (K^3*(K^3-1)/2)x6
This is coded as:
%Row indices of all possible pairs of rows
[y, x] = find(tril(logical(ones(K^(n_U_sets))), -1));
indices_pairs = [x, y]; %K^3*(K^3-1)/2
%Create D{g}
for g=1:sg
vectors = cellfun(#(x) {x(g,:)}, Ugrid); %1x3
T_temp = cell(1,n_U_sets);
[T_temp{:}] = ndgrid(vectors{:});
T_temp = cat(n_U_sets+1, T_temp{:});
T = reshape(T_temp,[],n_U_sets);
D{g}=[T(indices_pairs(:,1),:) T(indices_pairs(:,2),:)]; %(K^3*(K^3-1)/2) x (6)
end
Step 1.c: From D create C. Let R=(K^3*(K^3-1)/2). R is the size of any D{g}. C is a sg x R matrix constructed as follows: for g=1,...,sg and for r=1,...,R
if D{g}(r,1)>=D{g}(r,5)+D{g}(r,6) or D{g}(r,4)<=D{g}(r,2)+D{g}(r,3)
then C(g,r)=1
otherwise C(g,r)=0
This is coded as:
R=(K^(n_U_sets)*(K^(n_U_sets)-1)/2);
C=zeros(sg,R);
for g=1:sg
for r=1:R
if D{g}(r,1)>=D{g}(r,5)+D{g}(r,6) || D{g}(r,4)<=D{g}(r,2)+D{g}(r,3)
C(g,r)=1;
end
end
end
Step 2: Assign the same index to any two rows of C that are equal.
[~,~,idx] = unique(C,"rows");
Question: Steps 1.b and 1.c are the critical ones. With sg large and K between 3 and 8, they take a lot of time, due to the loop and reshape. Do you see any way to simplify them, for instance by vectorising?

Trying to develop closed form solutions of second order DE

Basically, I have this function in matlab:
function yy = homo2nd(tt,polycc,y0,v0)
rr = roots(polycc);
cc = [1 1; rr(1) rr(2)\[y0; v0]];
yy = cc(1)*exp(rr(1)*tt) + cc(2) * exp(rr(2)*tt);
yy = round(yy,8);
end
I understand that roots takes the roots of an array signifying the coefficients of the left side of the equation. I feed roots and argument like [1 1 1] and it spits out the eigenvalues of that function.
From there I am lost.
I define tt in the command shell like this:
tt = linspace(0,2*pi,100).
I call homo2nd and feed it arguments (tt,[1 1 1], 1, 1)
When I try to feed roots the argument [1 1 1] like I said I get this error:
Error using horzcat
Dimensions of arrays being concatenated are not consistent.
I just need help interpreting the code. Why are the arrays horizontally mismatched?
The error is occuring on this line
cc = [1 1; rr(1) rr(2)\[y0; v0]];
So let's look at this, the 1 1 is fine, it's saying there's a row vector [1,1].
The next part is where the error occurs, the ; moves us to a second row. The first element of that row is rr(1), this is fine.
However, the second element rr(2)\[y0; v0] is using the mldivide command and the result of this isn't a single element, hence the error.

Large image matrix: save to small matrices

I'm new to MATLAB and its development. I have a image which is 1134 (rows) X 1134 (columns). I want that image to save 3 (columns) X 3 (rows). In order to do that I need 378 cells. For that I used following code, but it gives me an error.
image=imread('C:\Users\ven\Desktop\test\depth.png');
I=reshape(image,1,1134*1134);
chunk_size = [3 3]; % your desired size of the chunks image is broken into
sc = sz ./ chunk_size; % number of chunks in each dimension; must be integer
% split to chunk_size(1) by chunk_size(2) chunks
X = mat2cell(I, chunk_size(1) * ones(sc(1),1), chunk_size(2) *ones(sc(2),1));
Error:
Error using mat2cell (line 97)
Input arguments, D1 through D2, must sum to each dimension of the input matrix size, [1 1285956].'
Unfortunately your code does not work as you think it would.
The ./ operator performs point wise division of two matrices. Short example:
[12, 8] ./ [4, 2] == [12/4, 8/2] == [3, 4]
In order for it to work both matrices must have exactly the same size. In your case you try to perform such an operation on a 1134x1134 matrix (the image) and a 1x2 matrix (chunk_size).
In other words you can not use it to divide matrices into smaller ones.
However, a solution to your problem is to use the mat2cell function to pick out subsets of the matrix. A explanation of how it is done can be found here (including examples): http://se.mathworks.com/matlabcentral/answers/89757-how-to-divide-256x256-matrix-into-sixteen-16x16-blocks.
Hope it helps :)
Behind the C=A./B command is loop over all elements of A(ii,jj,...) and B(ii,jj,..) and each C(ii,jj,..)=A(ii,jj,...)/B(ii,jj,...).
Therefore martices A and B must be of same dimension.
If you want to split matrix into groups you can use
sc=cell(1134/3,1);
kk=0;ll=0;
for ii=2:3:1133
kk=kk+1;
for jj=2:3:1133
ll=ll+1;
sc{kk,ll}=image(ii-1:ii+1,jj-1:jj+1);
end
end
The code allocates cell array sc for resulting submatrices and arbitrary counters kk and ll. Then it loops over ii and jj with step of 3 representing centers of each submatrices.
Edit
Or you can use mat2cell command (type help mat2cell or doc mat2cell in matlab shell)
sc=mat2cell(image,3,3);
In both cases the result is cell array and its iith and jjth elements (matrices) are accessible by sc{ii,jj}. If you want call iith anr jjth number in kkth and llth matrix, do it via sc{kk,ll}(ii,jj).
In short, you divided a 1134 x 1134 by 2 x 1 matrix. That doesn't work.
The error "Matrix dimensions must agree**" is from the dividing a matrix with another matrix that doesn't have the right dimensions.
You used the scalar divide "./" which divided a matrix by another matrix.
You want something like:
n = 1134 / 3 % you should measure the length of the image
I1=image(1:n,1:n); % first row
I2=image(1:n,n:2n);
I3=image(1:n,2n:3n);
I4=image(n:2n,1:n); % second row
I5=image(n:2n,n:2n);
I6=image(n:2n,2n:3n);
I7=image(2n:3n,1:n); % third row
I8=image(2n:3n,n:2n);
I9=image(2n:3n,2n:3n);
from here:
http://au.mathworks.com/matlabcentral/answers/46699-how-to-segment-divide-an-image-into-4-equal-halves
There would be a nice loop you could do it in, but sometimes thinking is hard.

Matlab Function with Varying parameters

I need help figuring out how to code the following problem. Any help would be greatly appreciated!
Create a function that will take a vector/array input for x (1 by n) and a scalar input for a, and produce the output defined by the following equation:
y(x,a)=((xsin(ax-2))/(sqrt(1+(ax)^2)
-π ≤ x ≤ π
a={.5 1 1.5 2}
The equation must be vectorized in terms of x and the output from the function is the array y which has the same dimension as the array x.
Write a script that calls this function to compute y(x,a) for the range of x defined above and each value of the parameter a. Results should be stored in a solution matrix using a different row of the solution matrix for each value of a.
So far for my function I have:
function [y] = part1(a,x)
y=((x*sin(a*x-2))/(sqrt(1+(a*x).^2)));
end
I'm not sure how to output this into the solution matrix
For my script I have:
%%
clear,clc
a={0.5 1 1.5 2};
x=-pi:0.1:pi;
for
part1(x,a)
end
I'm getting the following errors when I run this now:
Undefined function 'mtimes' for input arguments of type 'cell'.
Error in part1 (line 4)
y=((x*sin(a*x-2))/(sqrt(1+(a*x).^2)));
Error in labtest2 (line 8)
y(i,:)=part1(x,a(i));
EDIT
I've made some changes and am still getting some errors that I cannot resolve.
Here is my full code for function followed by full code for script:
Function
function [y] = part1(x,a)
nx=numel(x);
na=numel(a);
y=((x.*sin(a.*x-2))./(sqrt(1+(a.*x).^2)));
size(y)=[nx na]
end
Script
%%
clear,clc
a={0.5 1 1.5 2};
x=-pi:0.1:pi;
for i = 1:length(a)
y(i,:)=part1(x,a(i));
end
Errors
Undefined function 'times' for input arguments of type 'cell'.
Error in part1 (line 6)
y=((x.*sin(a.*x-2))./(sqrt(1+(a.*x).^2)));
Error in labtest2 (line 8)
y(i,:)=part1(x,a(i));
The reason you're getting Undefined function 'times' for input arguments of type 'cell' is because your variable a is a cell array. You need to change your assignment of a from
a={0.5 1 1.5 2};
to
a=[0.5 1 1.5 2];
which will make it just a normal array. Alternatively, you need to reference it with cell array notation: a{i} instead of a(i).
You're almost there. Note that you've written
function [y] = part1(a,x)
but you call it in your script as
part1(x,a)
so you should probably correct that.
A few things jump out at me:
You never assign the output of part1(x,a) to anything. You're told that
Results should be stored in a solution matrix using a different row of the solution matrix for each value of a.
What I take this to mean is that the 1st row corresponds to part1() evaluated for the 1st element of a. Since we're operating on x which is a vector, that row will have multiple columns. Your output is indeed a matrix. In your case, length(-pi:0.1:pi) == 63, therefore size(y) == [4 63], where y is your output matrix.
Your for loop is backwards. You're told to accept scalar a and vector x. Therefore, your script should be something like:
a = 0.5:0.5:2;
x = -pi:0.1:pi;
for i = 1:length(a)
y(i,:) = part1(x, a(i));
end
Note the use of length and the : operator. I want to iterate between 1 to length(a) (in this case, length(a) == 4) so that I can use the current a(i) value as an index into my output matrix, y. The : operator in y(i,:) signifies "The ith row and all columns of y will take the value output by part1(x,a(i))."
Your function needs to be changed up for element-by-element operations. Notice that, for instance, x*sin(a*x-2) works for scalar x but not vectors. This is because x is a vector and sin(a*x-2) is also a vector (since the sin call will operate element-by-element and a is a scalar). Trying to multiply two vectors together will result in errors since MATLAB will try to perform a matrix multiplication. Resolve this by replacing * with .*. This way it is unambiguous that you are going to multiply these two vectors element-by-element. You'll also need to change / to ./.
On another note, thank you for attempting to do your homework before asking SO for help. We've been getting a huge influx of questions from students that have made no attempt to do their own work before dumping it on us, so it's refreshing that we regulars of the MATLAB tag get to actual help out instead of telling people to do their own work.
Finally got the whole thing worked out.
Function
function [y] = part1(x,a)
y=((x.*sin(a.*x - 2))./(sqrt(1 + (a.*x).^2)));
end
Script
%%
clear all;
clc;
close all;
x=[-pi:.1:pi];
a=[.5:.5:2];
for i=1:length(a)
y(i,:)=part1(x,a(i));
plot(x,y)
end
Sol=[y]

Alternative to `ismember` and `intersect` in Matlab to perform the task of comparison?

I have 100 models (matrices), where each matrix's size is 4X3. Each of the four variables R_L, N_g, N_Pc, and uT are of size 4x3x100, where 4X3 is size of each matrix and there are 100 of such matrix. I have attached a snapshot of two variables to give an idea of what I mean:
I am looping through matrix 1 of first three variables (i.e. R_L, N_g, N_Pc) and comparing each element in matrix 1 of these variables with elements in other 99 matrices. I want to find those elements where all three variables in those 99 matrices are equal to corresponding three variables in any element of matrix 1.
For example, if all three variables in element (1,1) of matrix 1 have correspondingly similar values in element (2,2) of matrix 2, (2,1) of matrix 3, (2,4) of matrix 3 etc. then I will pick the results from variable 4 (i.e. uT) at all those above element positions i.e. (1,1) of matrix 1, (2,2) of matrix 2, (2,1) of matrix 3, (2,4) of matrix 3 etc from uT and store those results in a new variable called store_result to plot its histogram. It is shown in code below.
nModel=100;
ixk=1;
% looping inside model # 1
for k_model1=size(R_L,1):-1:1
for i_model1=1:size(R_L,2)
% comparing values in model 1 to values in model 2 to nModel
for model_no=2:nModel
% looping inside each model from model # 2 to nModel
for k=size(R_L,1):-1:1
for i=1:size(R_L,2)
if ismember(R_L(k_model1,i_model1,1), R_L(k,i,model_no)) &&...
ismember(N_g(k_model1,i_model1,1), N_g(k,i,model_no)) &&...
ismember(N_Pc(k_model1,i_model1,1), N_Pc(k,i,model_no))
index_for_identical_results(:,:,model_no)=intersect(ismember(R_L(k_model1,i_model1,1), R_L(k,i,model_no)),...
ismember(N_g(k_model1,i_model1,1), N_g(k,i,model_no)),...
ismember(N_Pc(k_model1,i_model1,1), N_Pc(k,i,model_no)));
end
end
end
end
store_result(:,ixk)=uT(index_for_identical_results(:,:,model_no));
ixk=ixk+1;
end
end
I have following concerns that I would like to be addressed:
ismember would be useful only when the values match exactly. In case there are no exact similar values, what would you suggest if I would like to give certain interval within which the values fall then it should be considered equal.
Since I want to find a grid (element) where all three variables are equal, therefore the function intersect would not work here (even though I have used in the code above). What would you suggest to use instead of intersect which can perform the similar function with multiple variables.
Thanks.
I was able to solve the problem as following:
error=0.1;
ixk=1;
% looping inside model # 1
for k_model1=size(R_L,1):-1:1
for i_model1=1:size(R_L,2)
count=1;
% comparing values in model 1 to values in model 2 to nModel
for model_no=2:nModel
% looping inside each model from model # 2 to nModel
for k=size(R_L,1):-1:1
for i=1:size(R_L,2)
if abs((R_L(k_model1,i_model1,1)-R_L(k,i,model_no))/R_L(k_model1,i_model1,1))<=error...
&& abs((N_g(k_model1,i_model1,1)-N_g(k,i,model_no))/N_g(k_model1,i_model1,1))<=error &&...
abs((N_Pc(k_model1,i_model1,1)-N_Pc(k,i,model_no))/N_Pc(k_model1,i_model1,1))<=error
% index_for_identical_results(:,:,model_no)=
if count==1 && ixk==1
store_result(1:2,ixk)=vertcat(uT_mpersec_end_of_window(k_model1,i_model1,1),uT_mpersec_end_of_window(k,i,model_no));
count=count+2;
elseif count==1 && ixk~=1
store_result(1:2,ixk)=vertcat(uT_mpersec_end_of_window(k_model1,i_model1,1),uT_mpersec_end_of_window(k,i,model_no));
count=count+2;
else
store_result(count,ixk)=uT_mpersec_end_of_window(k,i,model_no);
count=count+1;
end
end
end
end
end
ixk=ixk+1;
end
end