Extract and display result from table MATLAB - matlab

I am trying to extract the lowest value for V from the table produced for each force (F) in order to establish the optimum result, e.g. for F=5000, V=0.06575 is the optimum result.
I want to be able to display this for each instance of F. I'm not quite sure where I am going wrong.
%===========================================
%This Script calculates
%===========================================
%Parameter Values
%F:force (N)
%L1: Length of beam 1 (m)
%L2: Length of beam 2 (m)
%H: Height of beam 1 (m)
%h: Height of beam 2 (m)
%b: Cross section width (m)
%S: Yield strength (Pa)
%N: Factor of safety
%V:Volume of the beam (m^2)
%=========================================
clc %clear command window
clear all %clear all variables previously generated and stored in Matlab
format short g
L1=2;
L2=3;
b=0.05;
S=248;
K=1.42;
results=[];
optimalresults=[];
nd=3.6; %desired factor of safety calculated by group number
for F=5000:100:6000
for h=0.2:0.005:0.3 %loop of h
for H=0.2:0.005:0.3 % loop of H
M1=F*(L1+L2);
M2=F*L2;
I1=b*H^3/12;
I2=b*h^3/12;
Y1=H/2;
Y2=h/2;
Max_stress_1=M1*Y1/I1;
Max_stress_2=K*(M2*Y2/I2);
Max_total_stress=max(Max_stress_1,Max_stress_2);
Max_total_stress=Max_total_stress/1e6;
N=0.577*S/Max_total_stress;
%if N is greater than desired factor of safety then display results
if N >= nd
V=(b*L1*H)+(b*L2*h);
results=[results; F,V,N];sort(F);
end
end
end
results_sorted=sortrows(results,1); %sorts factor of safety from min to max
disp(' F V N');
disp(results_sorted);
optimum=results_sorted(1,:)
end
What do I have to change to display the minimal value of V for each F?

My guess is that you probably want this bit outside of the 3 for loops:
results_sorted=sortrows(results,1); %sorts factor of safety from min to max
disp(' F V N');
disp(results_sorted);
optimum=results_sorted(1,:)
Also, I am not sure what you achieve with sort(F); inside the loop.

I think your code needs two changes before you can get the minimal value of V for each F:
Where you use sortrows, you should sort the table using the second column (V), so that the lowest V gets placed in the top row. results_sorted=sortrows(results,2);
You should sort only the results for the current F, so either you clear the variable "results" for each F iteration results=[]; or you use a new variable. Be sure to check if "results" is not empty before sorting the rows.
The variable "optimum" has now the lowest V for each F iteration.

Related

Minimize difference between indicator variables in Matlab

