Идеи по уменьшению сложности трехмерной функции плотности для создания тройного поверхностного графика в Matlab

У меня есть функция трехмерной плотности q(x,y,z), которую я пытаюсь построить в Matlab 8.3.0.532 (R2014a).

Область определения моей функции начинается в точке a и заканчивается в точке b с равномерным интервалом ds. Я хочу отобразить плотность на тройном поверхностном графике, где каждое измерение на графике представляет собой пропорцию x, y, z в данной точке. Например, если у меня есть единица плотности в области q (1,1,1) и другая единица плотности в области q (17, 17, 17), в обоих случаях есть равные пропорции x, y, z, и поэтому у меня будет две единицы плотности на моем троичном поверхностном графике в координатах (1/3,1/3,1/3). У меня есть код, который работает с использованием ternsurf. Проблема в том, что количество точек пропорции растет экспоненциально быстро с размером домена. На данный момент я могу построить только область размером 10 (в каждом измерении) с единичным интервалом (ds = 1). Однако мне нужен гораздо больший домен, чем этот (размер 100 в каждом измерении) и намного меньший, чем единичный интервал (в идеале всего 0,1) - это приведет к 100 ^ 3 * (1/0,1) ^ 3 точки на сетке , с которым Matlab просто не может справиться. Есть ли у кого-нибудь идеи о том, как каким-то образом связать функцию плотности с пропорциями 3D, чтобы уменьшить количество точек?

Мой рабочий код с примером:

a = 0; % start of domain
b = 10; % end of domain
ds = 1; % spacing

[x, y, z] = ndgrid((a:ds:b)); % generate 3D independent variables
n = size(x);

q = zeros(n); % generate 3D dependent variable with some norm distributed density
for i = 1:n(1)
    for j = 1:n(2)
        for k = 1:n(2)
            q(i,j,k) = exp(-(((x(i,j,k) - 10)^2 + (y(i,j,k) - 10)^2 + (z(i,j,k) - 10)^2) / 20));
        end
    end
end

Total = x + y + z; % calculate the total of x,y,z at every point in the domain
x = x ./ Total; % find the proportion of x at every point in the domain
y = y ./ Total; % find the proportion of y at every point in the domain
z = z ./ Total; % find the proportion of z at every point in the domain
x(isnan(x)) = 0; % set coordinate (0,0,0) to 0
y(isnan(y)) = 0; % set coordinate (0,0,0) to 0
z(isnan(z)) = 0; % set coordinate (0,0,0) to 0

xP = reshape(x,[1, numel(x)]); % create a vector of the proportions of x
yP = reshape(y,[1, numel(y)]); % create a vector of the proportions of y
zP = reshape(z,[1, numel(z)]); % create a vector of the proportions of z

q = reshape(q,[1, numel(q)]);  % create a vector of the dependent variable q

ternsurf(xP, yP, q);  % plot the ternary surface of q against proportions
shading(gca, 'interp');
colorbar
view(2)

person Michael Andrew Bentley    schedule 07.10.2014    source источник


Ответы (2)


Я полагаю, вы имели в виду n(3) в своем самом внутреннем цикле. Вот несколько советов:

1) Снять петли:

q = exp(- ((x - 10).^2 + (y - 10).^2 + (z - 10).^2) / 20);

2) Ослабьте изменения формы:

xP = x(:); yP = y(:); zP = z(:);

3) Проверить Total один раз вместо трех проверок x,y,z:

Total = x + y + z; % calculate the total of x,y,z at every point in the domain
Total( abs(Total) < eps ) = 1;
x = x ./ Total; % find the proportion of x at every point in the domain
y = y ./ Total; % find the proportion of y at every point in the domain
z = z ./ Total; % find the proportion of z at every point in the domain

PS: Я только что узнал твое имя.. это Джонатан ;)

person Jonathan H    schedule 07.10.2014
comment
Эй Джонатан, спасибо, все хорошие советы! Любые идеи о том, как впоследствии убрать мое «пропорциональное пространство», чтобы уменьшить количество баллов? Я думаю, что это интересная математическая задача на самом деле! Я могу придумать, как это сделать с помощью циклов for и множества операторов if else, но это будет очень громоздко и медленно. Ваше здоровье! - person Michael Andrew Bentley; 08.10.2014
comment
Я ничего не вижу о биннинге в ОП. Если есть подвопрос, вы должны включить четкое описание, возможно, с фиктивным кодом, который не запускается, но выглядит как то, чего вы пытаетесь достичь :) - person Jonathan H; 08.10.2014

Метод дискретизации, вероятно, зависит от использования вашего графика, возможно, имеет смысл уточнить ваш вопрос с этой точки зрения. В целом, вы, вероятно, боретесь с ошибкой «Недостаточно памяти», пара соответствующих приемов описана здесь http://www.mathworks.nl/help/matlab/matlab_prog/resolving-out-of-memory.-errors.html?s_tid=doc_12b?refresh=true#brh72ex-52 . Конечно, они работают только до определенного размера массивов.

Более общее решение - слишком сохранять части массивов на жестком диске, это замедляет обработку, но оно будет работать. Например, вы можете определить несколько функций q с помощью ngrids, специфичных для масштаба (например, ngridOrder0=[0:10:100], ngridOrder10=[1:1:9], ngridOrder11=[11:1:19] и т. д.). ) и напишите функцию доступа, которая будет загружать/сохранять соответствующую сетку и функцию q в зависимости от той части графика, которую вы ищете.

person Kostya    schedule 09.10.2014