面積を求めたい
4 views (last 30 days)
Show older comments
曲線をyが0以上の時の加速成分と減速成分、yが0以下の時の加速成分と減速成分の4つに分け、
それぞれ面積の合計を求めたいと考えております
% dataの準備
x = linspace(0,1,1000);
base = 4*cos(2*pi*x);
Pos = [1 2 3 5 7 8]/10;
Hgt = [3 7 5 5 4 5];
Wdt = [1 3 3 4 2 3]/100;
for n = 1:length(Pos)
Gauss(n,:) = Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2);
end
PeakSig = sum(Gauss)+base;
% 使用するデータ
A = PeakSig(1:600);
plot(A)
% 局所最大値を求める
[pks,locs] = findpeaks(A)
% 同様に局所最小値を求める
[pks1,locs1] = findpeaks(-A)
% 先ほど求めた局所最大値のインデックスをもとに区分けをする
plot(A)
yline(0)
xline(locs(1)),xline(locs(2)),xline(locs(3)),xline(locs(4)),xline(locs1(1)),xline(locs1(2)),xline(locs1(3)),xline(locs1(4)),xline(locs1(5))
以下は求めたいものになります。
yが0以上である青色の面積と赤色の面積
yが0以下である緑色とオレンジ色の面積
4つの区画に分け、それぞれの合計値を算出したいと考えております。
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1089565/image.png)
% 正から負に変わるタイミング(yが0)がわからないため絶対値に直す
B = abs(A);
plot(B)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1089570/image.png)
再度色をつけると上記のような区分けになります。
% インデックスに格納する
idx = locs1(1) >= x & x <= locs(1);
x1 = x(idx)
% 面積を求める
trapz(0.001,x1)
この作業を全区域で行い、それぞれ足し合わせる
現状、私ができる方法としては以上になります。
上記のように1つ1つインデックスに格納していけば面積の合計値を求めることは可能かと思いますが、
この作業を異なる1000以上の曲線で行いたいので、時間がかかりすぎてしまいます。
何か効率よく面積を求める方法がありましたらご教示いただければ幸いです。
よろしくお願いいたします。
0 Comments
Accepted Answer
Hernia Baby
on 6 Aug 2022
実際にやってみましょう
■前準備:同じデータです
x = linspace(0,1,1000);
base = 4*cos(2*pi*x);
Pos = [1 2 3 5 7 8]/10;
Hgt = [3 7 5 5 4 5];
Wdt = [1 3 3 4 2 3]/100;
for n = 1:length(Pos)
Gauss(n,:) = Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2);
end
PeakSig = sum(Gauss)+base;
% 使用するデータ
A = PeakSig(1:600);
plot(A)
■条件分離
idx1 傾きが0以上
idx2 値が0以上
idx1 = gradient(A)>=0;
idx2 = A >= 0;
値が負のものB{3}とB{4}は絶対値をとっています
B{1} = A( idx1 & idx2);
B{2} = A(~idx1 & idx2);
B{3} = abs(A( idx1 & ~idx2));
B{4} = abs(A(~idx1 & ~idx2));
可視化してみます
figure
hold on
cellfun(@plot,B)
legend({'傾き:正 & 値:正','傾き:負 & 値:正','傾き:正 & 値:負','傾き:負 & 値:負'})
hold off
面積を求めます
B_sum = cellfun(@sum,B,'UniformOutput',false)
B_sum = cell2mat(B_sum)
5 Comments
Hernia Baby
on 10 Aug 2022
返信ありがとうございます。
面倒くさい場合も無名関数よりも関数を一度自作し、一気にやらせる方が可読性もよくなります。
load('A.mat')
SUMS = cell2mat(cellfun(@(x) MyFcn1(x),A,'UniformOutput',false))
関数1
・cell内のすべてがNaNの場合、NaNで表示
・違う場合は関数2へ移行
function y = MyFcn1(x)
idx = all(isnan(x),'all');
if idx
y = repmat(x,[4 1]);
else
y = MyFcn2(x);
end
end
関数2
・条件分離し合計したものを縦に連結
function y = MyFcn2(x)
idx1 = gradient(x) >= 0;
idx2 = x >= 0;
A = sum(x( idx1 & idx2),'omitnan');
B = sum(x(~idx1 & idx2),'omitnan');
C = sum(x( idx1 &~idx2),'omitnan');
D = sum(x(~idx1 &~idx2),'omitnan');
y = vertcat(A,B,C,D);
end
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!