How to use interp1 command?
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示

I have the code to draw each of these 6 figures as follows:
ph1 = 1;
ph2 = 2;
ph3 = 3;
ph4 = 4;
ph5 = 5;
ph6 = 6;
Vi=30;
Vo=0:0.1:30;
d= Vo./Vi ;
m1= d*ph1;
m2= d*ph2;
m3= d*ph3;
m4= d*ph4;
m5= d*ph5;
m6= d*ph6;
floor1= floor(m1);
floor2= floor(m2);
floor3= floor(m3);
floor4= floor(m4);
floor5= floor(m5);
floor6= floor(m6);
Kcm1 = (1-(floor1./(ph1*d))).*(1+floor1-ph1*d)
Kcm2 = (1-(floor2./(ph2*d))).*(1+floor2-ph2*d)
Kcm3 = (1-(floor3./(ph3*d))).*(1+floor3-ph3*d)
Kcm4 = (1-(floor4./(ph4*d))).*(1+floor4-ph4*d)
Kcm5 = (1-(floor5./(ph5*d))).*(1+floor5-ph5*d)
Kcm6 = (1-(floor6./(ph6*d))).*(1+floor6-ph6*d)
figure (1)
hold on
title('for the output current ripple')
xlabel('Duty Cycle')
ylabel('Kcm')
plot(d,Kcm1)
plot(d,Kcm2)
plot(d,Kcm3)
plot(d,Kcm4)
plot(d,Kcm5)
plot(d,Kcm6)
legend('Phase1','Phase2','Phase3','Phase4','Phase5','Phase6');
grid on
hold off
What I want to do is that based on an input value (which is going to be a value on the X-axis), I want the output to choose the figures out of these 6 figures that give the minimum Y-axis value.
For example,
If I put the input value to be 0.5, which is a duty cycle value on the X-axis, then the output should display and recommend (phase-2, phase-4 and figure 6) as they give the minimum value of Y-axis (exactly 0) at this specific input value of 0.5
Another example,
If the input value is 0.25, then the recommend figure to be displayed is (phase-4 the yellow one) as this also gives the minimum value on the Y-axis, and so on.
I was told that I could use the "interp1" command for each curve and pick the minimum but I don't know how to use it.
Please help me out?
1 件のコメント
採用された回答
Numbering your variables like that is a red-herring that makes this task more complex.
MATLAB is designed to work efficiently with arrays. Using arrays makes your code much simpler:
ph = 1:6;
Vi = 30;
Vo = 0:0.1:30;
d = Vo./Vi;
m = d(:).*ph; % note the orientation!
Kcm = (1-(floor(m)./m)).*(1+floor(m)-m);
figure (1)
title('for the output current ripple')
xlabel('Duty Cycle')
ylabel('Kcm')
plot(d,Kcm)
legend(sprintfc('Phase%d',ph));
grid on

Using arrays also makes your task much simpler:
inp = 0.5;
tmp = interp1(d,Kcm,inp);
idx = find(tmp==min(tmp))
idx = 1×3
2 4 6
inp = 0.75;
tmp = interp1(d,Kcm,inp);
idx = find(tmp==min(tmp))
idx = 4
Note that the orientation of the data in m is significant, because INTERP1 treats each column as its own dataset.
12 件のコメント
Mohammed Alharbi
2021 年 9 月 27 日
Thanks you so much Stephen. That was very helpful!
Mohammed Alharbi
2021 年 9 月 27 日
編集済み: Mohammed Alharbi
2021 年 9 月 27 日
Hi Stephen,
why would I get only one "idx" for some cases when two different "idx" are expected. for example for inp = 0.6667, idx should be 6 and 3 as both of them will give a minumim value of 0 as per the graph, but I am only getting the result for 6
inp = 0.6667;
tmp = interp1(d,Kcm,inp);
idx = find(tmp==min(tmp))
idx =
6
I was wondering if you would ask about this.
The answer is that those values are actually different, due to the accumulated floating point error.
Lets have a look:
ph = 1:6;
Vi = 30;
Vo = 0:0.1:30;
d = Vo./Vi;
m = d(:).*ph; % note the orientation!
Kcm = (1-(floor(m)./m)).*(1+floor(m)-m);
inp = 0.6667;
tmp = interp1(d,Kcm,inp)
tmp = 1×6
0.3333 0.1667 0.0000 0.0833 0.0667 0.0000
fprintf('%.40f\n',tmp([3,6])) % clearly not the same!
0.0000492537313432778867247283094421561600
0.0000487562189054669805677623417583532728
In you want, you could compare the absolute difference against a tolerance:
tol = 1e-5; % pick this value to suit YOUR definition of how different values can be.
idx = find(abs(tmp-min(tmp))<tol)
idx = 1×2
3 6
Read more about binary floating point numbers:
This is worth reading as well:
Mohammed Alharbi
2021 年 9 月 27 日
Super!
I can't thank you enogh Stephen. Thanks for your time and the info
Mohammed
Mohammed Alharbi
2021 年 9 月 27 日
Hi Stephen,
Sorry to keep bothering you with my questions and I really appreciate it. Just last question:
is there a way I can plot "ph against d" using the minimum data of Kcm of all the different Ph variables.

