NaN values from griddata (octave) - octave

I generated some scattered data and want to interpolate them to a grid.
I tried to plot the convex hull (because of the description of problems from other users) but also only getting error.
R = 2;
r = 7;
alpha_degree = 90;
alpha_rad = alpha_degree*pi/180;
theta = linspace(0,2*pi,100);
phi = linspace(0,pi,100);
[Phi,Theta] = meshgrid(phi,theta);
x = r.*sin(Theta);
y = (R+r.*cos(Theta)).*cos(Phi);
z = (R+r.*cos(Theta)).*sin(Phi);
z(z<0) = NaN;
x_rot = x.*cos(alpha_rad) - y.*sin(alpha_rad);
y_rot = y.*cos(alpha_rad) + x.*sin(alpha_rad);
z_rot = z;
[xx,yy] = meshgrid(linspace(-5,5));
zz = griddata(x_rot,y_rot,z_rot,xx,yy);
Sorry, here are more details:
I want to have a cap of a torus, therefore I have to set the negative values to NaN with z(z<0)=NaN.
After rotation the values are as expected, I have a rotated cap.
But when I use griddata to interpolate to a regular grid, nearly every points were set to NaN ( there are only a few Points in the corners).
I don´t understand why there are so many values set to NaN by using gridata.
(Because I´m new here I can´t post images, sorry)

I'm not sure what you were xpecting: With z(z<0) = NaN you set roughly half of all entries to NaN, and after your rotation and resampling with gridddata again about half of your entries are NaN as they should be!

Related

Surfaces with different colormaps

How can multiple surfaces be plotted on the axes but surfaces uses a different colormap?.
Using colormap("...") changes it for the entire figure, not just a single surface.
Thanks
Do You mean on same axes?
I haven't found a function that does this directly. But it is possible to pass the desired colors in the surf function.
Way I found:
Convert the data to a 0-1 scale and then convert to the desired colormap.
Example with hot and jet colormaps:
tx = ty = linspace (-8, 8, 41)';
[xx, yy] = meshgrid (tx, ty);
r = sqrt (xx .^ 2 + yy .^ 2) + eps;
tz = sin (r) ./ r ;
function normalized = normalize_01(data)
data_min = min(min(data))
data_max = max(max(data))
normalized = (data - data_min)/(data_max - data_min)
endfunction
function rgb = data2rgb(data, color_bits, cmap)
grays = normalize_01(data)
indexes = gray2ind(grays, color_bits)
rgb = ind2rgb(indexes, cmap)
endfunction
color_bits = 128
cmap_1 = hot(color_bits)
rgb_1 = data2rgb(tz, color_bits, cmap_1)
surf(tx, ty, tz, rgb_1)
hold on
cmap_2 = jet(color_bits)
rgb_2 = data2rgb(tz+3, color_bits, cmap_2)
surf(tx, ty, tz+3, rgb_2)
But if you also need a colorbar, this way might not be useful. Unless you find a way to manually add two colorbar like I did with the cmap.

Is there a limit in the number of degrees of freedom with the lm_feasible algorithm? If so, what is the limit?

