Matlab генерирует случайные числа и проверку перекрытия - PullRequest
0 голосов
/ 16 декабря 2018

Я написал код для генерации случайного числа стержней на Matlab в указанном домене, а затем сохранил вывод в текстовом файле.Я хотел бы попросить помощи по добавлению следующих опций в код;(i) если случайно сгенерированный стержень превышает заданный размер домена, длину этого стержня следует сократить, чтобы сохранить его в этом конкретном домене.(ii) я хотел бы избежать наложения вновь сгенерированного числа (стержня) с номером предыдущего, в случае наложения создайте другое место для нового стержня.

Я не могу понять, какДолжен ли я сделать это.Было бы очень полезно, если бы кто-то помог мне написать код для этих двух вариантов.Спасибо

% myrandom.m  
% Units are mm.

% domain size
bx = 160;
by = 40;
bz = 40;

lf = 12; % rod length
nf = 500; % Number of rods

rns = rand(nf,3);      % Start
rne = rand(nf,3)-0.5;  % End

% Start Points
for i = 1:nf
    rns(i,1) = rns(i,1)*bx;
    rns(i,2) = rns(i,2)*by;
    rns(i,3) = rns(i,3)*bz;
end

% Unit Deltas
delta = zeros(nf,1);
for i = 1:nf
   temp = rne(i,:);
   delta(i) = norm(temp);
end

% Length Deltas
rne = lf*rne./delta;

% End Points
rne = rns + rne;


fileID = fopen('scfibers.txt','w');
for i = 1:nf
    fprintf(fileID,'%12.8f %12.8f %12.8f\r\n',rns(i,1),rns(i,2),rns(i,3));
    fprintf(fileID,'%12.8f %12.8f %12.8f\r\n\r\n',rne(i,1),rne(i,2),rne(i,3));
end
fclose(fileID);

1 Ответ

0 голосов
/ 17 декабря 2018

Я бы начал с написания функции, которая создает случайные стержни:

function [rns,rne] = myrandom(domain,len,N)

rns = rand(N,3).*domain; % Start  --> rns = bsxfun(@times,rand(N,3),domain)
rne = rand(N,3)-0.5;  % End

% Unit Deltas
delta = zeros(N,1);
for k = 1:N
  delta(k) = norm(rne(k,:));
end

% Length Deltas
rne = len*rne./delta; % --> rne = len*bsxfun(@rdivide,rne,delta)

% End Points
rne = rns + rne;

% remove rods the exceed the domain:
notValid = any(rne>domain,2); % --> notValid = any(bsxfun(@gt,rne,domain),2);
rns(notValid,:)=[];
rne(notValid,:)=[];
end

Эта функция получает domain как [bx by bz], а также длину стержней как len, и N количество стержней для генерации.Обратите внимание, что с помощью поэлементного умножения (.*) я исключил первый цикл for.
Если вы используете версию MATLAB до 2016b, вам нужно использовать bsxfun:

В MATLAB® R2016b и более поздних версиях встроенные двоичные функции, перечисленные в этой таблице, независимо поддерживают неявное расширение.

Затронутые строки помечены --> в коде (с альтернативой).

Последние три строки в функции удаляют из результата все этапы, которые превышают размер домена (надеюсь, я правильно вас понял).

Далее явызовите эту функцию в скрипте:

% domain size
bx = 160;
by = 40;
bz = 40;
domain = [bx by bz];
lf = 12; % rod length
nf = 500; % Number of rods

[rns,rne] = myrandom(domain,lf,nf);
u = unique([rns rne],'rows');
remain = nf-size(u,1);
while remain>0
    [rns_temp,rne_temp] = myrandom(domain,lf,remain);
    rns = [rns;rns_temp];
    rne = [rne;rne_temp];
    u = unique([rns rne],'rows');
    remain = nf-size(u,1);
end

После базовых определений вызывается функция и возвращает rne и rns, которые, вероятно, меньше, чем nf.Затем мы проверяем дубликаты и сохраняем все уникальные стержни в u.Мы вычисляем стержни, оставшиеся для вычисления, и используем цикл while для генерации новых стержней по мере необходимости.На каждой итерации цикла мы добавляем вновь созданные стержни к тем, которые у нас есть в rne и rns, и проверяем, сколько уникальных векторов у нас сейчас, и, если их достаточно, мы покидаем цикл (тогда вы можете добавитьпечать в файл).

Обратите внимание, что:

  1. Я не был уверен, что вы подразумеваете под ", в случае наложения создайте другое место для нового стержня« - хотите ли вы иметь больше nf стержней, если некоторые являются дубликатами, то, из которых nf уникальны (что делает код выше)?или вы хотите удалить дубликаты и остаться только с nf уникальными стержнями?В случае последнего варианта я бы вставил функциональную часть unique в функцию, которая создает стержни myrandom.

  2. Цикл Wile, как написано выше, неэффективен, так какпредварительное выделение памяти не выполняется.Я не уверен, что это возможно, если вы просто хотите создать больше стержней, но сохраните дубликаты, но если нет (второй вариант в 1 выше), и если вы собираетесь использовать это выделение, то предварительное распределение очень рекомендуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...