**You are now following this question**

- You will see updates in your activity feed.
- You may receive emails, depending on your notification preferences.

547 views (last 30 days)

Show older comments

John D'Errico
on 1 Nov 2016

This is not even a MATLAB question. Not even close to the point where you can consider writing code, because you need to make many decisions, answer many questions.

What value is the maximum here? You cannot compute a half-max until you know what is the max. And you would also seem to need to know the min, as the half-max would be midway.

How can you compute the max of a relationship that seems to be trending upwards at each end, with no upper limit?

Do you intend to do smoothing? It would seem that otherwise, any such computation would be highly inaccurate. Lots of ways to do smoothing.

Once you have a curve that you are happy is smooth (or not if you do no smoothing) and you have decided what value for y is the half-max, then you compute the locations of those points on the curves by interpolation. Linear interpolation will surely suffice here, given how noisy is the data. But you have a long way to go before you start worrying about that.

parry sharma
on 1 Nov 2016

Image Analyst
on 1 Nov 2016

Image Analyst
on 1 Nov 2016

Edited: Image Analyst
on 24 Aug 2018

Use max():

% Find the half max value.

halfMax = (min(data) + max(data)) / 2;

% Find where the data first drops below half the max.

index1 = find(data >= halfMax, 1, 'first');

% Find where the data last rises above half the max.

index2 = find(data >= halfMax, 1, 'last');

fwhm = index2-index1 + 1; % FWHM in indexes.

% OR, if you have an x vector

fwhmx = x(index2) - x(index1);

Tusharkumar Sorathiya
on 15 Mar 2019

Hello Sir,

I have been using this logic for my thesis algorithm. Thanks a lot!!

problem i am facing now is: what if I want to find bandwidth at 25% reflection level. I tried to solve it by taking halfMax = (min(data) + max(data)) / 4; which works well. But when I have spectra something like as shown in attached figure. it always takes the very last value which isnt something i am looking for. I wanted to find out the value as depicted in figure.

Thanks in advance

Image Analyst
on 16 Mar 2019

Use a for loop

[maxValue, indexOfMax] = max(data);

value25 = 0.25 * maxValue

% Find 25% point on left

for index = indexOfMax : -1 : 1

if data(index) < value25

leftIndex = index;

break;

end

end

% Find 25% point on right

for index = indexOfMax : length(data)

if data(index) < value25

rightIndex = index;

break;

end

end

Tusharkumar Sorathiya
on 18 Mar 2019

Thanks a lot, you saved my time and made it easy.

really appreciated. :)

Image Analyst
on 18 Mar 2019

You're welcome. Then, can you please "Accept this answer"? Thanks in advance.

Tusharkumar Sorathiya
on 19 Mar 2019

Eunan McShane
on 17 Jul 2019

Hey Image Analyst,

I am working with a 999x512 matrix, for which I can simply calculate tha half max value of each column, although when using the indexing to find the locations 1 and 2 in order to find the half max, the script spits out a huge logical array which I can't work out how to manipulate into two values at the locations of interest, per column which I can take away and find the effective FWHM value. I am ignoring the first row in every column as it is effectively not a part of the waveform, I have attached a mini version of my matrix for you if you get a chance to look at this, thank you!

Image Analyst
on 19 Jul 2019

I don't understand. Try to describe in a different way, using a column of data to desmonstrate, or using images/diagrams. And describe what "Manipulate" means to you. Why can't you just do:

topRow = find(thisColumn, 1, 'first');

if ~isempty(topRow)

bottomRow = find(thisColumn, 1, 'last');

end

Eunan McShane
on 21 Jul 2019

Hey, I just want to find the two half max index locations as you do above, but for each of the 512 columns (whilst ignoring the first row in each column) by using your code above I can calculate the half max for each column but the index values will not calculate the FWHM for me.

Index 1 and 2 become 503049x512 logical arrays which I don't understand how they relate to the real index positions of 1 and 2, I hope this makes sense!

Image Analyst
on 21 Jul 2019

If this

clc

clear

close all;

fontSize = 16;

fprintf('Working...\n');

yourMatrix = rand(40, 30);

[rows, columns] = size(yourMatrix);

subplot(1, 2, 1);

imshow(yourMatrix);

title('Original Matrix', 'FontSize', fontSize);

axis('on', 'image');

for col = 1 : columns

thisColumn = yourMatrix(:, col);

% Find the half max value.

halfMax(col) = (min(thisColumn) + max(thisColumn)) / 2;

% Find where the data first drops below half the max.

index1(col) = find(thisColumn >= halfMax(col), 1, 'first');

% Find where the data last rises above half the max.

index2(col) = find(thisColumn >= halfMax(col), 1, 'last');

fwhm(col) = index2(col) - index1(col) + 1; % FWHM in indexes.

end

subplot(1, 2, 2);

imshow(yourMatrix, []);

axis('on', 'image');

hold on;

x = 1 : columns;

plot(x, index1, 'r-', 'LineWidth', 3);

plot(x, index2, 'r-', 'LineWidth', 3);

title('With upper and lower boundaries shown', 'FontSize', fontSize);

% Enlarge figure to full screen.

set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]);

msgbox('Done!');

doesn't work for you, I suggest you start a new question with your own data attached.

SHANTANU KSHIRSAGAR
on 25 Feb 2020

