Problems: 11.12.2017, spmd_minmaxproblems3.m

  Modified 19.03.2019
Practically identical with spmd_minmaxproblems2.m

Contents

(1) Max and min-points

Find max and min-values and locations by decomposing domain into labs and working in parallel with all labs available.

Start with the version 2 problems

First example:

clear
close all
format compact

Define function f

f=@(x) x.*sin(x);
%fplot(f,[-pi 10*pi])

Find local min and max on I=[-pi N*pi], take N=nlabs+1

In this case we know zeros of f: n*pi .

Open pool:

p=parpool
nlabs=p.NumWorkers  % Triton default: 20
Starting parallel pool (parpool) using the 'local' profile ...
connected to 20 workers.
p = 
 Pool with properties: 

            Connected: true
           NumWorkers: 20
              Cluster: local
        AttachedFiles: {}
    AutoAddClientPath: true
          IdleTimeout: 30 minutes (30 minutes remaining)
          SpmdEnabled: true
nlabs =
    20

Some rules of pools: parpool(nlabs), spmd ... end, delete(gcp)

spmd
    a=2*(labindex-1)*pi;
    b=2*labindex*pi;
    fprintf('Subinterval: [%-4g, %-4g]\n',a,b)
end
% Note1: If you started pool for nlabs=20 (eg.), you have to close it before
% changing to parpool(4) (eg.)
% To close pool:
%    delete(gcp)
%
% Note 2: If you have a pool open, you can do several spmd-blocks one after
% another. So the end statement of your spmd-block doesn't close the pool.
%
Interval.a=a;
Interval.b=b;
Lab  1: 
  Subinterval: [0   , 6.28319]
Lab  2: 
  Subinterval: [6.28319, 12.5664]
Lab  3: 
  Subinterval: [12.5664, 18.8496]
Lab  4: 
  Subinterval: [18.8496, 25.1327]
Lab  5: 
  Subinterval: [25.1327, 31.4159]
Lab  6: 
  Subinterval: [31.4159, 37.6991]
Lab  7: 
  Subinterval: [37.6991, 43.9823]
Lab  8: 
  Subinterval: [43.9823, 50.2655]
Lab  9: 
  Subinterval: [50.2655, 56.5487]
Lab 10: 
  Subinterval: [56.5487, 62.8319]
Lab 11: 
  Subinterval: [62.8319, 69.115]
Lab 12: 
  Subinterval: [69.115, 75.3982]
Lab 13: 
  Subinterval: [75.3982, 81.6814]
Lab 14: 
  Subinterval: [81.6814, 87.9646]
Lab 15: 
  Subinterval: [87.9646, 94.2478]
Lab 16: 
  Subinterval: [94.2478, 100.531]
Lab 17: 
  Subinterval: [100.531, 106.814]
Lab 18: 
  Subinterval: [106.814, 113.097]
Lab 19: 
  Subinterval: [113.097, 119.381]
Lab 20: 
  Subinterval: [119.381, 125.664]

Composite to ordinary variables (workers -> client)

A=[a{:}];B=[b{:}];
plot(A,f(A),'*k',B,f(B),'ok')
% Lab-boundaries a,b are zeros of f this time (zeros of sin).

Find min and max on each lab.

n=1000;
disp([num2str(n*nlabs) ' calculations, each lab doing ' ...
    num2str(n) ' simultaneously' ])
spmd
    x=linspace(a,b,n);
    y=f(x);
    % [ymax,maxI]=max(y); % Max on each lab and index of the 1'st
    % [ymin,minI]=min(y); % Min on each lab and its index of the 1'st
    ymax=max(y); % Max values on each lab
    ymin=min(y); % Min values on each lab
    maxI=ymax==y; % Logical indexvector of (all) max-values in each lab
    minI=ymin==y; % Logical indexvector of (all) min-values in each lab
    xmax=x(maxI); % x-values of max's
    xmin=x(minI); % x-values of min's
end
20000 calculations, each lab doing 1000 simultaneously

Error estimate (Not quite ...)

L=2*pi     % "Labinterval's" length
abserr=L/n % upper bound for abs error
L =
    6.2832
abserr =
    0.0063

Global max and min points

gmaxx=[xmax{1} xmax{2}] gmaxy=[ymax{1} ymax{2}] gminx=[xmin{1} xmin{2}] gminy=[ymin{1} ymin{2}]

