I need to use the Offset function to look at more than one column. Can I use this code on a range of specific columns? - range

I need to use the Offset function to look at more than one column. Can I use this code on a range of specific columns?
'Assign Unique Customer Numbers
Sheets("Subjects").Select
i = 1
Range("A2") = i
Set IDRange = Range("B3:B" & LastFullRow)
For Each z In IDRange
If z = z.Offset(-1, 0) Then
z.Offset(0, -1) = i
ElseIf z <> z.Offset(-1, 0) Then
i = i + 1
z.Offset(0, -1) = i
End If
Next z

Related

Extracting values from a function

I have a loop within a function that spits out values similar to:
E = 3,2,1,-1,-2
for
i = 1,2,3,4,5
I'm trying to extract the position where E becomes negative and then identify the step before it.
My attempt was something like
finalPos = find(i(E<0));
Firstly, it just doesn't seem right (my matlab syntax knowledge is poor as)
but secondly even if it did work it would tell me all positions where E is less than 0, where I only want to know the position before where E is no longer positive. i.e. E = 1, i = 3
Any help would be greatly appreciated!
Check the below:
E = [3,2,1,-1,-2] ;
idx = find(sign(E)==-1) % Get the sign and get index
idx = find(E<0) % Get by value
for i = 1:length(E)
if sign(E(i)) == -1
fprintf('E is Negative\n')
else
fprintf('E is Positive\n')
end
end
For last positive value
you can use a variable to store the last value
Example:-
E=[3,2,1,-1,-2]
finalpos=-1
for i = 1:5
if ( E<0)
finalpos=E(i-1);
break;
end
end
finalpos

Split histogram into different regions in Matlab