I am developing a finite element software that minimizes the energy of a mechanical structure. Using octave and its optim package, I run into a strange issue: The lm_feasible algorithm doesn't calculate at all when I use more than 300 degrees of freedom (DoF). Another algorithm (sqp) performs the calculation but doesn't work well when I complexify the structure and are out of my test case.
Is there a limit in the number of DoF with lm_feasible algorithm?
If so, how many DoF are maximally possible?
To give an overview and general idea of how the code works:
[x,y] = geometryGenerator()
U = zeros(lenght(x)*2,1);
U(1:2:end-1) = x;
U(2:2:end) = y;
%Non geometric argument are not optimised, and fixed during calculation
fct =#(U)complexFunctionOfEnergyIWrap(U(1:2:end-1),U(2:2:end), variousMaterialPropertiesAndOtherArgs)
para = optimset("f_equc_idx",contEq,"lb",lb,"ub",ub,"objf_grad",dEne,"objf_hessian",d2Ene,"MaxIter",1000);
[U,eneFinale,cvg,outp] = nonlin_min(fct,U,para)
Full example:
clear
pkg load optim
function [x,y] = geometryGenerator(r,elts = 100)
teta = linspace(0,pi,elts = 100);
x = r * cos(teta);
y = r * sin(teta);
endfunction
function ene = complexFunctionOfEnergyIWrap (x,y,E,P, X,Y)
ene = 0;
for i = 1:length(x)-1
ene += E*(x(i)/X(i))^4+ E*(y(i)/Y(i))^4- P *(x(i)^2+(x(i+1)^2)-x(i)*x(i+1))*abs(y(i)-y(i+1));
endfor
endfunction
[x,y] = geometryGenerator(5,100)
%Little distance from axis to avoid division by zero
x +=1e-6;
y +=1e-6;
%Saving initial geometry
X = x;
Y = y;
%Vectorisation of the function
%% Initial vector
U = zeros(length(x)*2,1);
U(1:2:end-1) = linspace(min(x),max(x),length(x));
U(2:2:end) = linspace(min(y),max(y),length(y));
%%Constraints
Aeq = zeros(3,length(U));
%%% Blocked bottom
Aeq(1,1) = 1;
Aeq(2,2) = 1;
%%% Sliding top
Aeq(3,end-1) = 1;
%%%Initial condition
beq = zeros(3,1);
beq(1) = U(1);
beq(2) = U(2);
beq(3) = U(end-1);
contEq = #(U) Aeq * U - beq;
%Parameter
Mat = 0.2e9;
pressure = 50;
%% Vectorized function. Non geometric argument are not optimised, and fixed during calculation
fct =#(U)complexFunctionOfEnergyIWrap(U(1:2:end-1),U(2:2:end), Mat, pressure, X, Y)
para = optimset("Algorithm","lm_feasible","f_equc_idx",contEq,"MaxIter",1000);
[U,eneFinale,cvg,outp] = nonlin_min(fct,U,para)
xFinal = U(1:2:end-1);
yFinal = U(2:2:end);
plot(x,y,';Initial geo;',xFinal,yFinal,'--x;Final geo;')
Finite Element Method is typically formulated as the optimal criteria for the minimization problem, which is equivalent to the Virtual Work Principle (see books like Hughes of Bathe). The Virtual Work, represents a set of linear (or nonlinear) equations which can be solved more efficiently (with fsolve).
If for some motive you must solve the problem as an optimization problem, then, if you are considering linear elasticity, your strain energy is quadratic, thus you could use the qp Octave function.
To use sparse matrices could also be helpful.

operands could not be broadcast together with shapes

I have used this code but it showing me error. Help me solve this.
som=MiniSom(x=10,y=10,input_len=15,sigma=1.0,learning_rate=0.5)
som.random_weights_init(x)
som.train_random(data=x,num_iteration=100)
from pylab import bone, pcolor, colorbar, plot, show
bone()
pcolor(som.distance_map().T)
colorbar()
markers = ['o', 's']
colors = ['r', 'g']
for i, x1 in enumerate(x):
w = som.winner(x)
plot(w[0] + 0.5,
w[1] + 0.5,
markers[y[i]],
markeredgecolor = colors[y[i]],
markerfacecolor = 'None',
markersize = 10,
markeredgewidth = 2)
show()
The line w = som.winner(x) should be replaced with w = som.winner(x1)
MiniSom.winner() method computes the coordinates of the winning neuron for the sample x, where sample x is one single row of your dataset, and the corresponding variable name in your code is x1.
You are iterating x1 over rows of x, however still trying to use the dataset variable x with som.winner() method.

How to find area enclosed by points in octave using Quadrature or any other method

