Finding the total value underneath a 3d line plot - matlab

So I have 3D filled line plots created in MATLAB using the following code:
for k = 1: P
for j = 1: L
X22 = linspace(0,b*1000,N+1);
Y22 = Yijk(j,:,k);
n = length(X22);
Z22 = contact_force(j,:,k);
Xp2 = zeros(2*n,1);
Yp2 = zeros(2*n,1);
Xp2(1:n) = X22;
Xp2(n+1:2*n) = X22(n:-1:1);
Yp2(1:n) = Y22;
Yp2(n+1:2*n) = Y22(n:-1:1);
Zp2(1:n) = 0;
Zp2(n+1:2*n) = Z22(n:-1:1);
figure(100+k);
hold on
fill3(Xp2,Yp2,Zp2,'c');
hold off
title(['Contact force at fraction '...
num2str(-1*((k-P)/P)) ' of base pitch'])
end
end
Which creates the following image :
I want to find what the total value for each blue line is, how would I do this?

Summing the area under the curve:
sumZ = 0;
for k = 1: P
for j = 1: L
X22 = linspace(0,b*1000,N+1);
Y22 = Yijk(j,:,k);
n = length(X22);
Z22 = contact_force(j,:,k);
Xp2 = zeros(2*n,1);
Yp2 = zeros(2*n,1);
Xp2(1:n) = X22;
Xp2(n+1:2*n) = X22(n:-1:1);
Yp2(1:n) = Y22;
Yp2(n+1:2*n) = Y22(n:-1:1);
Zp2(1:n) = 0;
Zp2(n+1:2*n) = Z22(n:-1:1);
sumZ = sumZ+Zp2;
figure(100+k);
hold on
fill3(Xp2,Yp2,Zp2,'c');
hold off
title(['Contact force at fraction '...
num2str(-1*((k-P)/P)) ' of base pitch'])
end
end

Related

Modifying bilinear interpolation matlab code to enlarge an image instead

I am trying to modify this code to enlarge an image instead of shrinking it by when I change the
eliminate the factor line and made shrinking factor= 2 and multiply by s where s is used, I didn't get the right output. Can anyone point me to what I am doing wrong.
Here is the code:
image=imread('b100.jpg');
factor=1.5;
shriking_factor= 1/factor;
[r c d] = size(image);
rn = floor(shriking_factor*r);
cn = floor(shriking_factor*c);
s = shriking_factor;
im_zoom = zeros(rn,cn,d);
for i = 1:rn;
x1 = cast(floor(i/s),'uint16');
x2 = cast(ceil(i/s),'uint32');
if x1 == 0
x1 = 1;
end
x = rem(i/s,1);
for j = 1:cn;
y1 = cast(floor(j/s),'uint32');
y2 = cast(ceil(j/s),'uint16');
if y1 == 0
y1 = 1;
end
ctl = image(x1,y1);
cbl = image(x2,y1);
ctr = image(x1,y2);
cbr = image(x2,y2);
y = rem(j/s,1);
tr = (ctr*y)+(ctl*(1-y));
br = (cbr*y)+(cbl*(1-y));
im_shrink(i,j) = (br*x)+(tr*(1-x));
end
end
image_shrink = cast(im_shrink,'uint8');
imshow(image_shrink)

Extrapolating value from function to a for loop and passing it back to the function