Dear Image Analyst,

I wanted to calculate the FWHM and area under pulse ; for each pulse , in a data containing multiple pulses .

I have the data in the form of excel sheets.

Can you help me with that.

Image Analyst
on 25 Feb 2020

Lots of us could. Post a new question, rather than here in parry's question.

fitri zabudin
on 28 Jan 2021

Image Analyst
on 29 Jan 2021

fitri zabudin
on 9 Feb 2021

Image Analyst
on 9 Feb 2021

SP
on 30 Jul 2021

Excuse me, sir. For the find function, can we limit the column (x-axis)? Such as find(data(:,50:100));

As I show the signal, because I want to calculate the full width at half maximum of this signal at the red arrow by using the 'first' and 'last' function. But the first and last are calculated at the red circle. So I want to limit the x-axis because I don't want to calculate at the red circle. Is it possible if I want to limit the x-axis in the range of the red arrow?

Now, I try to did such a find(data(:,50:100)); but it cannot to calculate correctly. I try to study the find function but I don't understand some sentence that is "If data is a multidimensional array, the find returns a column vector of the linear indices of the result". Maybe as this lesson, I cannot limit the data in x-axis.

If you have a good idea to resolve this problem, please suggest to me. If I'm not explaining well, I'm sorry.

of t

Image Analyst
on 31 Jul 2021

@SP, yes you can limit the search range by cropping the data like you did with find(data(:,50:100));

Just be aware that the rows and columns you find will be relative to that cropped array, not the original array.

MATLAB is in column major order so an array goes first down rows in a column before it moves to the next column, so the linear indexes are like this:

1 6 11

2 7 12

3 8 13

4 9 14

5 10 15

So if you wanted to find elements above 40 and less than 60:

m = 100 * rand(5, 3)

m = 5×3

80.2771 71.7417 41.5551
66.5391 71.0821 59.4884
8.8467 53.8624 93.7960
52.8215 42.6820 8.3886
27.8592 6.0552 40.8630

% Find values above 40 and below 60

mask = m > 40 & m < 60

mask = 5×3 logical array

0 0 1
0 0 1
0 1 0
1 1 0
0 0 1

[rows, column] = find(mask)

rows = 6×1

4
3
4
1
2
5

column = 6×1

1
2
2
3
3
3

linearIndexes = find(mask)

linearIndexes = 6×1

4
8
9
11
12
15

You can see that (row, column) = (4, 1) (the 1st elements) corresponds to 4.

(row, column) = (3, 2) (the 2nd elements) corresponds to 8.

(row, column) = (4, 2) (the 3rd elements) corresponds to 9.

(row, column) = (1, 3) (the 4th elements) corresponds to 11.

and so on

SP
on 31 Jul 2021

@Image Analyst Thank you, sir. I understand about the concept of linear indexes from your explanation. But I did the code like this:

vq2 = resample(x_ccd,100,1);

for kkkkkk = 1:30

halfMax = 0.5; % Set FWHM at 0.30

vq1(kkkkkk,:) = resample(IFFT_hologram_bf_NM(kkkkkk,:),100,1);

% Find where the data first drops below half the max.

index1 = find(vq1(kkkkkk,20000:35000) >= halfMax, 1, 'first');

% Find where the data last rises above half the max.

index2 = find(vq1(kkkkkk,:) >= halfMax, 1, 'last');

xx1 = vq2(index1); %find the position in mm

xx2 = vq2(index2); %find the position in mm

fwhm(kkkkkk,:) = xx2-xx1;

end

I did for loop that the literation will be calculate from row-by-row. Even I difined kkkkkk as the literation of for loop then I limited the range of x axis array (20000:35000), but the values of index1 and index2 isn't calculated correctly. The reason that I limited (kkkkkk,20000:35000) because I don't want to calculate at the two red circles. But if I define like this:

index1 = find(vq1(kkkkkk,:) >= halfMax, 1, 'first');

or

index1 = find(vq1(kkkkkk,1:62900) >= halfMax, 1, 'first'); (the number array of vq1 = 62900 arrays)

it can calculated index1 and index2 correctly. May you suggest about this problem to me, sir?

Image Analyst
on 31 Jul 2021

You either need to just add in the offset you searched from, like 20,000 to the index,

index1 = find(vq1(kkkkkk,20000:35000) >= halfMax, 1, 'first');

index1 = index1 + 19999; % Get index relative to the original length of the vector, not the cropped length.

or just mask out the stuff you don't want so it's not found

vq1(kkkkkk, 1:19999) = -inf;

vq1(kkkkkk, 35001:end) = -inf;

index1 = find(vq1(kkkkkk,20000:35000) >= halfMax, 1, 'first');

Maks
on 24 Aug 2018

Edited: Maks
on 24 Aug 2018

It should be "more or equal" for the first index: index1 = find(data >= halfMax, 1, 'first');

Image Analyst
on 24 Aug 2018

You're right. Thanks for catching that. I've edited my answer to fix it.

Muhammad Basit
on 9 Jul 2021

Image Analyst
on 11 Jul 2021

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!**An Error Occurred**

Unable to complete the action because of changes made to the page. Reload the page to see its updated state.

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

Select web siteYou can also select a web site from the following list:

Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.

- América Latina (Español)
- Canada (English)
- United States (English)

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)