I'm new to Matlab and want to write a program that chooses the value of a parameter (P) to minimize the difference between two vectors, where each vector is a variable in a dataframe. The first vector (call it A) is a predetermined vector of 1s and 0s, and the second vector (call it B) has each of its entries determined as an indicator function that depends on the value of the parameter P and other variables in the dataframe. For instance, let C be a third variable in the dataset, so
A = [1, 0, 0, 1, 0]
B = [x, y, z, u, v]
where x = 1 if (C[1]+10)^0.5 - P > (C[1])^0.5 and otherwise x = 0, and similarly, y = 1 if (C[2]+10)^0.5 - P > (C[2])^0.5 and otherwise y = 0, and so on.
I'm not really sure where to start with the code, except that it might be useful to use the fminsearch command. Any suggestions?
Edit: I changed the above by raising to a power, which is closer to the actual example that I have. I'm also providing a complete example in response to a comment:
Let A be as above, and let C = [10, 1, 100, 1000, 1]. Then my goal with the Matlab code would be to choose a value of P to minimize the differences between the coordinates of the vectors A and B, where B[1] = 1 if (10+10)^0.5 - P > (10)^0.5 and otherwise B[1] = 0, and similarly B[2] = 1 if (1+10)^0.5 - P > (1)^0.5 and otherwise B[2] = 0, etc. So I want to choose P to maximize the likelihood that A[1] = B[1], A[2] = B[2], etc.
I have the following setup in Matlab, where ds is the name of my dataset:
ds.B = zeros(size(ds,1),1); % empty vector to fill
for i = 1:size(ds,1)
if ((ds.C(i) + 10)^(0.5) - P > (ds.C(i))^(0.5))
ds.B(i) = 1;
else
ds.B(i) = 0;
end
end
Now I want to choose the value of P to minimize the difference between A and B. How can I do this?
EDIT: I'm also wondering how to do this when the inequality is something like (C[i]+10)^0.5 - P*D[i] > (C[i])^0.5, where D is another variable in my dataset. Now P is a scalar being multiplied rather than just added. This seems more complicated since I can't solve for P exactly. How can I solve the problem in this case?
EDIT 1: It seems fminbnd() isn't optimal, likely due to the stairstep nature of the indicator function. I've updated to test the midpoints of all the regions between indicator function flips, plus endpoints.
EDIT 2: Updated to include dataset D as a coefficient of P.
If you can package your distance calculation up in a single function based on P, you can then search for its minimum.
arraySize = 1000;
ds.A = double(rand([arraySize,1]) > 0.5);
ds.C = rand(size(ds.A));
ds.D = rand(size(ds.A));
B = #(P)double((ds.C+10).^0.5 - P.*ds.D > ds.C.^0.5);
costFcn = #(P)sqrt(sum((ds.A-B(P)).^2));
% Solving the equation (C+10)^0.5 - P*D = C^0.5 for P, and sorting the results
BCrossingPoints = sort(((ds.C+10).^0.5-ds.C.^0.5)./ds.D);
% Taking the average of each crossing point with its neighbors
BMidpoints = (BCrossingPoints(1:end-1)+BCrossingPoints(2:end))/2;
% Appending endpoints onto the midpoints
PsToTest = [BCrossingPoints(1)-0.1; BMidpoints; BCrossingPoints(end)+0.1];
% Calculate the distance from A to B at each P to test
costResult = arrayfun(costFcn,PsToTest);
% Find the minimum cost
[~,lowestCostIndex] = min(costResult);
% Find the optimum P
optimumP = PsToTest(lowestCostIndex);
ds.B = B(optimumP);
semilogx(PsToTest,costResult)
xlabel('P')
ylabel('Distance from A to B')
1.- x is assumed positive real only, because with x<0 then complex values show up.
Since no comment is made in the question it seems reasonable to assume x real and x>0 only.
As requested, P 'the parameter' a scalar, P only has 2 significant states >0 or <0, let's see how is this:
2.- The following lines generate kind-of random A and C.
Then a sweep of p is carried out and distances d1 and d2 are calculated.
d1 is euclidean distance and d2 is the absolute of the difference between A and and B converting both from binary to decimal:
N=10
% A=[1 0 0 1 0]
A=randi([0 1],1,N);
% C=[10 1 1e2 1e3 1]
C=randi([0 1e3],1,N)
p=[-1e4:1:1e4]; % parameter to optimize
B=zeros(1,numel(A));
d1=zeros(1,numel(p)); % euclidean distance
d2=zeros(1,numel(p)); % difference distance
for k1=1:1:numel(p)
B=(C+10).^.5-p(k1)>C.^.5;
d1(k1)=(sum((B-A).^2))^.5;
d2(k1)=abs(sum(A.*2.^[numel(A)-1:-1:0])-sum(B.*2.^[numel(A)-1:-1:0]));
end
figure;
plot(p,d1)
grid on
xlabel('p');title('d1')
figure
plot(p,d2)
grid on
xlabel('p');title('d2')
The only degree of freedom to optimise seems to be the sign of P regardless of |P| value.
3.- f(p,x) has either no root, or just one root, depending upon p
The threshold funtion is
if f(x)>0 then B(k)==1 else B(k)==0
this is
f(p,x)=(x+10)^.5-p-x^.5
Now
(x+10).^.5-p>x.^.5 is same as (x+10).^.5-x.^.5>p
There's a range of p that keeps f(p,x)=0 without any (real) root.
For the particular case p=0 then (x+10).^.5 and x.^.5 do not intersect (until Inf reached = there's no intersection)
figure;plot(x,(x+10).^.5,x,x.^.5);grid on
[![enter image description here][3]][3]
y2=diff((x+10).^.5-x.^.5)
figure;plot(x(2:end),y2);
grid on;xlabel('x')
title('y2=diff((x+10).^.5-x.^.5)')
[![enter image description here][3]][3]
% 005
This means the condition f(x)>0 is always true holding all bits of B=1. With B=1 then d(A,B) turns into d(A,1), a constant.
However, for a certain value of p then there's one root and f(x)>0 is always false keeping all bits of B=0.
In this case d(A,B) the cost function turns into d(A,0) and this is A itself.
4.- P as a vector
The optimization gains in degrees of freedom if instead of P scalar, P is considered as vector.
For a given x there's a value of p that switches B(k) from 0 to 1.
Any value of p below such threshold keeps B(k)=0.
Equivalently, inverting f(x) :
g(p)=(10-p^2)^2/(4*p^2)>x
Values of x below this threshold bring B closer to A because for each element of B it's flipped to the element value of A.
Therefore, it's convenient to consider P as a vector, not a ascalar, and :
For all, or as many (as possible) elements of C to meet c(k)<(10-p^2)^2/(4*p^2) in order to get C=A or
minimize d(A,C)
5.- roots of f(p,x)
syms t positive
p=[-1000:.1:1000];
zp=NaN*ones(1,numel(p));
sol=zeros(1,numel(p));
for k1=1:1:numel(p)
p(k1)
eq1=(t+10)^.5-p(k1)-t^.5-p(k1)==0;
s1=solve(eq1,t);
if ~isempty(s1)
zp(k1)=s1;
end
end
nzp=~isnan(zp);
zp(nzp)
returns
=
620.0100 151.2900 64.5344 34.2225 20.2500 12.7211
8.2451 5.4056 3.5260 2.2500 1.3753 0.7803
0.3882 0.1488 0.0278

Mnist dataset pattern recognition accuracy

I'm completely new to matlab and this is my first project. Mnist has 60000 picture between 0 and 9 for training and 1000 picture to test. what I did is try to make a pattern for all of this 10 class (0 to 9) by using mean.then for for recognition I use Euclidean distance. this is very simple but the accuracy is really low.
I don't know where is exactly my problem to give my back this percentage of accuracy. the accuracy :1.73%
here is my code
finding 10 pattern for all of our class:
root = 'F:\matlab\ex1\exercise-EquivaliencOfL2DistanceAndDotProduct\dataset';
fn = strcat (root, '\MnistTrainX.mat');
load (fn);
fn = strcat (root, '\MnistTrainY.mat');
load (fn);
weights = zeros (10, 784);
b = zeros (10, 1);
im=reshape(MnistTrainX(5,:),[28 ,28]);
imshow(im,[]);
imshow(im',[]);
for c=1 : 10
idx=find(MnistTrainY == c-1);
weights (c,:)=mean( MnistTrainX(idx,:));
end
trainAccuray = ComputeInnerProductAccuracy(weights,b, MnistTrainX,MnistTrainY);
display(trainAccuray);
fn = strcat (root, '\MnistTestX.mat');
load (fn);
fn = strcat (root, '\MnistTestY.mat');
load (fn);
testAccuray = ComputeInnerProductAccuracy(weights, b, MnistTestX, MnistTestY);
display(testAccuray);
and this is accuracy function
function [acc]=ComputeInnerProductAccuracy(weights, b, X, Y)
n = size(X, 1);
minmat = zeros (60000, 2);
endmat = zeros (60000, 10);
m = size(X);
a=0;
for i=1 : n
for j=1 : 10
endmat(i,j)=sum((X(i,:)-(weights(j,:))).^2,2);
end
[minmat(i,1) ,minmat(i,2)]= min(endmat(i,:));
if minmat(i,2)== Y(i)
a=a+1;
end
end
acc=(a*100)/60000;
end
Your code is mostly correct, though it's quite inefficient. I won't spend the time to make it more efficient as there are many areas that need addressing. Instead I'll focus on what is wrong. There are two things wrong with the code. Firstly is when you find which digit has the lowest distance:
[minmat(i,1) ,minmat(i,2)]= min(endmat(i,:));
Note that the second output of min produces the location of where the minimum is starting at index 1. The class values in Y should contain 0 to 9 but the output index of min in your case is from 1 to 10. The output minimum indices and the corresponding class values are 1 off from each other, which is probably the reason why you have such bad accuracy.
Therefore, you have to subtract 1 from minmat(i, 2) before you check to see if the minimum label is indeed the ground truth... or you can simply add 1 to Y(i) when checking:
[minmat(i,1) ,minmat(i,2)]= min(endmat(i,:));
if minmat(i,2)== Y(i)+1 % Change
a=a+1;
end
The second thing that is incorrect is that the "inner product" function (actually you're computing the Euclidean distance.... but let's put that aside for this answer) assumes that there are always 60000 inputs yet your test set doesn't have this many inputs. This will work fine on your training data but it will report the wrong accuracy for your test data. Make sure you change all instances of 60000 in the function to n. This variable you've already created in your code and determines how many inputs there are.

lsqr result strongly depends on weights

I need to solve:
argmin||W*FT^-1(Ax)-W*p||
using lsqr. p is image, x is k-space matrix, A is a matrix and W is a weighting matrix. In order to pass them to matlab lsqr, I vectorized p, x and W.
This is my code:
b=W.*p;
x=lsqr(#(x1,modo)FUNC(x1,W_vector,A,modo),b,tol,maxit);
X_k_lsqr=reshape(x,dim(1),dim(2),dim(3));
X_lsqr=real(ifftn(X_k_lsqr)).*MASK(:,:,:,1);
%% Auxiliary function
function [result modo]=FUNC(x1,W_vector,A,modo)
%Computes y=A*x for modo='notransp'
%Computes y=A'*x for modo='transp'
switch modo
case 'notransp'
res=A*x1;
R1=reshape(res,norient,dim(1)*dim(2)*dim(3));
for co=1:norient
R2(:,:,:,co)=reshape(R1(co,:),dim(1),dim(2),dim(3));
FR(:,:,:,co)=ifftn(R2(:,:,:,co));
aux=FR(:,:,:,co);
R3(co,:)=aux(:).';
end
result=W.*R3(:);
case 'transp'
RR1=reshape(x1./(W+eps),norient,dim(1)*dim(2)*dim(3));
for co=1:norient
RR2(:,:,:,co)=reshape(RR1(co,:),dim(1),dim(2),dim(3));
FRR(:,:,:,co)=fftn(RR2(:,:,:,co));
aux=FRR(:,:,:,co);
RR3(co,:)=aux(:).';
end
result=A'*RR3(:);
end
end
As W appears in both terms of the minimization problem, I would have expected the image I obtain as a result to be almost independent on W values.
The image looks qualitatively the same if I change W, but its values strongly depend on W. I don't know if something is wrong with my code.
Should I actually obtain almost the same values for different W?
A question: Have you checked the flag? Are you sure that you are using the results while the flag is 0?
An argument: I can assume W also as a switch that determines which components of p I want to minimize. If W*(Ax-b) is really equal to 0, then you are right but here we know that there is not an exact solution and it becomes W*(Ax-b) < W*tolerance. So, you are depending the end point of the algorithm on the elements of W together with the tolerance.

how to solve a very large overdetermined system of linear equations?

I am doing a project about image processing, and I need to solve the following set of equations:
Nx+Nz*( z(x+1,y)-z(x,y) )=0
Ny+Nz*( z(x+1,y)-z(x,y) )=0
and equations of the boundary (bottom and right side of the image):
Nx+Nz*( z(x,y)-z(x-1,y) )=0
Ny+Nz*( z(x,y)-z(x,y-1) )=0
where Nx,Ny,Nz are the surface normal vectors at the corresponding coordinates and are already determined. Now the problem is that since (x,y) are the coordinates on an image, which typically has a size of say x=300 and y=200. So there are 300x200=60000 unknowns. I rewrite the equations in the form of Mz=b, where M has a size of 120,000x60000, and both z and b are vectors of length 60000. When I solve it using the function in python scipy.linalg.lstsq, I run into memory errors.
I notice that M is very sparse as it only has two non-zero entries of either 1 or -1 in each row. However, I don't know how I can utilize it to solve the problem. Any ideas how I can solve it more efficiently in matlab or python?
In python I find a library that has the lsmr method (as mentioned by someone in the comment). Other than using this algorithm to solve the equation Mx=b, I want to know if I need to store M and B in sparse format as well. Now I just create a very large array with all entries zero in the beginning, then I use a for loop to loop over each pixel and change the corresponding entries to 1 or -1. Then I apply lsmr to solve Mx=b directly. Does it help if I construct the matrix M and b in any one of the sparse format? Right now most of the time spent is in solving Mx=b. Construct the array M,b and doing all previous tasks take negligible time compared to solving Mx=b.
thanks
edit: this is the python code I use to generate matrix M and b. They should be 'correct', but not sure if there are other better ways of rewriting the system of linear equations.
eq_no = 0
for pix in range(total_pix):
row, col = y[pix], x[pix]
if index_array[row,col] >= 0: # confirm (x,y) is inside boundary
# check x-direction
if index_array[row,col+1] >= 0: # (x+1,y) is inside boundary
M[eq_no,pix] = -1
M[eq_no,pix+1] = 1
b[eq_no,0] = -normal_array[row,col,0]/normal_array[row,col,2]
eq_no += 1
# check y-direction
next_pix = index_array[row+1,col]
if next_pix >= 0:
M[eq_no , pix] = -1
M[eq_no , next_pix] = 1
b[eq_no,0] = -normal_array[row,col,1]/normal_array[row,col,2]
eq_no += 1

need explanation about a matlab code snippet about moran process

I am new to Matlab. I was reading this code snippet, but in some parts (marked with asterisks) I don't understand what it means, so if anybody could help would be very much appreciated
function [A1nmb] = moran(initsize, popsize)
% MORAN generates a trajectory of a Moran type process
% which gives the number of genes of allelic type A1 in a population
% of haploid individuals that can exist in either type A1 or type A2.
% The population size is popsize and the initial number of type A1
% individuals os initsize.
% Inputs: initsize - initial number of A1 genes
% popsize - the total population size (preserved)
if (nargin==0)
initsize=10;
popsize=30;
end
A1nmb=zeros(1,popsize);
A1nmb(1)=initsize;
**lambda = inline('(x-1).*(1-(x-1)./N)', 'x', 'N');
mu = inline('(x-1).*(1-(x-1)./N)', 'x', 'N');**
x=initsize;
i=1;
while (x>1 & x<popsize+1)
if (lambda(x,popsize)/(lambda(x,popsize)+mu(x,popsize))>rand)
x=x+1;
A1nmb(i)=x;
else
x=x-1;
A1nmb(i)=x;
end;
i=i+1;
end;
nmbsteps=length(A1nmb);
***rate = lambda(A1nmb(1:nmbsteps-1),popsize) ...
+mu(A1nmb(1:nmbsteps-1),popsize);***
**jumptimes=cumsum(-log(rand(1,nmbsteps-1))./rate);**
jumptimes=[0 jumptimes];
stairs(jumptimes,A1nmb);
axis([0 jumptimes(nmbsteps) 0 popsize+1]);
The first line you marked
lambda = inline('(x-1).*(1-(x-1)./N)', 'x', 'N');
creates something called an inline function. It is equivalent to defining a mathematical function. Example:
y = inline('x^2')
would allow you to do
>> y(2)
4
This immediately explains the second line you marked.
rate = lambda(A1nmb(1:nmbsteps-1),popsize) ...
+mu(A1nmb(1:nmbsteps-1),popsize);
will compute the value of the function lambda(x,N) at x = A1nmb(1:nmbsteps-1) and N = popsize.
I will say immediately here that you should take a look at anonymous functions, a different format used to accomplish the same as inline. Only, anonymous functions are generally better supported, and usually a lot faster than inline functions.
Then, for the final line,
jumptimes = cumsum(-log(rand(1,nmbsteps-1))./rate);
is a nested command. rand will create a matrix containing pseudorandom numbers, log is the natural logarithm ("ln"), and cumsum creates a new matrix, where all the elements in the new matrix are the cumulative sum of the elements in the input matrix.
You will find the commands doc and help very useful. Try typing
doc cumsum
or
help inline
on the Matlab command prompt. Try that again with the commands forming the previous statement.
As a general word of advice: spend an insane lot of time reading through the documentation. Really, for each new command you encounter, read about it and play with it in a sandbox until you feel you understand it. Matlab only becomes powerful if you know all its commands, and there are a lot to get to know.
It defines an inline function object. For example this
lambda = inline('(x-1).*(1-(x-1)./N)', 'x', 'N')
defines lambda as a function with 2 variables. When you call lambda(A,n) Matlab simply expands the function you define in the first string. Thus lambda(A,n) using the variables you provide in the function call. lambda(A,n) would will evaluate to:
(A-1).*(1-(A-1)./n)
it just expands the function using the parameters you supply. Take a look at this link for more specific details http://www.mathworks.co.uk/help/techdoc/ref/inline.html
The cumsum function just returns the cumulative sum of a matrix along a particular dimension. Say we call cumsum on a vector X, then the value at element i in the result is equal to the sum of elements in X from index 1 to i. For example X = [1 2 1 3] we would get
AA = cumsum(X);
we would have
AA = [1 3 5 8]
See this link for more details and examples http://www.mathworks.co.uk/help/techdoc/ref/cumsum.html