function Test()
a = 2;
b = 1;
c = 0.5;
q = 0.001;
r = 10;
function F = Useful(x) %calculates existing values for x with size 11
eq1 = (1*(0.903*x(2))^(-1))-(0.903*x(1));
eq2 = (1*(0.665*x(3))*(0.903*x(2))^(-1))-0.903*x(4);
eq3 = (1*(0.399*x(5))*(0.903*x(2)))-0.665*x(6);
eq4 = (1*(0.399*x(5))*(0.903*x(2))^2)-0.903*x(7);
eq5 = (1*(0.399*x(5))*(0.903*x(2))^3)-1*x(8);
eq6 = (1*(0.665*x(3))*(0.399*x(5))*(0.903*x(2)))-1*x(9);
eq7 = (1*(0.665*x(3))*(0.399*x(5))*(0.903*x(2))^2)-0.903*x(10);
eq8 = (1*(0.665*x(3))*(0.399*x(5)))-0.903*x(11);
eq9 = x(3)+x(4)+x(9)+x(10)+x(11)-a;
eq10 = x(5)+x(6)+x(7)+x(8)+x(9)+x(10)+x(11)-b;
eq11 = x(2)+x(6)+2*x(7)+3*x(8)+x(9)+2*x(10)-x(1)-x(4)-c;
F = [eq1;eq2;eq3;eq4;eq5;eq6;eq7;eq8; eq9; eq10; eq11];
end
Value(1,1) = 0;
for d = 2:100
x = fsolve(#Useful,x0,options); %Produces the x(1) to x(11) values
Value(1,d) = (x(3)+x(5))*d+Value(1,d-1); %Gives a new value after each iteration
a = a-x(3);
b = b-x(5);
c = c-x(2);
end
function Zdot = rhs(t,z) %z = (e1,e2,e3,e4,e5)
Zdot=zeros(5,1);
Zdot(1) = -1*z(1);
Zdot(2) = 1*z(1);
Zdot(3) = 1*z(1) - 1*z(2)*z(3);
Zdot(4) = 1*1*z(1) - Value(1,100)*H(z(3))*z(4)*z(4);
Zdot(5) = Value(1,100)*H(z(3))*(z(4));
end
function hill = H(x)
hill = q/(q+x^r);
end
[T,Y] = ode15s(#rhs, [0, 120], [1, 0, 1, 0, 0]); %Solve second function with values giving z(1) to z(5)
plot(T,Y(:,5))
end
I'm wondering, is it possible to pass on each Value obtained (Value (1), Value (2)... so on), into "function Zdot" or is only the final value possible to pass on? Essentially is this possible to implement:
function Zdot = rhs(t,z) %z = (e1,e2,e3,e4,e5)
Zdot=zeros(5,1);
Zdot(1) = -1*z(1);
Zdot(2) = 1*z(1);
Zdot(3) = 1*z(1) - 1*z(2)*z(3);
Zdot(4) = 1*1*z(1) - Value(1,d)*H(z(3))*z(4)*z(4);
Zdot(5) = Value(1,d)*H(z(3))*(z(4));
end
Any insights would be much appreciated and I would be extremely grateful. Thank you in advance!

How do I construct those gradient and divergent matrices in MATLAB?

How can I construct the matrices G and D if I have h and w?
Please pay attention that in G there are some 0 rows and in D there are some 0 columns...
Even though i am very late with my solution for this, here it is for anybody wanting to implement it:
function g = gradientMat(w,h)
one = [-ones(w*h,1) ones(w*h,1)];
d = [0 1];
dx = spdiags(one,d,w*h,w*h);
dx(1:h:end,:) = zeros(w,w*h);
d = [0 h];
dy = spdiags(one,d,w*h,w*h);
dy(h*(w-1)+1:end,:) = zeros(h,w*h);
g = [dx;dy];
end
This solution has the advantage to use matlabs sparse diagonal matrices, which allow you to create the gradient matrix for large images and make calculation with these faster.
To obtain the divergence, simpley use:
g = gradientMat(size(image)(1),size(image)(2));
div = (-g')*g;
this is how I did it now, but there must be a more elegant way, right?!
%% construct G
% upper half
firstDiagG = ones(h, 1);
firstDiagG(h) = 0;
firstDiagG = -firstDiagG;
firstDiagG = repmat(firstDiagG,w,1);
% first = diag(firstDiagG);
firstG = spdiags(firstDiagG,0,n,n);
secondDiagG = ones(h, 1);
secondDiagG(h) = 0;
secondDiagG = repmat(secondDiagG,w,1);
% second = diag(secondDiagG);
secondG = spdiags(secondDiagG,0,n,n);
secondG = [zeros(size(secondG,1),1) secondG];
secondG = secondG(:,1:end-1);
upperHalf = firstG + secondG;
% lower half
thirdDiagG = ones(n-h, 1);
thirdDiagG = [thirdDiagG; zeros(h, 1)];
thirdDiagG = -thirdDiagG;
% thirdG = diag(thirdDiagG);
thirdG = spdiags(thirdDiagG,0,n,n);
fourthDiagG = [ones(n-2*h, 1); zeros(n-2*h, 1)];
% fourthG = diag(fourthDiagG);
fourthG = spdiags(fourthDiagG,0,n,n);
fourthG = [zeros(size(fourthG,1), h) fourthG];
fourthG = fourthG(:,1:end-h);
% fourthG = [fourthG zeros(size(fourthG,1),h)];
% fourthG = [fourthG; zeros(size(fourthG,1), size(fourthG,2))];
lowerHalf = thirdG + fourthG;
G = [upperHalf; lowerHalf];
%% construct D
% left half
firstD = firstG; % is the same as in G
secondDiagD = secondDiagG; % is the same as in G
% secondD = diag(secondDiagD);
secondD = spdiags(secondDiagD,0,n,n);
secondD = [zeros(1, size(secondD,1)); secondD];
secondD = secondD(1:end-1,:);
leftHalf = firstD + secondD;
% right half
thrirdDiagD = flip(thirdDiagG);
% thirdD = diag(thrirdDiagD);
thirdD = spdiags(thrirdDiagD,0,n,n);
fourthDiagD = ones(n, 1);
% fourthD = diag(fourthDiagD);
fourthD = spdiags(fourthDiagD,0,n,n);
fourthD = [zeros(h, size(fourthD,1)); fourthD];
fourthD = fourthD(1:end-h,:);
rightHalf = thirdD + fourthD;
D = [leftHalf rightHalf];

Matlab surf only points, not lines

I have to draw a hipsometric map on a 3D plot. I have two vectors 1x401 (named xLabels and yLabels) which are the geo coordinates, and401x401(namedA`) matrix with the altitude data. To plot the data I use:
surf(xLabels, yLabels,A,'EdgeColor','None','Marker','.');
which leads to something like that:
But i would like to have something like that:
On the second image, only the surface is plotted, while my image looks like pillars.
I tried even make my vectors to 401x401 using meshgrid but it did not have any effect.
Do you have any idea what I should change?
#EDIT
I checked for X and Y data. I quess is too small interval (0.0083), but when i try plot good second of upper plots with same interval it draws correctly.
#EDIT2:
sizeX = 4800;
sizeY = 6000;
pixdegree = 0.0083; % 1 pixel is 0.0083 degree on map
intSize = 2;
lon = 37 + (35/60);
lat = 55+ (45/60);
fDEM = 'E020N90';
fHDR = 'E020N90.HDR';
[startXY, endXY] = calcFirstPixel(lon, lat); %calc borders for my area
f = fopen('E020N90.DEM');
offset = (startXY(1,2)*sizeX*intSize)+(startXY(1,1)*intSize);
fseek(f, offset,0); %seek from curr file pos
x = 0;
A = [];
BB = [];
jump = (intSize*sizeX)-(401*2);
while x<401
row = fread(f, 802);
fseek(f, jump, 0); %jump 2 next row
A = [A row];
x = x+1;
end
fclose(f);
A = A';
A = A(:,2:2:802);
m1 = min(A(:)); %wartość minimalna dla naszej podziałki
m2 = max(A(:)); %wartość maksymalna dla naszej podziałki
step = m2/8; % będzie 8 kolorów
highScale = m1:step:m2-step; %wartości graniczne dla każdego z nich
%handles.axes1 = A;
colormap(hObject, jet(8));
startXtick = 20 + pixdegree*startXY(1,1);
endXtick = 20 + pixdegree*endXY(1,1);
startYtick = 90 - pixdegree*endXY(1,2);
endYtick = 90 - pixdegree*startXY(1,2);
[XX,YY] = ndgrid(startXtick:pixdegree:endXtick,startYtick:pixdegree:endYtick);
xLabels = startXtick:pixdegree:endXtick;
yLabels = startYtick:pixdegree:endYtick;
surf(xLabels, yLabels,A,'EdgeColor','None','Marker','.');
set(gca,'YDir','normal');
grid on;
view([45 45])
And .DEM files
function [startXY, endXY] = calcFirstPixel(lon,lat)
global fHDR;
format = '%s %s';
f = fopen(fHDR);
cont = textscan(f, format);
LonStart = str2double(cont{1,2}{11,1});
LatStart = str2double(cont{1,2}{12,1});
diffPerPix = str2double(cont{1,2}{13,1});
fclose(f);
x = LonStart;
countX = 0
y = LatStart;
countY= 0;
while x<lon
x=x+diffPerPix
countX = countX +1;
end
while y>lat
y=y-diffPerPix
countY = countY+1;
end
startXY= [countX-200 countY-200];
endXY = [countX+200 countY+200];
end

Subscripted assignment dimension mismatch in matlab

I executed this code using Feature Matrix 517*11 and Label Matrix 517*1. But once the dimensions of matrices change the code cant be run. How can I fix this?
The error is:
Subscripted assignment dimension mismatch.
in this line :
edges(k,j) = quantlevels(a);
Here is my code:
function [features,weights] = MI(features,labels,Q)
if nargin <3
Q = 12;
end
edges = zeros(size(features,2),Q+1);
for k = 1:size(features,2)
minval = min(features(:,k));
maxval = max(features(:,k));
if minval==maxval
continue;
end
quantlevels = minval:(maxval-minval)/500:maxval;
N = histc(features(:,k),quantlevels);
totsamples = size(features,1);
N_cum = cumsum(N);
edges(k,1) = -Inf;
stepsize = totsamples/Q;
for j = 1:Q-1
a = find(N_cum > j.*stepsize,1);
edges(k,j) = quantlevels(a);
end
edges(k,j+2) = Inf;
end
S = zeros(size(features));
for k = 1:size(S,2)
S(:,k) = quantize(features(:,k),edges(k,:))+1;
end
I = zeros(size(features,2),1);
for k = 1:size(features,2)
I(k) = computeMI(S(:,k),labels,0);
end
[weights,features] = sort(I,'descend');
%% EOF
function [I,M,SP] = computeMI(seq1,seq2,lag)
if nargin <3
lag = 0;
end
if(length(seq1) ~= length(seq2))
error('Input sequences are of different length');
end
lambda1 = max(seq1);
symbol_count1 = zeros(lambda1,1);
for k = 1:lambda1
symbol_count1(k) = sum(seq1 == k);
end
symbol_prob1 = symbol_count1./sum(symbol_count1)+0.000001;
lambda2 = max(seq2);
symbol_count2 = zeros(lambda2,1);
for k = 1:lambda2
symbol_count2(k) = sum(seq2 == k);
end
symbol_prob2 = symbol_count2./sum(symbol_count2)+0.000001;
M = zeros(lambda1,lambda2);
if(lag > 0)
for k = 1:length(seq1)-lag
loc1 = seq1(k);
loc2 = seq2(k+lag);
M(loc1,loc2) = M(loc1,loc2)+1;
end
else
for k = abs(lag)+1:length(seq1)
loc1 = seq1(k);
loc2 = seq2(k+lag);
M(loc1,loc2) = M(loc1,loc2)+1;
end
end
SP = symbol_prob1*symbol_prob2';
M = M./sum(M(:))+0.000001;
I = sum(sum(M.*log2(M./SP)));
function y = quantize(x, q)
x = x(:);
nx = length(x);
nq = length(q);
y = sum(repmat(x,1,nq)>repmat(q,nx,1),2);
I've run the function several times without getting any error.
I've used as input for "seq1" and "seq2" arrays such as 1:10 and 11:20
Possible error might rise in the loops
for k = 1:lambda1
symbol_count1(k) = sum(seq1 == k);
end
if "seq1" and "seq2" are defined as matrices since sum will return an array while
symbol_count1(k)
is expected to be single value.
Another possible error might rise if seq1 and seq2 are not of type integer since they are used as indexes in
M(loc1,loc2) = M(loc1,loc2)+1;
Hope this helps.