enter image description here
I am having difficulty with my code aligning right shifted waveforms by the minimum peak point. In the left shifted, I copy the difference in indices between the desired minimum point and the given one to left of the waveform, and then delete those extra points after once this aligns the waveform. However, the same technique is not working for the right shifted ones. Any help would be much appreciated! Input (vals) is any n x 97 matrix.
function [vals] = align_wvs(wvs)
%Align_wvs - Align waveforms to minimum point
%
%align_wvs(wvs)
%
%wvs - matrix of waveforms
%
%Returns 'vals' - newly aligned matrix of waveforms
wvfrms = (wvs*10^6); %convert to microvolts
wvfrms = wvfrms(:,all(~isnan(wvfrms)));
min_pt = min(wvfrms(:)); %find minimum point in wvs
[~,col] = find(wvfrms==min_pt); %find index of min poin
if numel(col)>1
col = col(1);
end
%and that of other wvfrms
vals = zeros(size(wvfrms)); %matrix of size wvfrms, vals
for i = 1:size(vals,1) %for length of input
vals(i,:) = wvfrms(i,:); %copy og wvfrm into vals
nums = vals(i,:); %get second copy
ind_min = min(nums);
[~,colmin] = find(nums==ind_min);
diff_col = col-colmin;
if (diff_col~=0) %if difference is not = 0
if (diff_col>0) %if wvfrm is shifted to the left
inds = nums(1:diff_col); %copy first n values of nums, where n is diff_rows
new_length = length(nums)+length(inds); %extend wvfrm by amount ind
new_vals = zeros(1,new_length); %create new array of size new_length
new_vals(1:(diff_col)) = inds; %add inds to begining of new array
new_vals(diff_col+1:end) = nums; %add nums to rest of array
new_vals(1:(diff_col)) = [];%delete diff_rows-1 values from end
vals(i,:) = new_vals; %add to values
else %if wvfrm is shifted to the right
inds = nums(end+(diff_col+1):end); %copy last n values of nums, where n is diff_rows
new_length = length(nums)+length(inds); %extend wvfrm by amount ind
new_vals = zeros(1,new_length); %create new array of size new_length
new_vals(end+(diff_col+1):end) = inds;%add inds to end of new array
new_vals(1:(end+(diff_col))) = nums;%add nums to rest of array
new_vals(1:(diff_col*-1)) = []; %delete diff_rows-1 values from begining
vals(i,:) = new_vals; %add to values
end
end
end
end
List item
Does replacing the if (diff_col~=0) block with the following work?
if (diff_col~=0)
if (diff_col>0)
vals(i,:) = [zeros(1,diff_col) nums(1:(end-diff_col))];
else
vals(i,:) = [nums((-diff_col+1):end) zeros(1,-diff_col)];
end
end
Related
I am running a matrix off of a nested for loop. My problem here is that the values come out wrong because the loop fills the matrix row by row. I would like to have the loop fill the matrix column by column to avoid this issue.
T_i = 85; %Initial temperature (K)
T_inf = 20; %Free stream temperature (K)
h = 50; %Convection heat transfer coefficient (W/m^2K)
alp = 0.0000015; %Thermal diffusivity (m^2/s)
k = 15; %Thermal conductivity (W/mK)
del_x = 0.03; %Incremental distance between center nodes (m)
del_t = 300; %Incremental time diference (s)
Fo = alp*del_t/(del_x^2) %Find the Numerical/Discretized Fourier Number
Bi = h*del_x/k %Find the Numerical/Discretized Biot Number
T__vec = [85;85;85;85] %Initial temperature vector for 4 node points.
%T_inf_vec = 20+zeros(1:10)
M=5 %No. of rows
N=10 %No. of columns
T_inf_vec = [20,20,20,20,20,20,20,20,20,20]
A=zeros(M,N);
A(1:4)= T__vec;
A = [T_inf_vec;A];
for i=2:M
for j=2:N
T_p1=(2*Fo*A(i+1,j-1))+(2*Bi*Fo*A(i-1,j-1))+(((1-2*Fo)-(2*Bi*Fo))*A(i,j-1))
T_p11 = Fo*A(i-1,j-1)-2*Fo*A(i,j-1)+A(i,j-1)+Fo*A(i+1,j-1);
if i==2
A(i,j)= T_p1
elseif i<1
A(i,j)= 20
else
A(i,j)= T_p11
end
end
end
Change the for loop by:
for j=2:M
for i=2:N
T_p1=(2*Fo*A(i+1,j-1))+(2*Bi*Fo*A(i-1,j-1))+(((1-2*Fo)-(2*Bi*Fo))*A(i,j-1))
T_p11 = Fo*A(i-1,j-1)-2*Fo*A(i,j-1)+A(i,j-1)+Fo*A(i+1,j-1);
if i==2
A(i,j)= T_p1
elseif i<1
A(i,j)= 20
else
A(i,j)= T_p11
end
end
end
I'm trying to iterate in MATLAB (not allowed to use in built functions) to find the maximum value of each row in a certain matrix. I've been able to find the max value of the whole matrix but am unsure about isolating the row and finding the max value (once again without using max()).
My loop currently looks like this:
for i = 1:size(A, 1)
for j = 1:size(A, 2)
if A(i, j) > matrix_max
matrix_max = A(i, j);
row = i;
column = j;
end
end
end
You need a vector of results, not a single value. Note you could initialise this to zero. Don't initialise to zero unless you know you only have positive values. Instead, initialise to -inf using -inf*ones(...), as all values are greater than negative infinity. Or (see the bottom code block) initialise to the first column of A.
% Set up results vector, same number of rows as A, start at negative infinity
rows_max = -inf*ones(size(A,1),1);
% Set up similar to track column number. No need to track row number as doing each row!
col_nums = zeros(size(A,1),1);
% Loop through. i and j = sqrt(-1) by default in MATLAB, use ii and jj instead
for ii = 1:size(A,1)
for jj = 1:size(A,2)
if A(ii,jj) > rows_max(ii)
rows_max(ii) = A(ii,jj);
col_nums(ii) = jj;
end
end
end
Note that if vectorisation doesn't violate your "no built-ins" rule (it should be fine, it's making the most of the MATLAB language), then you can remove the outer (row) loop
rows_max = -inf*ones(size(A,1),1);
col_nums = zeros(size(A,1),1);
for jj = 1:size(A,2)
% Get rows where current column is larger than current max stored in row_max
idx = A(:,jj) > rows_max;
% Store new max values
rows_max(idx) = A(idx,jj);
% Store new column indices
col_nums(idx) = jj;
end
Even better, you can cut your loop short by 1, and initialise to the first column of A.
rows_max = A(:,1); % Set current max to the first column
col_nums = ones(size(A,1),1); % ditto
% Loop from 2nd column now that we've already used the first column
for jj = 2:size(A,2)
idx = A(:,jj) > rows_max;
rows_max(idx) = A(idx,jj);
col_nums(idx) = jj;
end
You can modified it likes the following to get each max for each row:
% initialize
matrix_max = zeros(size(A,1),1);
columns = zeros(size(A,1),1);
% find max
for i = 1:size(A, 1)
matrix_max(i) = A(i,1);
columns(i) = 1;
for j = 2:size(A, 2)
if A(i, j) > matrix_max(i)
matrix_max(i) = A(i, j);
columns(i) = j;
end
end
end
I'm having trouble with a loop that counts the white pixels in a
piece of an image, and stores the total white pixels and the y and x
position of that piece in the image, each on its own array.
When I print the values inside the loop it works just fine, but right
after the loop the 3 arrays are filled with zeros.
Can anyone help?
Cod:
y = zeros(altura*largura);
x = zeros(altura*largura);
v = zeros(altura*largura);
for j=0:altura-1
for k=0:largura-1
pedaco = f8(j*40+1 : j*40+40, k*40+1 : k*40+40); %binary piece
pedac = im2uint8(pedaco);
totalBrancos = sum(sum(pedac)); %sum white pixels
pos = altura*j+k+1;
y(pos) = j;
x(pos) = k;
v(pos) = totalBrancos;
disp(y(pos)); %works
disp(x(pos)); %works
disp(v(pos)); %works
end
end
disp(y); %all zeros
disp(x); %all zeros
disp(v); %all zeros
Your zeros calls are creating a (alturalargura) by (alturalargura) matrix, which I don't think is what you intended as you are saving data into by calculating a position
If that's the case, try
y = zeros(1, altura*largura);
x = zeros(1, altura*largura);
v = zeros(1, altura*largura);
It is possible to use a single index into a multi-index matrix, however your pos calculation is not correct for doing that.
I'm using data set with 200 data points that is used to draw B-Spline curve and I want to extract the 100 original control points from this curve to use it in one algorithm to solve one problem. The result of control points it's too small compared with the value of the data points of B-Spline curve so I don't know if I make something wrong in the following code or not I need help to know that because I must used these control points to complete my study in one algorithm
link of set of data points:
https://drive.google.com/open?id=0B_2BUqaJptbqUkRWLWdmbmpQakk
Code :
% read data set
dataset = importdata("path of data set here");
x = dataset(:,1);
y = dataset(:,2);
for i=1:200
controlpoints(i,1) = x(i);
controlpoints(i,2) = y(i);
controlpoints(i,3) = 0;
end
% Create Q with some points from originla matrix controlpoints ( I take only 103 points)
counter =1;
for i=1:200
if (i==11) || (i==20) || (i==198)
Q(counter,:) = F(i,:);
counter = counter +1;
end
if ne(mod(i,2),0)
Q(counter,:) = F(i,:);
counter = counter+1;
end
end
I used Centripetal method to find control points from curve like the following picture
Complete my code:
% 2- Create Centripetal Nodes array from Q
CP(1) = 0;
CP(103) =1;
for i=2:102
sum = 0;
for j=2:102
sum = sum + sqrt(sqrt((Q(j,1)-Q(j-1,1))^2+(Q(j,2)-Q(j-1,2))^2));
end
CP(i) = CP(i-1) + (sqrt(sqrt((Q(i,1)-Q(i-1,1))^2+(Q(i,2)-Q(i-1,2))^2))/sum);
end
p=3; % degree
% 3- Create U_K array from CP array
for i=1:103
U_K(i) = CP(i);
end
To calculate control points we must follow this equation P=Qx(R') --> R' is inverse of R matrix so we must find R matrix then fins P(control points matrix) by the above equation. The following scenario is used to find R matrix
and to calculate N in B-Spline we must use these recursive function
Complete my code :
% 5- Calculate R_i_p matrix
for a=1:100
for b=1:100
R_i_p(a,b) = NCalculate(b,p,U_K(a),U_K);
end
end
% 6- Find inverse of R_i_p matrix
R_i_p_invers = inv(R_i_p);
% 7- Find Control points ( 100 points because we have curve with 3 degree )
for i=1:100
for k=1:100
PX(i) = R_inv(i,k) * Q(k,1);
PY(i) = R_inv(i,k) * Q(k,2);
end
end
PX2 = transpose(PX);
PY2 = transpose(PY);
P = horzcat(PX2,PY2); % The final control points you can see the values is very small compared with the original data points vlaues
My Recursive Function to find the previous R matrix:
function z = NCalculate(j,k,u,U)
if (k == 1 )
if ( (u > U(j)) && (u <= U(j+1)) )
z = 1;
else
z = 0;
end
else
z = (u-U(j)/U(j+k-1)-U(j)* NCalculate(j,k-1,u,U) ) + (U(j+k)-u/U(j+k)-U(j+1) * NCalculate(j+1,k-1,u,U));
end
end
Really I need to this help so much , I tried in this problem from one week :(
Updated:
Figure 1 for the main B-spline Curve , Figure 2 for the result control points after applied reverse engineering on this curve so the value is so far and so small compared with the original data points value
Updated(2):
I made some updates on my code but the problem now in the inverse of R matrix it gives me infinite value at all time
% 2- Create Centripetal Nodes array from Q
CP(1) = 0;
CP(100) =1;
sum = 0;
for i=2:100
sum = sum + sqrt(sqrt((Q(i,1)-Q(i-1,1))^2+(Q(i,2)-Q(i-1,2))^2));
end
for i=2:99
CP(i) = CP(i-1) + (sqrt(sqrt((Q(i,1)-Q(i-1,1))^2+(Q(i,2)-Q(i-1,2))^2))/sum);
end
% 3- Create U_K array from CP array
for i=1:100
U_K(i) = CP(i);
end
p=3;
% create Knot vector
% The first elements
for i=1:p+1
U(i) = 0;
end
% The last elements
for i=100:99+p+1
U(i) = 1;
end
% The remain elements
for j=2:96
sum = 0;
for i=j:(j+p-1)
sum = sum + U_K(i);
end
U(j+p) = (1/p)* sum;
end
% 5- Calculate R_i_p matrix
for a=1:100
for b=1:100
R_i_p(a,b) = NCalculate(b,p,U_K(a),U);
end
end
R_i_p_invers = inv(R_i_p);
% 7- Find Control points ( 100 points )
for i=1:100
for k=1:100
if isinf(R_inv(i,k))
R_inv(i,k) = 0;
end
PX(i) = R_inv(i,k) * Q(k,1);
PY(i) = R_inv(i,k) * Q(k,2);
end
end
PX2 = transpose(PX);
PY2 = transpose(PY);
P = horzcat(PX2,PY2);
Note: I updated my NCalculate recursive function to give me 0 if the result is NaN (not a number )
function z = NCalculate(j,k,u,U)
if (k == 1 )
if ( (u >= U(j)) && (u < U(j+1)) )
z = 1;
else
z = 0;
end
else
z = (u-U(j)/U(j+k-1)-U(j)* NCalculate(j,k-1,u,U) ) + (U(j+k)-u/U(j+k)-U(j+1) * NCalculate(j+1,k-1,u,U));
end
if isnan(z)
z =0;
end
end
I think there are a few dubious issues in your approach:
First of all, if you try to create a b-spline curve interpolating 103 input points (and no other boundary conditions are imposed), the b-spline curve will have 103 control points regardless what degree the b-spline curve is.
The U_K array is the parameter assigned to each input point. They are not the same as the knot sequence ti used by the Cox DeBoor recursive formula. If the b-spline curve is of degree 3, you shall have (103+3+1) knot values in the knot sequence. You can create the knot values in the following way:
0) Denote the parameters as p[i], where i = 0 to (n-1), p[0]=0.0 and n is number of points.
1) Create the knot values as
knot[0] = (p[1]+p[2]+p[3])/D (where D is degree)
knot[1] = (p[2]+p[3]+p[4])/D
knot[2] = (p[3]+p[4]+p[5])/D
......
These are the interior knot values. You should notice that p[0] and p[n-1] will not be used in this step. You will have (n-D-1) interior knots.
2) Now, add p[0] to the front of the knot values (D+1) times and add p[n-1] to the end of the knot values (D+1) times and you are done. At the end, you will have (N+D+1) knots in total.
I have an array A (I have written so as to make it similar to the matrix that I am using) :
%%%%%%%%%%%%% This is Matrix %%%%%%%%%%%%%%%%%%%%
a = 3; b = 240; c = 10; d = 30; e = 1;
mtx1 = a.*rand(30,1) + a;
mtx2 = round((b-c).*rand(30,1));
mtx3 = round((d-e).*rand(30,1));
mtx4 = -9999.*ones(30,1);
A = [mtx1 mtx2 mtx3 mtx4];
for i = 10:12
for ii = 17 :19
A(i,:)= -9999;
A(ii,:)= 999;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
I would calculate some statistical values, excluding from the calculation the values **-9999 and 999.
the statistical values must be calculated with respect to each column.
the columns represent respectively: the wind speed, direction, and
other parameters
I wrote a code but it is not correct
[nr,ncc]=size(A);
for i=1:ncc
B = A(:,i); %// Temp Vector
Oup=1; Odw=1; %// for Vector Control
while Oup>0 %// || Odw>0 % Oup>0 OR Odw>0 , Oup>0 && (AND) Odw>0
B=sort(B,'descend');
U = find(B<999 & B>-9999); % find for each column of the temp
%vector
Oup = length(U); % Calculates the length
B(U)=[]; % Delete values -9999 and 9999
end
% calculates parameters with the vector temp
count(i)=length(B);
med(i)=mean(B);
devst(i)=std(B);
mediana(i)=median(B);
vari(i)=var(B);
kurt(i)=kurtosis(B);
Asimm(i)=skewness(B);
Interv(i)=range(B);
Mass(i)=max(B);
Mini(i)=min(B);
if length(B)<nr
B(length(B)+1:nr)=nan;
end
C(:,i)=B(:); %//reconstruction of the original matrix
end
would you have any suggestions?
If your data set is in A, and you want to operate on it with a function f, just use logical indexing, i.e.:
f(A( ~(A==999 & A==-9999) )) =...
Alternatively, use find and linear indexing:
ind = find( ~(A==999 & A==-9999) );
f(A(ind)) = ....