I am trying to link two equations, where I use a for loop calculate the value of k from the range of frequencies (eg. 1-5 Hz) then use each of the k values and substitute the values of k into a 6x6 matrix. Can anyone help show me how to create a matrix for each value of k in Matlab?
1st Equation
for f = 1:5; % Range of Frequencies (Hz)
f;
w = 2.*pi.*f; % Angular Frequency (Hz)
p = 8050;% Density of Mild Steel(kg/m^3)
v = 0.30; % Poissons Ratio of Mild Steel
R = 0.02; % Radius of Pipe (m)
E = 210*10^9; % Youngs Modulus of Mild Steel (pa)
a = (w.^2).*p;
b = (p.*(1-(v.^2)).*(R.^2).*(w.^2)-E);
c = (p.*(R.^2).*(w.^2)-E).*E;
**k(f) = sqrt((a.*b)/c); % k = Wave Number**
end
2nd Equation (6x6 Matrix)
k =
L1=0.1;
L2=0.6;
L3=0.6;
D= [0,0,exp(-k*L1),exp(-k*L2),0,0; exp(-k*L1),1,exp(-k*L1),exp(-k*L2),0,0; -k*exp(-k*L1),k,k*exp(-k*L1),-k*exp(-k*L2),0,0;0,0,exp(-k*(L1+L2)),k,-exp(-k*(L1+L2)),-exp(-k*L3);0,0,-k*exp(-k*(L1+L2)),1,k*exp(-k*(L1+L2)),k*exp(-k*L3);0,0,exp(-k*(L1+L2)),1,0,0]
(Answer modified following the comment)
You can try definig the output array D as a 3 dimensions array.
D=NaN(6,6,length(k))
for i=1:length(k)
D(:,:,i)= [0,0,exp(-k(i)*L1),exp(-k(i)*L2),0,0; exp(-k(i)*L1),1,exp(-k(i)*L1),exp(-k(i)*L2),0,0; -k(i)*exp(-k(i)*L1),k(i),k(i)*exp(-k(i)*L1),-k(i)*exp(-k(i)*L2),0,0;0,0,exp(-k(i)*(L1+L2)),k(i),-exp(-k(i)*(L1+L2)),-exp(-k(i)*L3);0,0,-k(i)*exp(-k(i)*(L1+L2)),1,k(i)*exp(-k(i)*(L1+L2)),k(i)*exp(-k(i)*L3);0,0,exp(-k(i)*(L1+L2)),1,0,0]
end
The D array will be:
D(:,:,1) =
0 0 0.9999 0.9993 0 0
0.9999 1.0000 0.9999 0.9993 0 0
-0.0012 0.0012 0.0012 -0.0012 0 0
0 0 0.9991 0.0012 -0.9991 -0.9993
0 0 -0.0012 1.0000 0.0012 0.0012
0 0 0.9991 1.0000 0 0
D(:,:,2) =
0 0 0.9998 0.9985 0 0
0.9998 1.0000 0.9998 0.9985 0 0
-0.0025 0.0025 0.0025 -0.0025 0 0
0 0 0.9983 0.0025 -0.9983 -0.9985
0 0 -0.0025 1.0000 0.0025 0.0025
0 0 0.9983 1.0000 0 0
D(:,:,3) =
0 0 0.9996 0.9978 0 0
0.9996 1.0000 0.9996 0.9978 0 0
-0.0037 0.0037 0.0037 -0.0037 0 0
0 0 0.9974 0.0037 -0.9974 -0.9978
0 0 -0.0037 1.0000 0.0037 0.0037
0 0 0.9974 1.0000 0 0
D(:,:,4) =
0 0 0.9995 0.9971 0 0
0.9995 1.0000 0.9995 0.9971 0 0
-0.0049 0.0049 0.0049 -0.0049 0 0
0 0 0.9966 0.0049 -0.9966 -0.9971
0 0 -0.0049 1.0000 0.0049 0.0049
0 0 0.9966 1.0000 0 0
D(:,:,5) =
0 0 0.9994 0.9963 0 0
0.9994 1.0000 0.9994 0.9963 0 0
-0.0061 0.0062 0.0061 -0.0061 0 0
0 0 0.9957 0.0062 -0.9957 -0.9963
0 0 -0.0061 1.0000 0.0061 0.0061
0 0 0.9957 1.0000 0 0
Hope this helps.
I will try to answer your question...
Firstly, you don't need the initial for loop. You can calculate all values of wavelength without loops.
f = 1:5; % Range of Frequencies (Hz)
w = 2.*pi.*f; % Angular Frequency (Hz)
p = 8050;% Density of Mild Steel(kg/m^3)
v = 0.30; % Poissons Ratio of Mild Steel
R = 0.02; % Radius of Pipe (m)
E = 210*10^9; % Youngs Modulus of Mild Steel (pa)
a = (w.^2).*p;
b = (p.*(1-(v.^2)).*(R.^2).*(w.^2)-E);
c = (p.*(R.^2).*(w.^2)-E).*E;
k = sqrt((a.*b)./c); % k = Wave Number
L1=0.1;
L2=0.6;
L3=0.6;
Then you can use a for loop to calculate the D matrix and a cell array to store the results:
results = cell(1, length(k));
for i = 1:length(k)
results{i} = [
0,0,exp(-k(i)*L1),exp(-k(i)*L2),0,0;...
exp(-k(i)*L1),1,exp(-k(i)*L1),exp(-k(i)*L2),0,0;...
-k(i)*exp(-k(i)*L1),k(i),k(i)*exp(-k(i)*L1),-k(i)*exp(-k(i)*L2),0,0;...
0,0,exp(-k(i)*(L1+L2)),k(i),-exp(-k(i)*(L1+L2)),-exp(-k(i)*L3);...
0,0,-k(i)*exp(-k(i)*(L1+L2)),1,k(i)*exp(-k(i)*(L1+L2)),k(i)*exp(-k(i)*L3);...
0,0,exp(-k(i)*(L1+L2)),1,0,0
]
end
P.S. Without trying to get on to you, I think that what you just want is to someone solve an excercise for you. If this is not the case, ignore my p.s.
Related
I want to solve the following equation for X. All parameters in my equation are matrices:
( [A]' * [X] )+( [X] * [A] ) = -I
I =
0 0 0 0
0 0 0 0
0 0 6.7955 -2.8529
0 0 -2.8529 3.9426
and
[A] =
-0.0038 -0.0011 -0.0012 -0.0012
-0.0011 -0.0049 -0.0012 -0.0023
1.0000 0 0 0
0 1.0000 0 0
You can use sylvester:
>> sylvester(A', A, -I)
ans =
1.0e+06 *
2.2772 -1.4202 0.0071 -0.0045
-1.4202 0.9749 -0.0043 0.0032
0.0071 -0.0043 0.0011 -0.0005
-0.0045 0.0032 -0.0005 0.0005
I'm trying to solve a system of 10 linear equations out of which the middle 8 equations look alike. They look like this :
t_i-1 - 2.3086*(t_i) + t_i+1 == -7.7160
where i = 2:9
so I decided to construct the coefficient matrix and the constant matrix(array) for the system of equations through looping.This is what I did.
T = sym('t' , [1 10]); %% Creates a vector T = [ t1 t2 .... t10]
A_10 = zeros(10,10);
b_10 = zeros(10,1);
for i = 2:9 %% This loop generates the equations and arranges them in the matrices A_10 and B_10.
T(i-1) - 2.3086*T(i) + T(i+1) == -7.7160;
[A_10(i,i-1:i+1),b_10(i,1)] = equationsToMatrix(ans)
end
Everything except for the ninth row(last but one) is correct in the Matrix A_10. This is what A_10 looks like
A_10 =
Columns 1 through 9
0 0 0 0 0 0 0 0 0
1.0000 -2.3086 1.0000 0 0 0 0 0 0
0 1.0000 -2.3086 1.0000 0 0 0 0 0
0 0 1.0000 -2.3086 1.0000 0 0 0 0
0 0 0 1.0000 -2.3086 1.0000 0 0 0
0 0 0 0 1.0000 -2.3086 1.0000 0 0
0 0 0 0 0 1.0000 -2.3086 1.0000 0
0 0 0 0 0 0 1.0000 -2.3086 1.0000
0 0 0 0 0 0 0 1.0000 1.0000
0 0 0 0 0 0 0 0 0
Column 10
0
0
0
0
0
0
0
0
-2.3086
0
The last three elements of the row nine should be 1 , -2.3086 , 1 like the previous rows but it shows 1, 1, -2.3086. What am I doing wrong here?
This is what the iteration looks like in the loop
ans = t8 - (11543*t9)/5000 + t10 == -1929/250
The equation is correct too. I can't figure out what the problem is.
Without the second input vars, equationsToMatrix uses symvar to determine the variable list.
Using symvar directly with the last equation gives
>> i = 9;symvar(T(i-1) - 2.3086*T(i) + T(i+1) == -7.7160)
ans =
[ t10, t8, t9]
So for whatever reason, symvar produced the incorrect ordering for only the last equation (possibly because 1 < 9). To remedy the situation, pass your intended ordering using the second input
eqn = T(i-1) - 2.3086*T(i) + T(i+1) == -7.7160;
[A_10(i,i-1:i+1),b_10(i,1)] = equationsToMatrix(eqn,T(i-1:i+1));
You'll also noticed I assigned the equation to an explicit variable eqn. This is better practice than relying on ans.
Also, since you're producing a numeric array anyway, you can produce A without the Symbolic Toolbox in a number of ways. For example:
n = 10;
A = full(spdiags(ones(n,1)*[1,-2.3086,1],[-1,0,1],n,n));
A([1,end],:) = 0;
I want to project the texture of 3D surface (CylCoors 300000x3) into a 2D plane (Image 380x360). For doing so I take every unique value in Z (UniqueZ=unique(CylCoors(:,3))) and and Theta (UniqueTheta=unique(CylCoors(:,1))) and project all the texture values (PointValues 300000x1) where both meet like this:
Image=zeros(max(UniqueH),max(UniqueTheta)); %380x360
tic
HMat=bsxfun(#eq,CylCoors(:,3),UniqueH'); % 300000x380
ThetaMat=bsxfun(#eq,CylCoors(:,1),UniqueTheta'); %300000x360
for ii=1:length(UniqueH) % Sloooow and not nice :(
for jj=1:length(UniqueTheta)
Image(ii,jj)=sum(PointValues.*...
HMat(:,ii).*ThetaMat(:,jj))/...
sum(HMat(:,ii).*ThetaMat(:,jj));
end
end
toc
Here's an example with trimmed variables:
CylCoorsSample = [263.0000 184.2586 10.0000
264.0000 183.0417 10.0000
264.0000 182.1572 10.0000
82.0000 157.4746 11.0000
80.0000 158.2348 11.0000
86.0000 157.3507 11.0000
84.0000 157.7633 11.0000]
PointValuesSample = [0.4745
0.5098
0.5020
0.4784
0.4510
0.4431
0.5804]
UniqueTheta = [80
82
84
86
263
264]
UniqueH =[10
11]
ThetaMat = HMat =
0 0 0 0 1 0 1 0
0 0 0 0 0 1 1 0
0 0 0 0 0 1 1 0
0 1 0 0 0 0 0 1
1 0 0 0 0 0 0 1
0 0 0 1 0 0 0 1
0 0 1 0 0 0 0 1
Image = % size: length(UniqueH)xlength(UniqueTheta)
NaN NaN NaN NaN 0.4745 0.5059
0.4510 0.4784 0.5804 0.4431 NaN NaN
Is there a way to vectorize the for loops using accumarray? Something tells me this is the case, but I find the multidimensional sub indexing for this function quite confusing.
Any other vectorization solutions (using smart combinations of reshape,bsxfun, and sum I assume) are also welcome, but I would really like to understand this use of accumarray a bit better.
Given:
CylCoorsSample = [263.0000 184.2586 10.0000
264.0000 183.0417 10.0000
264.0000 182.1572 10.0000
82.0000 157.4746 11.0000
80.0000 158.2348 11.0000
86.0000 157.3507 11.0000
84.0000 157.7633 11.0000]
PointValuesSample = [0.4745
0.5098
0.5020
0.4784
0.4510
0.4431
0.5804]
You can use accumarray as follows (using the third output of unique to generate the required subs input):
[UniqueTheta, ~, subsTheta]=unique(CylCoorsSample(:,1))
[UniqueH,~,subsH]=unique(CylCoorsSample(:,3))
sz = [numel(UniqueH), numel(UniqueTheta)]
Image = accumarray([subsH, subsTheta], PointValuesSample, sz, #mean, NaN)
So I used MATLAB's bwdist function to obtain the distance transform of a binary image. My question is, how do I transform a signed distance matrix back into a binary image?
D = bwdist(BW)
Specifically, is there a transform that can go back from BW -> D?
If D = bwdist(BW), how about BW0 = D<=0?
Consider the first example from the bwdist documentation:
bw = zeros(5,5); bw(2,2) = 1; bw(4,4) = 1
bw =
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 1 0
0 0 0 0 0
[D,IDX] = bwdist(bw)
D =
1.4142 1.0000 1.4142 2.2361 3.1623
1.0000 0 1.0000 2.0000 2.2361
1.4142 1.0000 1.4142 1.0000 1.4142
2.2361 2.0000 1.0000 0 1.0000
3.1623 2.2361 1.4142 1.0000 1.4142
To get back your binary image, you just want the points in the distance transform that are equal to zero (i.e. on a non-zero pixel in the original bw):
>> bw0 = D<=0
bw0 =
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 1 0
0 0 0 0 0
>> isequal(bw,bw0)
ans =
1
I'm using Matlab and well it's straightforward to find the probability of an element in a matrix, but I a little unsure of how to find probability of an element in a row or column.
e.g this matrix:
X = [
1 2 4 1 8;
5 3 6 9 2;
6 2 2 3 2
];
How would I find the probability of "2" occurring in each row and column of this random matrix.
You could do the following:
X_unique = unique(X);
p_row = zeros(size(X,1),numel(X_unique));
p_col = zeros(size(X,2),numel(X_unique));
for ii = 1:size(X,1)
p_row(ii,:) = hist(X(ii,:),X_unique);
p_row(ii,:) = p_row(ii,:)/sum(p_row(ii,:));
end
for ii = 1:size(X,2)
p_col(ii,:) = hist(X(:,ii),X_unique);
p_col(ii,:) = p_col(ii,:)/sum(p_col(ii,:));
end
Now, each row of p_row contains the probability distribution of the elements of unique(X) in the corresponding row of X and each row of p_col contains the probability distribution of the elements of unique(X) in the corresponding column of X.
For example, for the given example,
X_unique =
1
2
3
4
5
6
8
9
Thus,
p_row =
0.4000 0.2000 0 0.2000 0 0 0.2000 0
0 0.2000 0.2000 0 0.2000 0.2000 0 0.2000
0 0.6000 0.2000 0 0 0.2000 0 0
p_col =
0.3333 0 0 0 0.3333 0.3333 0 0
0 0.6667 0.3333 0 0 0 0 0
0 0.3333 0 0.3333 0 0.3333 0 0
0.3333 0 0.3333 0 0 0 0 0.3333
0 0.6667 0 0 0 0 0.3333 0
Here's a simple, not-quite-Matlab-ish solution that works on non-empty bi-dimensional matrices, looking for elements with the value "2", and returning probabilities by column:
a = [1 2 4 1 8; 5 3 6 9 2; 6 2 2 3 2];
nrows = size(a,1);
ncols = size(a,2);
pc = zeros(1, ncols); % Prob. by column
% Iterate trough columns
for k = 1:ncols
n = sum(a(:,k) == 2);
pc(k) = n/nrows;
end;
You can adapt it to compute "probabilities" by row, or by other dimensions, or look for other values.