Intersection of line and curve Matlab - matlab

Well another problem has pop up recently.
I have a set representing a curve and a line I drew with the line() function.
So far my code is :
clc, clear all, close all;
n = 800/1500;
I = [ 0 1.1 4 9.5 15.3 19.5 23.1 26 28.2 30.8 33.3 35.9];
E_up = [ 5.8 10.5 28 60.3 85.5 100.3 108 113.2 117 120.5 123.5 126];
E_up = E_up./n;
Iw = [ 34 31.5 28.2 23.9 19.9 16.1 13 8.1 3.5 1.2 0 NaN];
E_down = [124.6 122.5 118.8 112.2 103.9 93.1 81.6 59.1 29.6 14.5 9.5 NaN];
E_down = E_down./n;
x_est = I;
y_est = spline(Iw,E_down,x_est)
A(:,1)= E_up
A(:,2) = y_est
ma = mean(A,2)
% figure()
% hold all
% % plot(x_est,y_est,'ro')
% plot(I,E_up,'b-',Iw,E_down,'g-')
% plot(I,ma,'r')
% grid on
% legend('up','down','mean')
%dane_znamionowe
clc, clear all, close all;
%data_entry
n = 800/1500;
I = [ 0 1.1 4 9.5 15.3 19.5 23.1 26 28.2 30.8 33.3 35.9];
E_up = [ 5.8 10.5 28 60.3 85.5 100.3 108 113.2 117 120.5 123.5 126];
E_up = E_up./n; %rescalling_EMF
Iw = [ 34 31.5 28.2 23.9 19.9 16.1 13 8.1 3.5 1.2 0 NaN];
E_down = [124.6 122.5 118.8 112.2 103.9 93.1 81.6 59.1 29.6 14.5 9.5 NaN];
E_down = E_down./n; %rescalling_EMF
Un = 220;
In = 28.8;
wn = 1500;
wmax = 3000;
P = 5.5e3;
Rs = 15.8/25;
%interpolation
x_est = I;
y_est = spline(Iw,E_down,x_est);
%mean_values
A(:,1)= E_up;
A(:,2) = y_est;
ma = mean(A,2);
%party_Xd
figure()
[ax,h1,h2] = plotyy(I+30,wn,I,ma,'plot','plot');
set(ax(1),'ylim',[0 3000],'ytick',[1500 3000]);
set(ax(2),'ylim',[0 300],'ytick',[100 200 300]);
hold(ax(1))
hold(ax(2))
%stable_parts
set(ax,'NextPlot','add')
plot(ax(2),I,ma,'b')
plot(ax(2),0,Un,'m*')
i2 = 0:0.01:70;
plot(ax(2),i2,Un-(i2*Rs),'m--')
iin = 0:1:300;
plot(ax(2),In,iin,'g-')
plot(ax(1),i2,wn,'k-','linewidth',8)
plot(ax(1),28.8,1500,'g*')
%loop
p1x = [35 45 55 65];
for ii = 1 :length(p1x)
x11 = p1x(ii);
y11 = 0;
x21 = In;
y21 = wn;
x1 = [35 45 55 65];
y1 = [0 0 0 0];
x2 = [In In In In];
y2 = [wn wn wn wn];
slope = (y21-y11)/(x21-x11);
xLeft = 0;
yLeft = slope * (xLeft - x11) + y11;
xRight = 70;
yRight = slope * (xRight - x11) + y11;
plot(ax(2),x11,0,'r.')
a1 = line([xLeft, xRight], [yLeft, yRight], 'Color', 'c');
x0 = (max(min(x1),min(x2))+min(max(x1),max(x2)))/2;
fun1 = #(x) interp1(x1,y1,x,'linear');
fun2 = #(x) interp1(x2,y2,x,'linear');
difffun = #(x) fun1(x)-fun2(x);
crossing = fzero(difffun,x0); %crossing x coordinate
crossval = fun1(crossing);
end
My graph looks like this which is pretty decent.But I need to find the intersection point of the cyan line and blue curve.

An answer based on my solution to a similar question:
%dummy input
x1=[0 1 2 3];
y1=[1 4 2 0];
x2=[-1 3 4 5];
y2=[-1 2 5 3];
x0 = (max(min(x1),min(x2))+min(max(x1),max(x2)))/2;
fun1 = #(x) interp1(x1,y1,x,'linear','extrap');
fun2 = #(x) interp1(x2,y2,x,'linear','extrap');
difffun = #(x) fun1(x)-fun2(x);
crossing = fzero(difffun,x0); %crossing x coordinate
crossval = fun1(crossing); %substitute either function at crossing point
plot(x1,y1,'b-',x2,y2,'r-',crossing,crossval,'ks');
legend('line1','line2','crossover','location','nw');
after which your crossing point is given by [crossing, crossval].
Result:

Related

matlab system of equations with one unchanging solution ('q')

I am trying to solve a model of 4 equations, where everything is real. It is essentially a pipe branch problem with "1" being upstream of the pump (with some head on it), and "2" and "3" are downstream w/o head. The units are English.
Anyway, I'm just solving the system of 4 equations and 4 unknowns and looking at a plot of head (ha) vs. total flow rate (Q1). Across this space though I only am collecting points in a vertical line, i.e. the head changes but the flowrate doesn't.
I was thinking the problem may be some variables are being held onto, but I treat "ha" the same as "Q1" so that doesn't seem likely... Realistically, this is matching a system curve to a pump curve, and of course that point moves when the system changes (both flowrate and head), so it seems I am doing something wrong....
Here is the script:
clear sol1 sol2 sol3 sol4 S q h
clc; clearvars; close all;
syms Q1 Q2 Q3 ha
D1 = 1.25/12; Z1 = 0; P1 = 62.4*10; A1 = pi*(1/4)*D1*D1; f1 = 0.011; L1 = 50;
D2 = 0.5/12; Z2 = 25; P2 = 0; A2 = pi*(1/4)*D2*D2; f2 = 0.011; L2 = 100; %V2 = Q2 / A2;
D3 = 0.5/12; Z3 = 10; P3 = 0; A3 = pi*(1/4)*D3*D3; f3 = 0.011; L3 = 100; %V3 = Q3 / A3;
gamma = 62.468;
origPumpData = [0 150; 0.4 148; 0.8 145; 1.2 143; 1.6 141; 2 139; 2.4 138; 2.8 136; 3.2 134; 3.6 132; 4 130; 4.4 128; 4.8 127; 5.2 125; 5.6 124; 6 121; 6.4 118; 6.8 117; 7.2 115; 7.6 113; 8 111; 8.4 110; 8.8 108; 9.2 106; 9.6 104; 10 102; 10.4 100; 10.8 98; 11.2 97;
11.6 94; 12.0 93; 12.4 91; 12.8 89; 13.2 87; 13.6 86; 14 84; 14.4 82; 14.8 80; 15.2 78; 15.6 76; 16 74; 16.4 72; 16.6 70];
pumpData(:,1) = origPumpData(:,1)/448.8312;
pumpData(:,2) = origPumpData(:,2);
polyFit = fit(pumpData(:,1),pumpData(:,2),'poly2');
assume(in(Q1,'real') & Q1 > 0.0001 & Q1 < 1 );
assume(in(Q2,'real') & Q2 > 0.0001 & Q2 < 1 );
assume(in(Q3,'real') & Q3 > 0.0001 & Q3 < 1 ) ;
assume(in(ha,'real') & ha > 0.0001 & ha < 1000.0);
eq1 = #(Q1) polyFit.p1*Q1*Q1 + polyFit.p2*Q1 + polyFit.p3;
eq2 = #(P1,Z1,F1,Q1,A1,L1,D1,P2,Z2,F2,Q2,A2,L2,D2) P1/gamma + ((Q1/A1)^2)/64.4 + Z1 - hf(F1,L1,D1,Q1,A1) - hf(F2,L2,D2,Q2,A2) + ha == P2/gamma + ((Q2/A2)^2)/64.4 + Z2;
eq3 = #(P1,Z1,F1,Q1,A1,L1,D1,P3,Z3,F3,Q3,A3,L3,D3) P1/gamma + ((Q1/A1)^2)/64.4 + Z1 - hf(F1,L1,D1,Q1,A1) - hf(F3,L3,D3,Q3,A3) + ha == P3/gamma + ((Q3/A3)^2)/64.4 + Z3;
eq4 = Q1 == Q2 + Q3;
guesses = [0.07116936917086152675558661517184;
0.035125850031368916048762418970837;
0.036043519139492610706824196201003;
303.02361035523126099594683749354];
for i = 1:1:2
disp(i)
disp(Z1)
Z1 = Z1-5
f1 = f1+0.01
f3 = f3 + 0.01
S(i) = vpasolve([eq1(Q1) eq2(P1,Z1,f1,Q1,A1,L1,D1,P2,Z2,f2,Q2,A2,L2,D2) eq3(P1,Z1,f1,Q1,A1,L1,D1,P3,Z3,f3,Q3,A3,L3,D3) eq4], [Q1 Q2 Q3 ha], guesses )
S(i).Q1
S(i).Q2
S(i).Q3
S(i).ha
q(i) = S(i).Q1
h(i) = S(i).ha
guesses = [S(i).Q1 S(i).Q2 S(i).Q3 S(i).ha]'
clear S
end
plot( q, h, '*b');
function hf = hf(f,L,D,Q,A)
hf = f*(L/D)*(1/64.4)*(Q/A)^2;
end
you're solving eq1 == 0(default) and computing Q1, independent of other equations and parameters. that's why you get constant Q1 in every iteration.