for example according to the graph above, when d is from 0 to 0.183, 6-phase should be selected as this will give the minimum values of Kcm, then from around 0.184 up to 0.224, 5-phase will be slected, and so on. in some cases, as discussed, for example when d=0.5, then we can select 2-phase, or 4-phase or 6-phase.
A similar graph of how I want it is shown in the bottom graph below comparing phase-3 and phase-4 to get the lowest value of Y-axis of the other graph

Stephen23
2021 年 9 月 27 日
Perhaps something like this will get you started:
ph = 1:6;
Vi = 30;
Vo = 0:0.1:30;
d = Vo./Vi;
m = d(:).*ph; % note the orientation!
Kcm = (1-(floor(m)./m)).*(1+floor(m)-m);
% new code:
X = Kcm==min(Kcm,[],2);
Y = 7-sum(cumsum(X,2)>0,2);
plot(d,Y)

Mohammed Alharbi
2021 年 9 月 28 日
編集済み: Mohammed Alharbi
2021 年 9 月 28 日
YOU ARE GENOIUS!
Thanks a lot mate!
is just that I am thinking of a way how I can represent that for some duty cycles values like for example when D=0.5, then Phase-2, Phase-4, and Phase-6, can all give the lowest Kcm value. The above figure shows only the selction of phase-2 for this case. would it be possible to overlap it with other figures likewise the orignal figure?
Thanks again!
Mohammed
Stephen23
2021 年 9 月 28 日
"how I can represent that for some duty cycles values like for example when D=0.5, then Phase-2, Phase-4, and Phase-6, can all give the lowest Kcm value. "
That is a bit more tricky because there are varying numbers of possible results. Some possible approaches:
- use a loop, calculate and plot each duty-cycle separately.
- use a scatter plot, for example:
ph = 1:6;
Vi = 30;
Vo = 0:0.01:30; % <- smaller step!
d = Vo./Vi;
m = d(:).*ph; % note the orientation!
Kcm = (1-(floor(m)./m)).*(1+floor(m)-m);
% new code:
tol = 1e-5; % pick this value to suit your needs.
idx = abs(Kcm-min(Kcm,[],2))<tol;
[idr,idc] = find(idx);
scatter(d(idr),ph(idc),'.')

Mohammed Alharbi
2021 年 10 月 3 日
Hi Stephen,
When I am using the MATLAB Function in Simulink I get the below error:

