function xy = solver(kd,bx)
rand('state',0);
npts = length(kd);
xy = zeros(npts,1);
if any(kd(:)>0)
nones=ones(npts,1);
dr=sqrt(bx(2)^2+bx(4)^2);
kd(kd>dr)=dr;
[dum,p]=sort(-max(kd));
kd=kd(p,p);
S=((kd-eye(npts))>=0); % Remember positive position
sI=find(S); % Positive index
strainMatrix = S; % Create strainMatrix;
mx=-dum(1)*1.21;
dx=min(bx(2),mx);
dy=min(bx(4),mx);
D=dx+dy;
d=D/16;
while max(2,ceil(dx/d))*max(2,ceil(dy/d))<60
d=d/2;
end
x=0:d:dx;
if x(end)<dx
x(end+1)=dx;
end
y=0:d:dy;
if y(end)<dy
y(end+1)=dy;
end
[x,y]=meshgrid(x,y);
xy0=x(:)+i*y(:);
k = length(xy0);
M=fix(8+npts/4);
N0=min(M,npts);
xy(1:N0) = solverl(S(1:N0,1:N0),kd(1:N0,1:N0),dx,dy,N0);
for N=(M+1):npts
xy(N) = solver2(S(1:N,N),kd(1:N,N),N,xy0,...
xy(1:N),k,d,dx,dy,4);
end
for N=1:N0
xy(N) = solver2(S(:,N),kd(:,N),N,[xy(N);xy0],xy,k+1,d,dx,dy,5);
end
m=2;
for f=1:2,
[XY1,XY2] = meshgrid(xy);
strainMatrix(sI) = abs(abs(XY1(sI)-XY2(sI))-kd(sI));
if sum(strainMatrix(sI))<4
break;
end
[sV,sP] = sort(-sum(strainMatrix));
n=min(fix(npts/m),sum(sV<(sum(sV)*0.98/npts)));
sN = sP(1:n);
for i=sN,
xy(i) = solver2(S(:,i),kd(:,i),i,[xy(i);xy0],xy,k+1,d,dx,dy,5);
m=m/2;
end
end
[v,w]=sort(p);
xy=xy(w,:);
end
xy=[real(xy) imag(xy)];
function xy = solverl(S,kd,dx,dy,npts)
[I,J] = find(triu(S,1));
if isempty(I),
xy = zeros(npts,1);
return;
end
y = kd(find(triu(S,1)));
k = 450+npts*30; % change k according to memory capacity.
x = zeros(npts,k);
x(:) = rand(npts*k,2)*[dx;i*dy];
[tv,id] = min(sum(abs(abs(x(I,:)-x(J,:))-y(:,ones(1,k)))));
xy=x(:,id);
%xy = freeforce(S,kd,xy,dx,dy,npts,200);
%function xy = freeforce(S,kd,xy,dx,dy,npts,n)
sI=find(S);
fM=S;
d=kd(sI);
[X1,X2]=meshgrid(xy);
dX=X1(sI)-X2(sI);
strain=sum(abs(abs(dX)-d));
strain0=0;
while strain0<strain,
%for iC=1:n,
% Direction of force between every point and every other point
% * magnitude of strain
% * whether or not S(i,j) contains a don't-care for xy(i) and xy(j)
strain = strain0;
fM(sI) = dX.*(kd(sI)./(abs(dX)+eps)-1);
forces = sum(fM,2);
rand_forces=.1*rand(npts,1).*abs(forces).*exp(-1i*2*pi*rand(npts,1));
xy0 = xy - .1*(forces+rand_forces);
xy0=min(dx,max(0,real(xy0)))+1j*min(dy,max(0,imag(xy0)));
[X1,X2]=meshgrid(xy0);
dX=X1(sI)-X2(sI);
strain0 = sum(abs(abs(dX)-kd(sI)));
xy = xy0;
end;
function xy1 = solver2(S,kd,N,xy,xy0,k,d,dx,dy,n)
I = find(S);
if isempty(I),
xy1 = xy0(N);
return;
end
z = kd(:);
kones=ones(1,k);
xy=xy(:).';
[tv0,id]=min(sum(abs(abs(xy(ones(size(I)),:)-xy0(I,kones))-z(I,kones))));
xy1=xy(id);
for m=1:n
d0=d;
d=d0/4;
[tv,xy1]=finegrid(I,xy1,xy0,d0,d,dx,dy,z);
if tv0 - tv < 0.1, break, end
tv0 = tv;
end
function [tv,xy1]=finegrid(I,xy,xy0,d0,d,dx,dy,z);
x1=real(xy);
y1=imag(xy);
x=max(0,x1-d0):d:min(dx,x1+d0);
y=(max(0,y1-d0):d:min(dy,y1+d0))';
xy=x(ones(size(y)),:)+i*y(:,ones(size(x)));
xy=xy(:).';
kones=ones(size(xy));
[tv,id]=min(sum(abs(abs(xy(ones(size(I)),:)-xy0(I,kones))-z(I,kones))));
xy1=xy(id);
|