I have two sets of coordinates (both positive and negative values, not necessarily in increasing order, and in many cases there are different values of y for the same value of x) which I can load into two row vectors of equal size.
I want to calculate the area enclosed by the curve.
How to do it with octave?
I tried this answer but it does not work because it seems that the area printed (204.64) is too high (see picture).
I tried the code:
function showdata(fName)
M = dlmread(fName);
H = M(2:end, 1); % starting row number is 2
B = M(2:end, 2);
aux = figure();
plot(H, B,'linewidth',2);
xlabel ("Auxilary field H (A/m)");
ylabel ("Magnetic Field B (Tesla)");
area = polyarea(H,B)
axis([min(H), max(H), min(B), max(B)]);
grid on;
grid minor on;
title (area,"fontsize",20);
Then I am calling showdata('data.txt') in Octave.
Picture of Data points:
This is the data file I am using.
There is a function for computing convex hull called "convhull" in Octave. It returns the indices of the points formming convex hull data.
M = dlmread("data.txt"); #I removed the header in data.txt
x = M(:,1);
y = M(:,2);
k = convhull(x,y);
plot (x(k), y(k), "r-", x, y, "b+");
n = rows(k);
x_prime = vertcat(x(k(n)), x(k(1:n-1)));
y_prime = vertcat(y(k(n)), y(k(1:n-1)));
A = .5*abs(x_prime'*y(k)-y_prime'*x(k)); #80.248
polyarea(x(k), y(k)) == A and true
Maybe convex hull is not good estimate of area because the top left and the down-right lines are a little far away from the points. There are other ways to form a polygon from data
, one of which could be alpha shape. However, alpha shape are more complicated and there is no corresponding pre-built function in Octave.
Update:
Each x corresponds to at least one y cordinate. I marked the highest point and lowest point laying on the same x and estimate the area again.
There is the code:
[uni, ~] = sort(unique(x));
n = rows(uni);
outline = [];
for i = 1:n
y_list = y(x==uni(i));
[y_max, ~] = max(y_list);
outline(i, :)= [uni(i), y_max];
[y_min, ~] = min(y_list);
outline(2*n-i+1,:)= [uni(i), y_min];
endfor
figure;
plot (x(k), y(k), "r-", x, y, "b+", outline(:,1), outline(:,2), "g-", "linewidth", 3);
polyarea(outline(:,1), outline(:,2)) #74.856
By the way, if the arguments of function polyarea do not form a close curve function polyarea would return wrong area.
Four point on a unit square:
[(0,0), (1,0), (1,1), (0,1)], [(0,0), (1,1), (1,0), (0,1)]
polyarea([0,1,1,0],[0,0,1,1])!==polyarea([0,1,1,0],[0,1,0,1]).

Satisfying an inequality in an Octave 3D plot

Suppose I generate a plot in the following way:
x=linspace(-2,2,50);
y=linspace(-2,2,50);
[xx,yy]=meshgrid(x,y);
mesh(xx,yy,4-(xx.^2+yy.^2))
Is there anyway to impose an inequality such that I only plot values where x < y?
One possible hack:
x = y = linspace(-2, 2, 50);
[xx, yy] = meshgrid(x, y);
cond = xx < yy;
xx = xx .* cond;
yy = yy .* cond;
mesh(xx, yy, 4-(xx.^2+yy.^2));
Strictly speaking, this will move all coordinate pairs (x,y) that do not meet the criterion x < y from their current location to the origin of the plot:
This is fairly similar to another answer already provided, but might help with the "strange aberration" you mention that answer caused in your data. Basically create a mask that is 1 where xx < yy, and 0 otherwise:
mask = xx < yy;
Then apply this mask to your xx and yy meshes:
xx_mask = xx.*mask;
yy_mask = yy.*mask;
And only then do you plot your results:
mesh(xx_mask, yy_mask, 4-(xx_mask.^2 + yy_mask.^2));
Basically the only difference is that this way you are setting the unwanted values in your xx and yy matrices to zero before you square them and plot them.
Note, this was tested with MATLAB instead of Octave, but they should give similar results.
Solutions above are only good if the point (0,0) is part of your chart. Otherwise it adds the point to the chart and then tries to plot, creating strange effect, like below.
[![x=linspace(1,3,50);
y=linspace(1,3,50);
\[xx,yy\]=meshgrid(x,y);
mask = xx < yy;
xx_mask = xx.*mask;
yy_mask = yy.*mask;
mesh(xx_mask, yy_mask, 4-(xx_mask.^2 + yy_mask.^2));][1]][1]
What can be alternatively be done is to leave x and y axes values as is and only convert z axis values to NA inthe range not satisfying the condition.
x=linspace(1,3,50);
y=linspace(1,3,50);
[xx,yy]=meshgrid(x,y);
mask = xx < yy;
function result = applyCondition(cond)
result = ifelse(cond, 0, NA);
endfunction
zz = 4-(xx.^2 + yy.^2);
mesh(xx, yy, zz + arrayfun(#applyCondition, mask));
This solution works in all cases, regardless of (0,0) being part of you chart of not.