How to build up linear functions in MATLAB and plot the?

Hi, I am new in MATLAB and I want to build a code for these linear functions and plot them to use it in my research paper.
The general shape of the linear fuctions are attached.
The idea from these functions that if I have values for example from (0 to 0.04999) in x axis and i substitute them in the first linear function, I want the output to be from (0-0.25) ...
in the second linear function the input from (0.05 to 0.24999) so the output that I want to be are (0.3 - 0.55).
in the third linear function the input from (0.25 to 0.6) so the output that I want to be are (0.6 - 1).
I dont intrest in exact value of the slope at this stage, I just want general functions to achieve what i want.
Thanks in advance

Answers (3)

The lilnes are easy enough to plot —
xm = [0 0.04999; 0.05 0.24999; 0.25 0.6];
ym = [0 0.25; 0.3 0.55; 0.6 1];
for k = 1:size(xm,1)
B(:,k) = [xm(k,:); 1 1].' \ ym(k,:).'; % Slopes & Intercepts
end
figure
hold on
for k = 1:size(xm,1)
plot(xm(k,:), ym(k,:), '-k')
end
hold off
What do you want to do with them after that?
.

21 Comments

M
M on 3 Aug 2022
Edited: M on 3 Aug 2022
@Star Strider, thanks but I want the functions itself to substitute any number on it not plot the numbers only! and then plot the functions..
I mean i need those three functions
I am still not certain what you want.
To get one line with a slope common to all the points listed:
xm = [0 0.04999; 0.05 0.24999; 0.25 0.6];
ym = [0 0.25; 0.3 0.55; 0.6 1];
[xq,ix] = sort(xm(:));
yq = ym(ix);
DM = [xq ones(size(xq))];
B = DM \ yq % [Slope; Intercept]
B = 2×1
1.5000 0.1500
yi = DM * B;
figure
plot(xq, yi, '.-')
grid
.
@Star Strider, I was wrong when I said to you that the three function should have the same slop.. sorry.
How can I change the slop for each function Please?
M
M on 3 Aug 2022
Edited: M on 3 Aug 2022
@Star Strider, I want to use these functions in fuzzy logic problem .. thanks
@Star Strider, Now just all want I want the three functions with different slops..
In my original Answer, the first row of the ‘B’ matrix are the sloopes of the individual line segments. You can change that to any values you want.
To calculate the resulting lines, and using my original code (and slopes) as a starting point:
xm = [0 0.04999; 0.05 0.24999; 0.25 0.6];
ym = [0 0.25; 0.3 0.55; 0.6 1];
for k = 1:size(xm,1)
B(:,k) = [xm(k,:); 1 1].' \ ym(k,:).'; % Slopes & Intercepts
end
B
B = 2×3
5.0010 1.2501 1.1429 0 0.2375 0.3143
figure
hold on
for k = 1:size(xm,1)
plot(xm(k,:), [xm(k,:); 1 1].'*B(:,k), '-k')
end
hold off
So if you want to change the slopes to something else (here numbers generated by the rand function:
B(1,:) = rand(size(B(1,:)))
B = 2×3
0.5312 0.9381 0.2751 0 0.2375 0.3143
figure
hold on
for k = 1:size(xm,1)
plot(xm(k,:), [xm(k,:); 1 1].'*B(:,k), '-k')
end
hold off
This simply demonstrates how to set the slopes. They can be anything you want.
.
@Star Strider,thank you, but i didn't get where is the functions so I can substitute any number on it!
I am not certain how to define a function for that.
Try this —
xm = [0 0.04999; 0.05 0.24999; 0.25 0.6];
ym = [0 0.25; 0.3 0.55; 0.6 1];
for k = 1:size(xm,1)
B(:,k) = [xm(k,:); 1 1].' \ ym(k,:).'; % Slopes & Intercepts
end
B
B = 2×3
5.0010 1.2501 1.1429 0 0.2375 0.3143
figure
hold on
for k = 1:size(xm,1)
plot(xm(k,:), [xm(k,:); 1 1].'*B(:,k), '-k')
end
hold off
NewSlopes = [5.2 3.4 0.6]; % Define Slopes Vector
B(1,:) = NewSlopes % Assign Slopes Vector To Create New Linear Functions
B = 2×3
5.2000 3.4000 0.6000 0 0.2375 0.3143
figure
hold on
for k = 1:size(xm,1)
plot(xm(k,:), [xm(k,:); 1 1].'*B(:,k), '-k')
end
hold off
.
@Star Strider sorry for bothering, but you didnt get me well.
I mean for example if there is input value (x value) 0.12 and i want to see it's output (y value), it's output should be in the second function range.
so I have to substitute in a certain function, where is that function?
@M, do you want to exploit the curve-fitting toolbox to generate the line functions for you?
There are formulas to determine the parameters of the line: (1) slope and (2) y-intercept, between two points.
That requirement is cedrtainly not obvious from the previous descriptions!
Try this —
xm = [0 0.04999; 0.05 0.24999; 0.25 0.6];
ym = [0 0.25; 0.3 0.55; 0.6 1];
for k = 1:size(xm,1)
B(:,k) = [xm(k,:); 1 1].' \ ym(k,:).'; % Slopes & Intercepts
end
xq = 0.12; % Supplied Value For 'x'
xm_row = @(x) find(xm(:,1) <= x & xm(:,2) >= x); % Function To Determine Segment Membership
Check = xm_row(xq) % Check Result
Check = 2
yq = [xq 1] * B(:,xm_row(xq)) % Call Function & Find 'y'
yq = 0.3875
figure
hold on
for k = 1:size(xm,1)
plot(xm(k,:), [xm(k,:); 1 1].'*B(:,k), '-', 'DisplayName',sprintf('Segment %d',k))
end
plot(xq,yq,'rs', 'DisplayName','(xq,yq)')
hold off
legend('Location','best')
That seems to meet the current requirements. (It would not work if ‘x’ (or ‘xq’) is not within any of those limits.)
.
Actually, @Star Strider has computed the parameters needed to construct the line functions:
xm = [0 0.04999; 0.05 0.24999; 0.25 0.6];
ym = [0 0.25; 0.3 0.55; 0.6 1];
for k = 1:size(xm,1)
B(:,k) = [xm(k,:); 1 1].' \ ym(k,:).'; % Slopes & Intercepts
end
m = B(1, 1:3) % Slopes
m = 1×3
5.0010 1.2501 1.1429
c = B(2, 1:3) % Intercepts
c = 1×3
0 0.2375 0.3143
Having that you just need to write the line functions, where you may want to use them in your Fuzzy Logic System
x1 = linspace(xm(1), xm(2), 101);
x2 = linspace(xm(3), xm(4), 101);
x3 = linspace(xm(5), xm(6), 101);
y1 = m(1)*x1 + c(1); % line #1: y = 5.0010*x
y2 = m(2)*x2 + c(2); % line #2: y = 1.2501*x + 0.2375
y3 = m(3)*x3 + c(3); % line #3: y = 1.1429*x + 0.3143
plot(x1, y1, x2, y2, x3, y3)
M
M on 3 Aug 2022
Edited: M on 3 Aug 2022
@Sam Chak, this is what I want exactly ... now do you know how can I make these as memebrship functions? general membership functions not specifically to use it in Sugeno..
I mean I have many values and I want to substitute them in these functions and save their outputs.. can you help plesae in this? Thanks
@M — Please see my previous Comment as well.
I believe it demonstrates that.
M
M on 3 Aug 2022
Edited: M on 3 Aug 2022
@Star Strider yes thanks. I didnt notice that.
can you help me in formulating for loop for "xq" .. to substitute all values that I have please and save their outputs?
"... I have many values and I want to substitute them in these functions and see save their outputs.."
Show us why what I gave you to begin with will not let you do precisely that...I showed you precisely that result as the first plot where the vector yh was computed from a whole bunch of x values; the x can be totally arbitrary in number and value (although they ought to be within the range of the defined breakpoints range, obviously).
Illustrate again --
>> yNew=fnY(pi/10) % save a new single value at some arbitrary point, x
yNew =
0.6733
>>
or, with a vector of points...
>> xvals=rescale(rand(1,7),0,0.6) % 7 random points between 0 and 0.6
xvals =
0 0.6000 0.4549 0.5091 0.2921 0.4800 0.0824
>> yvals=fnY(xvals) % and the function values to go with 'em...
yvals =
0 1.0000 0.8341 0.8961 0.6481 0.8629 0.3405
>>
and just to show that they satisfy the criteria we'll put 'em on that original figure yet again...
>> plot(xvals,yvals,'or')
which again shows they all are identically on the given line segments as defined...
You've yet to show us why this won't work for you.
I do not know what other values you have, so I created some — .
xm = [0 0.04999; 0.05 0.24999; 0.25 0.6];
ym = [0 0.25; 0.3 0.55; 0.6 1];
for k = 1:size(xm,1)
B(:,k) = [xm(k,:); 1 1].' \ ym(k,:).'; % Slopes & Intercepts
end
xq = [0.12 rand(1,9)*0.6]; % Supplied Values For 'x'
for k = 1:numel(xq)
xm_row = @(x) find(xm(:,1) <= x & xm(:,2) >= x); % Function To Determine Segment Membership
yq(k) = [xq(k) 1] * B(:,xm_row(xq(k))); % Call Function & Find 'y'
end
Points = [xq; yq]
Points = 2×10
0.1200 0.1433 0.5412 0.4145 0.2087 0.4961 0.3901 0.5859 0.0221 0.4086 0.3875 0.4166 0.9328 0.7880 0.4983 0.8813 0.7601 0.9839 0.1103 0.7813
figure
hold on
for k = 1:size(xm,1)
plot(xm(k,:), [xm(k,:); 1 1].'*B(:,k), '-', 'DisplayName',sprintf('Segment %d',k))
end
plot(xq,yq,'rs', 'DisplayName','(xq,yq)')
hold off
legend('Location','best')
The points are random, however they all appear to plot correctly.
.
Just one small nit -- the above using OP's segment definitions leaves a small but finite region of distance 1E-5 undefined -- that's the primary reason I went with the interp1 route and set the breakpoints as -eps(bkptValue) less than the beginning of the next segment. Then there's no explicit comparison to fail and the discontinuity won't show up until actually hits the beginning of the next segment.
I agree, however it’s the way OP framed the problem, so I kept with it.
Understand; pointing out for OP's benefit...

Sign in to comment.

% the lookup table/interpolant function...
y=[0 0.25 0.30 0.55 0.6 1];
x=[0 0.05-eps(0.05) 0.05 0.25-eps(0.25) 0.25 0.6];
% let's use it...
xh=[0:0.01:0.6]; % sample points to evaluate
yh=interp1(x,y,xh); % functional values
plot(xh,yh,'x') % see what it looks like...
results in
plot() by default would draw the line between the breakpoints; hence the markers only here to illustrate...

8 Comments

M
M on 3 Aug 2022
Edited: M on 3 Aug 2022
@dpb, thanks but I want the functions itself to substitute any number on it not plot the numbers only! and then plot the functions..
I mean i need those three functions
You can evaluate the function at any single point you need -- and do anything you want with the result.
I just plotted the results to show you what the above gives over the range of values of the independent variable -- that doesn't prohibit you from using it as desired -- you can encapsulate it as an anonymous function
What, specifically, do you need with the functions that can't be done evaluating one expression instead? Show us a place in your code the above won't work to accomplish the objective.
>> fnY=@(v)interp1(x,y,v); % an anonymous function to use
>> y=fnY(pi/10) % an arbitrary point selected
y =
0.6733
>> hold on
>> plot(pi/10,y,'or') % show it on top of previous plot
>> xh=[0 x(2)]; % the range of the function first breakpoint
>> plot(xh,fnY(xh),'g-') % show it in full over that range, too...
>>
What, specifically, that you need doesn't that let you do?
@M, guess you want three generic line functions () where you can later use them in your Takagi Sugeno fuzzy system.
@Sam Chak Exactly .. how to do that??
Do what, specifically?
Why can't you pass/use the function I defined? Have you even tried it?
Show us code that you've tried and that doesn't function; don't just complain.
Alternatively, you could do something like
>> bkpt=reshape(x,2,[]).'
bkpt =
0 0.0500
0.0500 0.2500
0.2500 0.6000
>> resp=reshape(y,2,[]).'
resp =
0 0.2500
0.3000 0.5500
0.6000 1.0000
>> b=arrayfun(@(i)polyfit(bkpt(i,:),resp(i,:),1),1:size(bkpt,1),'UniformOutput',0);
>> for i=1:numel(b)
fnY(i)={@(x)polyval(b{i},x)};
end
>> whos fnY
Name Size Bytes Class Attributes
fnY 1x3 408 cell
>> fnY{3}(pi/10)
ans =
0.6733
>>
gives a handle array of the three line segments defined above that could be passed as separate array elemnts but it's not clear what advantage this has over simply using the one global function wherever it is needed.
I'll 'fess that I don't have and have never used the fuzzy logic TB so there may be something I'm missing, but we would need to see why that solution doesn't work to figure out what might do instead or to correct whatever is wrong with it (or in your use thereof).
Hi @dpb.. sorry I have just tried your code...
all the codes here give the same answer.
The lookup table aspects of @doc:interp1 can be extremely handy tool for shortening user code such as here -- using it for reverse lookup is also something not to be overlooked.
The only disadvantage here I can see is that one does, indeed, have to use values within each segment only to draw a continuous line segment that will show the discontinuity without a line segment drawn between sections. But, the other solutions also all have to have some other way to handle it that is at least as much code/logic as would be using the segment breakpoints in a loop similarly as to @Star Strider
xq = [0.12 rand(1,9)*0.6]; % Supplied Values For 'x'
yq=fnY(xq); % 'y'
Points = [xq; yq]
figure
hold on
xm=reshape(x,2,[]).'; % convert to S-S's variable from mine
for k = 1:size(xm,1)
plot(xm(k,:), fnY(xm(k,:)), '-', 'DisplayName',sprintf('Segment %d',k))
end
plot(xq,yq,'rs', 'DisplayName','(xq,yq)')
hold off
legend('Location','best')
gives
which is same plot with slightly different set of randomized xq,yq points...I was just too lazy to go to the extra trouble so just dumped the points out to simulate the lines.

Sign in to comment.

Categories

Find more on Parallel Computing in Help Center and File Exchange

Asked:

M
M
on 3 Aug 2022

Edited:

dpb
on 4 Aug 2022

Community Treasure Hunt

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

Start Hunting!