Composite to ordinary variables (results from workers to client):

Xmax=[xmax{:}];
Ymax=[ymax{:}];
Xmin=[xmin{:}];
Ymin=[ymin{:}];

Check lab-borders

sum(Xmax==A)
sum(Xmin==A)
% Both return 0, as they should, because the labintervals are [k-1,k+1]*pi.
plot(Xmin,Ymin,'*r',Xmax,Ymax,'*k')
ans =
     0
ans =
     0

Increase accuracy!

Repeat the same procedure using labs with small radii around min/max-points.
nlabs=20; % Triton max  %as before
n=1000; % as before
% parpool(nlabs)
spmd
    am=xmin-abserr;bm=xmin+abserr;
    aM=xmax-abserr;bM=xmax+abserr;
    xm=linspace(am,bm,n);
    xM=linspace(aM,bM,n);
    ym=f(xm);yM=f(xM);
    [ymax,maxI]=max(yM); % Max on each lab and its index
    [ymin,minI]=min(ym); % Min on each lab and its index
    % In this case the shorter form using max/min is ok, as we know
    % uniqueness on the small intervals. (But this is hardly more
    % efficient though.)
    xmax2=xM(maxI);       % x-values of max's
    ymax2=f(xmax2);
    xmin2=xm(minI);       % x-values of min's
    ymin2=f(xmin2);
end
Xmax2=[xmax2{:}];
Ymax2=[ymax2{:}];
Xmin2=[xmin2{:}];
Ymin2=[ymin2{:}];

Error:

abserr2=abserr/n
max(abs(Xmax2-Xmax))
max(abs(Ymax2-Ymax))
%
abserr2 =
   6.2832e-06
ans =
    0.0031
ans =
   3.9886e-04

In some cases need to remove extra points

Here's one attempt:

%{
aa=[a{:}];bb=[b{:}];
Axmax=[aa' gmaxx']
pick=~(Axmax(:,1)==Axmax(:,2));
xmaxtrue=gmaxx(pick);
ymaxtrue=gmaxy(pick);
%}

Removal of a single value is easy:

t=-2:2; T=[t t t t]
% Remove 0's
T(T~=0)
% or
T(T==0)=[]
T =
  Columns 1 through 13
    -2    -1     0     1     2    -2    -1     0     1     2    -2    -1     0
  Columns 14 through 20
     1     2    -2    -1     0     1     2
ans =
  Columns 1 through 13
    -2    -1     1     2    -2    -1     1     2    -2    -1     1     2    -2
  Columns 14 through 16
    -1     1     2
T =
  Columns 1 through 13
    -2    -1     1     2    -2    -1     1     2    -2    -1     1     2    -2
  Columns 14 through 16
    -1     1     2

Zeros of f using brackets we just found

Br=[Ymax' Ymin']
spmd
    ab=[Xmax(labindex) Xmin(labindex)];
    z=fzero(f,ab);
end
Z=[z{:}]
% Here of course we know the result.
Z-(1:nlabs)*pi
% YES !!!
Br =
    1.8197   -4.8145
    7.9167  -11.0407
   14.1724  -17.3076
   20.4447  -23.5831
   26.7222  -29.8618
   33.0017  -36.1421
   39.2826  -42.4233
   45.5640  -48.7047
   51.8459  -54.9869
   58.1278  -61.2692
   64.4104  -67.5514
   70.6929  -73.8340
   76.9755  -80.1168
   83.2580  -86.3996
   89.5406  -92.6824
   95.8235  -98.9652
  102.1065 -105.2480
  108.3895 -111.5308
  114.6724 -117.8136
  120.9554 -124.0964
Z =
  Columns 1 through 7
    3.1416    9.4248   15.7080   21.9911   28.2743   34.5575   40.8407
  Columns 8 through 14
   47.1239   53.4071   59.6903   65.9734   72.2566   78.5398   84.8230
  Columns 15 through 20
   91.1062   97.3894  103.6726  109.9557  116.2389  122.5221
ans =
  Columns 1 through 7
         0    3.1416    6.2832    9.4248   12.5664   15.7080   18.8496
  Columns 8 through 14
   21.9911   25.1327   28.2743   31.4159   34.5575   37.6991   40.8407
  Columns 15 through 20
   43.9823   47.1239   50.2655   53.4071   56.5487   59.6903