I have an Image histogram using imhist and it contains 3 different regions like the attached image shows, I want to get the borders or the interval of the largest continuous area of the histogram, in this case, the second region is the one that I am looking for and the borders would be 43 and 225
You can find the begin and end bins for each region like this
[counts,binLocations] = imhist(I);
der = diff([false; counts>0; false]);
upedge = find(der == 1);
downedge = find(der == -1) - 1;
regions = [binLocations(upedge) binLocations(downedge)];
If the values are not exactly zero, but very close to zero then you can replace 0 with some threshold value in the above code.
Example
im = uint8(zeros(300,400));
im(1:100,:) = uint8(randi([0,40],[100,400]));
im(101:200,:) = uint8(randi([90,100],[100,400]));
im(201:300,:) = uint8(randi([140,240],[100,400]));
[counts,binLocations] = imhist(im);
der = diff([false; counts>0; false]);
upedge = find(der == 1);
downedge = find(der == -1) - 1;
regions = [binLocations(upedge) binLocations(downedge)];
results in
regions =
0 40
90 100
140 240
I will use the answer to this question to find regions of consecutive non zero elements in an array.
lets assume we have this array (histogram):
h = [0,0,0,1,2,3,44,77,5,656,0,0,0,0,0,0,2,99,7,34];
now we want to know were each region of consecutive non-zero elements starts and ends, in this example we want
startIndex = [4,17]
endIndex = [10,20]
lengths = [7,4]
to get this result we use the code from the question as follows:
dsig = diff([1,h(:)'==0,1]);
startIndex = find(dsig < 0);
endIndex = find(dsig > 0)-1;
duration = endIndex-startIndex+1;
and to get longest region use:
[~,maxLengthIndex] = max(lengths);
maxStartIndex = startIndex(maxLengthIndex);
maxEndIndex = endIndex(maxLengthIndex);

How does the following syntax may be shortened and improved?

Given a 12 x 13 matrix in Matlab, I need to select the row with the greatest value in column 9, every two rows, and create a matrix containing the selected rows. The following piece of code does the job, but I was wondering how this syntax could be improved and shortened.
A = rand(12,13);
a = A(1:2,:);
if a(1,9) > a(2,9)
a = A(1,:);
else
a = A(2,:);
end
b = A(3:4,:);
if b(1,9) > b(2,9)
b = A(3,:);
else
b = A(4,:);
end
c = A(5:6,:);
if c(1,9) > c(2,9)
c = A(5,:);
else
c = A(6,:);
end
d = A(7:8,:);
if d(1,9) > d(2,9)
d = A(7,:);
else
d = A(8,:);
end
e = A(9:10,:);
if e(1,9) > e(2,9)
e = A(9,:);
else
e = A(10,:);
end
f = A(11:12,:);
if f(1,9) > f(2,9)
f = A(11,:);
else
f = A(12,:);
end
SELECTED_A = [a;b;c;d;e;f];
Thank you.
I can provide a way shorter solution, but if you want it fully vectorized, you'll have to wait for someone with a little more proficiency. Here's the code:
A=rand(12,13);
B=zeros(6,13); % preallocate solutionarray
for ii=2:2:12 % loop through every (second) row
[~,ind]=max([A(ii,9),A(ii-1,9)]); % check which element is greater
B(ii/2,:)=A(ii-(ind==2),:); % select corresponding row
end
This will give you an array B with the values you are looking for.
EDIT: There was a little flaw in the code: the condition in row 5 of the code needs to be ind==2 otherwise it will always chose the row with the smaller entry in column 9. Alternatively you could also leave it ind==1 and switch the elements in row 4 i.e. max([A(ii-1,9),A(ii,9)])

MATLAB: Find function within range

How can I use the find function within specific ranges.
Say, I have an array arr1 with random values. I have the start & end indices of the portions I'd like to analyze (in this example, I want to find the first occurrence for when the value is larger than 0.8)
How could the find function be used here with start and end indices and the condition as well?
For example:
arr1 = rand(1000,1);
start_ind = [100;500;850];
end_ind = [160;620;925];
for i = 1:length(start_ind)
output = find(arr1(start_ind(i):end_ind(i)) >=0.8); % ????
end
Much appreciated,
Use the second argument of find to only get the first match. You can then shift indices by adding start_ind - 1:
arr1 = rand(1000,1);
start_ind = [100; 500; 850];
end_ind = [160; 620; 925];
output = zeros(length(start_ind), 1);
for i = 1:length(start_ind)
output(i) = find(arr1(start_ind(i):end_ind(i)) >=0.8, 1) + start_ind(i) - 1;
end

Saving intermediate variable values of a recursive function

I'm trying to code a function calculating difference quotients. I need to this for polynomial interpolation. Given nodes x = linspace(a,b,n+1), function values at the nodes y = func(x) I want to find the values of difference quotients f[x0], f[x_0,x_1], ..., f[x_0,x_1,...,x_n]. To calculate f[x_0,x_1,...,x_n] I will need f[x_0,x_1,...,x_(n-1)], etc., thus it would be a good idea save the intermediate steps on my way to f[x_0,x_1,...,x_n], so that on my way to f[x_0,x_1,...,x_n] I will save the preceding difference quotients as elements of a vector.
Could someone tell me how to correct my code in order to save appropriate difference quotient values? Here's the code:
function [fx, all_fx] = ilo2(a,b,x,y,fx,all_fx)
if a == b
fx(end+1) = y(a);
if a == 1
all_fx(end+1) = fx(end);
end
return
end
a;
b;
[c, all_fx] = ilo2(a+1,b,x,y,fx,all_fx);
[d, all_fx] = ilo2(a,b-1,x,y,fx,all_fx);
fx(end+1) = (c-d)/(b-a);
if a == 1
all_fx(end+1) = fx(end);
end
end
The difference quotients I need are under 'if a == 1' condition.
Ok, I think I fixed it:
function [all_fx,fx] = ilo(a,b,x,y,all_fx,fx)
if a == b
fx(end+1) = y(a);
if a == 1
all_fx(end+1) = fx(end);
end
return
end
[all_fx,c] = ilo(a+1,b,x,y,all_fx,fx);
[all_fx,d] = ilo(a,b-1,x,y,all_fx,fx);
fx(end+1) = (c-d)/(b-a);
if a == 1
all_fx(end+1) = fx(end);
end
end