2015-07-28 6 views
1

Мне нужно оценить функцию (скажем) Fxy = 2 * x.^2 +3 * y.^2; на тройной сетке x-range (0 - 1), y-range (0-1) и 1-x-y (0 - 1). Я не могу построить тройную сетку, на которой мне нужно оценить вышеуказанную функцию. Кроме того, после оценки мне нужно построить функцию в трехмерном контурном графике. В идеале мне нужны оси, чтобы идти против часовой стрелки в смысле (x -> y -> (1-x-y)).Построить тройную сетку, оценить функцию на графике сетки и контура в Matlab

Я попытался функция

function tg = triangle_grid (n, t) 

    ng = ((n + 1) * (n + 2))/2; 
    tg = zeros (2, ng); 

    p = 0; 

    for i = 0 : n 
    for j = 0 : n - i 
     k = n - i - j; 
     p = p + 1; 
     tg(1:2,p) = (i * t(1:2,1) + j * t(1:2,2) + k * t(1:2,3))/n; 
    end 
    end 

    return 
end 

для числа интервалов подразделов между треугольными краями координатой

n = 10 (say) 

и для краевых координат равностороннего треугольника

t = tcoord = [0.0, 0.5,   1.0; 
       0.0, 1.0*sqrt(3)/2, 0.0]; 

Это создало треугольную сетку с осью х от 0-1, а остальные два ar e не от 0-1.

мне нужно что-то вроде этого:

wiki link

... с осями в диапазоне 0-1 (0-100 также делать).

Кроме того, мне нужно знать координатные точки для всех пересечений в треугольной сетке. Как только у меня есть это, я могу перейти к оценке функции в этой сетке.

Моя конечная цель - получить что-то вроде этого. Это лучшее представление о том, что мне нужно для достижения (по сравнению с предыдущим сюжетом, который я теперь удален)

better representation

Обратите внимание, что две тройных участки имеют изо-ценностные контуры, которые отличаются по величине , В моем случае разница на порядок, два очень разных Fxy's.

Если я могу построить два тернарных графика друг на друга, то и оценить композиции на пересечении двух изо-значных контуров на тернарной плоскости. Композиции должны быть считаны из тройного графика, а не прямоугольной сетки, на которой определяется треугольник. В настоящее время проблемы (как указано в разделе комментариев, будут обновляться после того, как проблема будет ближе к решению).

+0

насчет https://www.mathworks.com/matlabcentral/fileexchange/2299-alchemyst-ternplot –

+0

Да, но, насколько я могу см., он использует измеренные данные. Мне нужно генерировать данные на основе функции. –

+0

О, я вижу. Тебе не нужен тройной сюжет. Вы просто хотите построить в областях, где 1-x-y находятся в диапазоне (0-1), правильно? –

ответ

2

Я являюсь автором ternplot.Как вы правильно поняли, ternpcolor не делает то, что вы хотите, поскольку он автоматически создается для данных сетки. Оглядываясь назад, это было не очень мудрое решение, у меня есть made a note, чтобы изменить дизайн. Между тем этот код должен делать то, что вы хотите:

EDIT: Я изменил код, чтобы найти пересечение двух кривых, а не только одного.

N = 10; 
x = linspace(0, 1, N); 
y = x; 

% The grid intersections on your diagram are actually rectangularly arranged, 
% so meshgrid will build the intersections for us 
[xx, yy] = meshgrid(x, y); 
zz = 1 - (xx + yy); 

% now that we've got the intersections, we can evaluate the function 
f1 = @(x, y) 2*x.^2 + 3*y.^2 + 0.1; 
Fxy1 = f1(xx, yy); 
Fxy1(xx + yy > 1) = nan; 

f2 = @(x, y) 3*x.^2 + 2*y.^2; 
Fxy2 = f2(xx, yy); 
Fxy2(xx + yy > 1) = nan; 

f3 = @(x, y) (3*x.^2 + 2*y.^2) * 1000; % different order of magnitude 
Fxy3 = f3(xx, yy); 
Fxy3(xx + yy > 1) = nan; 

subplot(1, 2, 1) 
% This constructs the ternary axes 
ternaxes(5); 

% These are the coordinates of the compositions mapped to plot coordinates 
[xg, yg] = terncoords(xx, yy); 
% simpletri constructs the correct triangles 
tri = simpletri(N); 

hold on 
% and now we can plot 
trisurf(tri, xg, yg, Fxy1); 
trisurf(tri, xg, yg, Fxy2); 
hold off 
view([137.5, 30]); 

subplot(1, 2, 2); 
ternaxes(5) 
% Here we plot the line of intersection of the two functions 
contour(xg, yg, Fxy1 - Fxy2, [0 0], 'r') 
axis equal 

enter image description here