Data arrangement in vector

I have the following vector:
Here is the code to produce this vector:
A = [11 115 167 44 51 5 6];
B = [100 1 1 87];
C = [2000 625];
D = [81 623 45 48 6 14 429 456 94];
E = [89];
F = [44 846 998 2035 498 4 68 4 1 89];
G = {A,B,C,D,E,F};
[max_val, idx] = max(cellfun(#numel, G)); % Find max sizes of vectors
% Create vector with zeros filling open matrix space
LeftIndented = zeros(idx,max_val);
for k = 1:numel(G), LeftIndented(k,1:numel(G{k})) = G{k}; end
I would like to have a vector with:
Data to the right (zeros to the left)
Centered data (surrounded with zeros)
(Notice that if data cannot be exactly centered, it is ok if it is off by one vector space to the left)
How can I achieve this?
You can pad each vector with zeros:
A = [11 115 167 44 51 5 6];
B = [100 1 1 87];
C = [2000 625];
D = [81 623 45 48 6 14 429 456 94];
E = [89];
F = [44 846 998 2035 498 4 68 4 1 89];
G = {A,B,C,D,E,F};
[max_val, idx] = max(cellfun(#numel, G)); % Find max sizes of vectors
% Create vector with zeros filling open matrix space
LeftIndented = zeros(idx,max_val);
Centered = zeros(idx,max_val);
RightAligned = zeros(idx,max_val);
for k = 1:numel(G)
LeftIndented(k,1:numel(G{k})) = G{k};
l = length(G{k});
padding = max_val - l;
leftPadding = floor(padding / 2);
Centered(k, :) = [zeros(1, leftPadding), G{k}, zeros(1, padding - leftPadding)];
RightAligned(k, :) = [zeros(1, padding), G{k}];
end
This is equivalent to
A = [11 115 167 44 51 5 6];
B = [100 1 1 87];
C = [2000 625];
D = [81 623 45 48 6 14 429 456 94];
E = [89];
F = [44 846 998 2035 498 4 68 4 1 89];
G = {A,B,C,D,E,F};
[max_val, idx] = max(cellfun(#numel, G)); % Find max sizes of vectors
% Create vector with zeros filling open matrix space
LeftIndented = zeros(idx,max_val);
Centered = zeros(idx,max_val);
RightAligned = zeros(idx,max_val);
for k = 1:numel(G)
LeftIndented(k,1:numel(G{k})) = G{k};
l = length(G{k});
padding = max_val - l;
leftPadding = floor(padding / 2);
Centered(k, 1 + leftPadding:leftPadding + l) = G{k};
RightAligned(k, 1 + padding:end) = G{k};
end
but in the second code the values of the vectors are written into the correct position in a zero vector.
A solution using strjust:
A = [11 115 167 44 51 5 6];
B = [100 1 1 87];
C = [2000 625];
D = [81 623 45 48 6 14 429 456 94];
E = [89];
F = [44 846 998 2035 498 4 68 4 1 89];
G = {A,B,C,D,E,F};
data = [G{:}];
N = cellfun(#numel, G);
M = max(N);
idx = char((N.' >= (1:M))+32);
Le = strjust(idx, 'left');
Ri = strjust(idx, 'right');
Ce = strjust(idx, 'center');
LeftAdjusted = zeros(M, N);
RightAdjusted = zeros(M, N);
Centered = zeros(M, N);
LeftAdjusted(Le.' ~= ' ') = data;
RightAdjusted(Ri.' ~= ' ') = data;
Centered(Ce.' ~= ' ') = data;
LeftAdjusted = LeftAdjusted.';
RightAdjusted = RightAdjusted.';
Centered = Centered.';

2-DCT Image compression matlab

Problem:
I tried implementing Discrete Cosine Transformation compression using matlab.
Input image would a jpg image (Lena) having a size 512 X 512.
There are two stages namely compression and decompression.
Compression and Quantization:
The input image is converted to YCbCr component. Then Y component is taken up
for compression. Further DCT will quantized.
Quantization and Decompression:
The quantized image is undergoes dequantization for decompression.
Issues:
Rectangular boxes are spotted in the decompressed version of the image. Is anything wrong with the code?
For your inference, below are the sample input and output images and followed by the matlab code.
Input image:
Y Component in YCbCr:
Output image:
Code:
clc;
clear all;
close all;
I = imread('lena512.jpg');
figure, imshow(I);
% Y = I;
YCbCr = rgb2ycbcr(I);
figure, imshow(YCbCr);
Y = YCbCr(:,:, 1);
figure, imshow(Y);
[h, w] = size(Y);
r = h/8;
c = w/8;
s = 1;
q50 = [16 11 10 16 24 40 51 61;
12 12 14 19 26 58 60 55;
14 13 16 24 40 57 69 56;
14 17 22 29 51 87 80 62;
18 22 37 56 68 109 103 77;
24 35 55 64 81 104 113 92;
49 64 78 87 103 121 120 101;
72 92 95 98 112 100 103 99];
% COMPRESSION
for i=1:r
e = 1;
for j=1:c
block = Y(s:s+7,e:e+7);
cent = double(block) - 128;
for m=1:8
for n=1:8
if m == 1
u = 1/sqrt(8);
else
u = sqrt(2/8);
end
if n == 1
v = 1/sqrt(8);
else
v = sqrt(2/8);
end
comp = 0;
for x=1:8
for y=1:8
comp = comp + cent(x, y)*(cos((((2*(x-1))+1)*(m-1)*pi)/16))*(cos((((2*(y-1))+1)*(n-1)*pi)/16));
end
end
F(m, n) = v*u*comp;
end
end
for x=1:8
for y=1:8
cq(x, y) = round(F(x, y)/q50(x, y));
end
end
Q(s:s+7,e:e+7) = cq;
e = e + 8;
end
s = s + 8;
end
% % % % % % % % % % % % % % %
% % DECOMPRESSION
% % % % % % %
s = 1;
for i=1:r
e = 1;
for j=1:c
cq = Q(s:s+7,e:e+7);
for x=1:8
for y=1:8
DQ(x, y) = q50(x, y)*cq(x, y);
end
end
for m=1:8
for n=1:8
if m == 1
u = 1/sqrt(8);
else
u = sqrt(2/8);
end
if n == 1
v = 1/sqrt(8);
else
v = sqrt(2/8);
end
comp = 0;
for x=1:8
for y=1:8
comp = comp + u*v*DQ(x, y)*(cos((((2*(x-1))+1)*(m-1)*pi)/16))*(cos((((2*(y-1))+1)*(n-1)*pi)/16));
end
end
bf(m, n) = round(comp)+128;
end
end
Org(s:s+7,e:e+7) = bf;
e = e + 8;
end
s = s + 8;
end
imwrite(Y, 'F:\workouts\phd\jpeg\input.jpg');
imwrite(uint8(Org), 'F:\workouts\phd\jpeg\output.jpg');
return;
Can you suggest me where the error is? It would be helpful.

How to rewrite this Matlab 2014 code with axis-subplots to 2016?

Code which I wrote for Matlab 2014 but which I want to rewrite it to Matlab 2016 such that it becomes more compact, since it is extranous now
hFig3=figure('Units', 'inches');
hax3_b1=axes('Parent', hFig3);
hax3_b2=axes('Parent', hFig3);
hax3_b3=axes('Parent', hFig3);
hax3_b4=axes('Parent', hFig3);
b1=subplot(2,2,1, hax3_b1);
b2=subplot(2,2,2, hax3_b2);
b3=subplot(2,2,3, hax3_b3);
b4=subplot(2,2,4, hax3_b4);
% Example of common expression
set([b1 b2], 'Units', 'inches'); % http://stackoverflow.com/a/39817473/54964
u=0:0.1:1; y=sin(u); C = [0 2 4 6; 8 10 12 14; 16 18 20 22];
imagesc(b1, u, y, C);
hold on;
plot(b2, u');
histogram(b3, u');
histogram(b4, u);
hold off;
drawnow;
Output is ok
OS: Debian 8.5 64 bit
MATLAB: 2014 but want to convert to 2016
You can simply write:
figure('Units','inches');
b1 = subplot(2,2,1);
b2 = subplot(2,2,2);
b3 = subplot(2,2,3);
b4 = subplot(2,2,4);
or preferably, if you want to have an array of the axes:
figure('Units','inches');
b(1) = subplot(2,2,1);
b(2) = subplot(2,2,2);
b(3) = subplot(2,2,3);
b(4) = subplot(2,2,4);
or use a simple for loop:
figure('Units','inches');
b(1:4) = axes;
for k = 1:numel(b)
b(k) = subplot(2,2,k);
end
In any option you choose there is no need for all the axes commands.
Here is all your 'demo' code:
b(1:4) = axes;
for k = 1:numel(b)
b(k) = subplot(2,2,k);
end
set(b(1:2), 'Units', 'inches');
u=0:0.1:1; y=sin(u); C = [0 2 4 6; 8 10 12 14; 16 18 20 22];
imagesc(b(1), u, y, C);
plot(b(2), u');
histogram(b(3), u');
histogram(b(4), u);
There might be no real need also in the figure command, it depends on what do with it.
If you're just looking for shorter you can eliminate most of the stuff at the beginning. You don't need the figure but I keep it as a matter of habit.
fh = figure;
x = 1:4;
b = arrayfun(#(y) subplot(2,2,y), x, 'UniformOutput',0);
b{1}.Units = 'inches';
b{2}.Units = 'inches';
u=0:0.1:1; y=sin(u); C = [0 2 4 6; 8 10 12 14; 16 18 20 22];
imagesc(b{1}, u, y, C);
plot(b{2}, u');
histogram(b{3}, u');
histogram(b{4}, u);

How do I add lines connecting corresponding boxes, that I've drawn on a plot? (MATLAB)

I have a matrix (Data) which looks like this:
(start) (stop) (strand) (gene number)
[ 1 29 1 1]
[ 32 38 1 1]
[ 44 60 1 1]
[ 66 70 0 2]
[ 75 80 0 2]
[ 81 88 0 3]
[ 99 102 0 3]
[ 111 160 0 3]
[ 166 170 1 4]
[ 171 188 1 4]
which I have plotted onto a graph using the first two columns as X positions, and a set Y position. This is the code I have up till now:
if nargin<4, strands = 0; end;
if nargin<3, height = 0.1; end;
if nargin<2, y = 2.1; end;
for k=1:size(cds,1),
xc = [cds(k,1) cds(k,2) cds(k,2) cds(k,1)];
if strands,
if cds(k,3), % minus strand
yc = [y y y-height/2 y-height/2];
c = 'r';
else % plus strand
yc = [y+height/2 y+height/2 y y];
c = 'b';
end
else
yc = [y+height/2 y+height/2 y-height/2 y-height/2];
c = 'b';
end
h(k) = patch(xc,yc,c);
end
What I'm trying to do is add lines underneath each 'box' which corresponds to the gene number (4th collumn of the data matrix). How would I go about doing this with the plot function?
It's not clear from your question how you want the lines to indicate the gene numbers, I assume you want different colors for each type. Here is how I would do it:
cds = [
1 29 1 1
32 38 1 1
44 60 1 1
66 70 0 2
75 80 0 2
81 88 0 3
99 102 0 3
111 160 0 3
166 170 1 4
171 188 1 4
];
strands = 0;
height = 0.1;
y = 2.1;
[g,gIdx,gNum] = unique(cds(:,4));
clr = 'gcmykrb';
for k=1:size(cds,1),
xc = [cds(k,1) cds(k,2) cds(k,2) cds(k,1)];
if strands,
if cds(k,3), % minus strand
yc = [y y y-height/2 y-height/2];
c = 'r';
else % plus strand
yc = [y+height/2 y+height/2 y y];
c = 'b';
end
else
yc = [y+height/2 y+height/2 y-height/2 y-height/2];
c = 'b';
end
h(k) = patch(xc,yc,c);
hLine(k) = line([cds(k,1) cds(k,2)], [y-3*height/4 y-3*height/4], ...
'LineWidth',5, 'Color',clr(gNum(k)));
end
legend(hLine(gIdx), num2str(g), 'Orientation','horizontal')