Althoug I predfined the dimensions of what the output is going to be, as follows:
function [PWM_signals,phase_delay,Num_phases] = PWM_FCN(vin,vout,ref) %inputs: referance current and sensed current in each phase
Num_phases = zeros(3,1);
phase_delay = zeros(6,1); %output phase shift
x=0;
ph=zeros(1,6);
tmp=zeros(1,6);
d=zeros(1,1001);
m=zeros(1001,6);
Kcm=zeros(1001,6);
Vo=zeros(1,1001);
tol=0;
ph = 1:6;
Vi = 1;
Vo = 0:0.001:1;
d = Vo./Vi;
m = d(:).*ph; % note the orientation!
Kcm = (1-(floor(m)./m)).*(1+floor(m)-m);
tol = 1e-2;
inp = vout/vin;
tmp = interp1(d,Kcm,inp);
Num_phases = find(abs(tmp-min(tmp))<tol);
PWM_signals = zeros(6,1); %output state 1 or 0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Chose the phases according to the refernce current:
if (ref > 200 && ref <= 240)
x=6;
elseif (ref > 165 && ref <= 200)
x=5;
elseif (ref > 130 && ref <= 165)
x=4;
elseif (ref > 90 && ref <= 130)
x=3;
elseif (ref > 0 && ref <= 90)
x=2;
elseif ref==0
x=0;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for 6 phases
%%%%%%%%%%%%%%5%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if x==6 || max(Num_phases)==6 && x >=3 % for very high current switch on all phases, Or switch the 6 phases if the current ripple is excellent to switch 6 phases yet the current should not be very low
PWM_signals = ones (6,1); % all phases are 1s
phase_delay(1) =0 ; phase_delay(2) =60*((1/100e3)/360) ; phase_delay(3) =120*((1/100e3)/360) ; phase_delay(4) =180*((1/100e3)/360) ; phase_delay(5) =240*((1/100e3)/360) ; phase_delay(6) =300*((1/100e3)/360) ;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for 5 phases
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (x > 2 && x <= 5) && (max(Num_phases) ==5) || (x == 5) && (max(Num_phases) < 5 ) % if the current is to hight to handel less the number of phases, then always swithc 5 phases
PWM_signals(1) =1 ; PWM_signals(2) =1 ; PWM_signals(3) =1 ; PWM_signals(4) =1 ; PWM_signals(5) =1 ; PWM_signals(6) =0 ; %then switch ON all the first 5 phases and switch OFF the last phase
phase_delay(1) =0 ; phase_delay(2) =72*((1/100e3)/360) ; phase_delay(3) =144*((1/100e3)/360) ; phase_delay(4) =216*((1/100e3)/360) ; phase_delay(5) =288*((1/100e3)/360) ; phase_delay(6) =0 ;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for 4 phases
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ((x > 2 && x <= 4) && (max(Num_phases) ==4 || sum(Num_phases)/3 ==4 )) || ((x == 4) && (max(Num_phases) < 4 )) % if the
PWM_signals(1) =1 ; PWM_signals(2) =1 ; PWM_signals(3) =1 ; PWM_signals(4) =1 ; PWM_signals(5) =0 ; PWM_signals(6) =0 ;
phase_delay(1) =0 ; phase_delay(2) =90*((1/100e3)/360) ; phase_delay(3) =180*((1/100e3)/360) ; phase_delay(4) =270*((1/100e3)/360) ; phase_delay(5) =0 ; phase_delay(6) =0 ;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for 3 phases
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (x > 0 && x <= 3) && (sum(Num_phases)/3 ==3) || (x == 3) && (max(Num_phases) < 3 )
PWM_signals(1) =1 ; PWM_signals(2) =1 ; PWM_signals(3) =1 ; PWM_signals(4) =0 ; PWM_signals(5) =0 ; PWM_signals(6) =0 ; phase_delay(1) =0 ; phase_delay(2) =120*((1/100e3)/360) ; phase_delay(3) =240*((1/100e3)/360) ; phase_delay(4) =0 ; phase_delay(5) =0 ; phase_delay(6) =0 ;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for 2 phases
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (x > 0 && x <= 2) && (sum(Num_phases)/6 == 2 || max(Num_phases) >= 4) % 2+4+6=12/2=2
PWM_signals(1) =1 ; PWM_signals(2) =1 ; PWM_signals(3) =0 ; PWM_signals(4) =0 ; PWM_signals(5) =0 ; PWM_signals(6) =0 ;
phase_delay(1) =0 ; phase_delay(2) =180*((1/100e3)/360) ; phase_delay(3) =0 ; phase_delay(4) =0 ; phase_delay(5) =0 ; phase_delay(6) =0 ;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for 0 phases
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ref == 0
PWM_signals = zeros (6,1);
phase_delay(1) =0 ; phase_delay(2) =0; phase_delay(3) =0; phase_delay(4) =0; phase_delay(5) =0 ; phase_delay(6) =0 ;
end
I removed the function and includded the inputs variables (vin,vout,ref) and put them all in a normal m.file and I don't get any error and get exactly what I want.
So can you please let me know what is the issue?
I am including both the Simulink file and the m.file
thanks
Stephen23
2021 年 10 月 4 日
@Mohammed Alharbi: you should ask this in a new thread.
Mohammed Alharbi
2021 年 10 月 4 日
Hi Stephen,
Thanks for your response.
I already did but still waiting for a help and the thought of asking you here. This is the link for the new post:
https://uk.mathworks.com/matlabcentral/answers/1465904-matlab-function-simulink-simulink-does-not-have-enough-information-to-determine-output-sizes-for-th?s_tid=srchtitle
Thanks a lot!
Mohammed Alharbi
2021 年 10 月 4 日
編集済み: Mohammed Alharbi
2021 年 10 月 4 日
Hi Stephen,
I sloved the previous issue by putting
m = d'*ph;
instead of:
m = d(:).*ph;
But now I have another issue with using the "find" command in Simulink function block as it always returns a variable-length vector. Please have a look at this thread if you have time, I am sure you will be the one who can hlep me out with this
Thannks in advance!
Mohammed
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Creating, Deleting, and Querying Graphics Objects についてさらに検索
タグ
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- 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)