EDIT 2: Если вы хотите, чтобы найти точку пересечения между двумя контурами, вы эффективно решить два одновременных уравнений. Этот бит дополнительного кода будет решить, что для вас (заметьте, я использовал некоторые анонимные функции в приведенном выше коде в настоящее время, а):

f1level = 1; 
f3level = 1000; 
intersection = fsolve(@(v) [f1(v(1), v(2)) - f1level; f3(v(1), v(2)) - f3level], [0.5, 0.4]); 
% if you don't have the optimization toolbox, this command works almost as well 
intersection = fminsearch(@(v) sum([f1(v(1), v(2)) - f1level; f3(v(1), v(2)) - f3level].^2), [0.5, 0.4]); 

ternaxes(5) 
hold on 
contour(xg, yg, Fxy1, [f1level f1level]); 
contour(xg, yg, Fxy3, [f3level f3level]); 
ternplot(intersection(1), intersection(2), 1 - sum(intersection), 'r.'); 
hold off 

enter image description here

+1

ваш подход дает мне правильные значения функции в точках пересечения сетки, но поскольку точки сетки все еще находятся в прямоугольных координатах, значения осей считаются , скажем, поместив указатель на пересечение, дает мне индексы в прямоугольных координатах, противоположные тому, что хотелось бы, т. е. пересечение по определенным осям. Другая проблема заключается в том, что «держать» не работает. Если мне нужно построить две разные функции друг над другом на тех же треугольных осях, чтобы увидеть, где контур пересекается и получить соответствующие значения x, y, я не могу этого сделать. –

+0

Фантастика;) Хорошая работа! –

+0

Я рассмотрю добавление поддержки подсказки/указателя в этих координатах. Я написал ternplot перед этим, функциональность всплывающей подсказки существовала в Matlab, поэтому я стараюсь не использовать ее (или пропустить). Возможно, вы можете указать проблему в репозитории. Что касается второго вопроса, то код, который я разместил выше, позволит вам добавить второй график, выполнив второй «trisurf». Если конечная цель состоит в том, чтобы найти линию равенства для двух поверхностей, рассмотрим построение контура разности. – chthonicdaemon

2

Я немного поиграл с подачей файлов https://www.mathworks.com/matlabcentral/fileexchange/2299-alchemyst-ternplot.

если вы просто сделать это:

[x,y]=meshgrid(0:0.1:1); 
Fxy = 2*x.^2 +3 *y.^2; 
ternpcolor(x(:),y(:),Fxy(:)) 

Вы получаете: создан

enter image description here

Ось трети точно так, как вы говорите (1-х-у) внутри функции ternpcolor. Есть много вещей, чтобы «настроить» здесь, но я надеюсь, что этого достаточно, чтобы вы начали.

+0

Спасибо, но это использует ту же сетку, которая генерируется в функции Первоначально я использовал. Таким образом, значение функции наверху такое же, как справа. Это связано с тем, что сетка по-прежнему является декартовой, а не треугольной (Barycentric?). Метка осей (в представлении об обмене файлами) отдельно от фактической сетки. –

+0

У меня нет абсолютно никакого представления о том, что вы говорите (потому что я совершенно неопытен в таких сюжетах), и, к сожалению, я чувствую, что не могу вам помочь :(Прошу прощения. @ jam_27. –

+0

его первый раз тоже с тройными сюжетами. Надеюсь, кто-то еще с большим опытом найдет это. –

0

Вот решение с помощью R и мой пакет ggtern. Я также включил точки, находящиеся в непосредственной близости, для сравнения.

library(ggtern) 

Fxy  = function(x,y){ 2*x^2 + 3*y^2 } 
x = y = seq(0,1,length.out = 100) 
df  = expand.grid(x=x,y=y); 
df$z  = 1 - df$x - df$y 
df  = subset(df,z >= 0) 
df$value = Fxy(df$x,df$y) 

#The Intended Breaks 
breaks = pretty(df$value,n=10) 

#Create subset of the data, within close proximity to the breaks 
df.sub = ldply(breaks,function(b,proximity = 0.02){ 
    s = b - abs(proximity)/2; f = b + abs(proximity)/2 
    subset(df,value >= s & value <= f) 
}) 

#Plot the ternary diagram 
ggtern(df,aes(x,y,z)) + 
    theme_bw() + 
    geom_point(data=df.sub,alpha=0.5,color='red',shape=21) + 
    geom_interpolate_tern(aes(value = value,color=..level..), size = 1, n = 200, 
         breaks = c(breaks,max(df$value) - 0.01,min(df$value) + 0.01), 
         base  = 'identity', 
         formula = value ~ poly(x,y,degree=2)) + 
    labs(title = "Contour Plot on Modelled Surface", x = "Left",y="Top",z="Right") 

Который производит следующее:

example