⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pivotgolf.m

📁 Moler写的配套书中的源程序
💻 M
字号:
function scoreout = pivotgolf(course,pivotstrat,nholes)% PIVOTGOLF  Pivot Pickin' Golf.%    Your goal is to use LUGUI to compute the LU decompositions of nine%    matrices with as little roundoff error as possible.  Your score for%    each hole is norm(R,inf)+norm(Leps,inf)+norm(Ueps,inf) where%    R = L*U - A(p,q) is the residual and Leps and Ueps are the nonzeros%    that should be zero in L and U.%%    The golf courses include:%       magic -- magic squares and Golub matrices, some are rank deficient.%       testmats -- various test matrices, Pascal, Hilbert, gallery, etc.%       rand #s -- random integer matrices initialized by rand('state',s).%%    The four pivot strategies are:%       pick -- use the mouse to pick the pivots.%       diagonal -- pivot on the diagonal, it is possible to divide by zero.%       partial -- pivot is the largest element in the current column.%       complete -- pivot is the largest element in the unreduced matrix.%%    PIVOTGOLF(course,pivotstrat,nholes) bypasses the initial screen.%       course = 'magic', 'testmats', or a numeric s to set rand('state',s).%       pivotstrat = 'pick','diagonal','partial', or 'complete'.%       nholes = number of holes (matrices)%%    Try to pick pivot elements that divide into the other elements exactly.%    If you can choose a pivot element that is a power of two, there will%    be no roundoff error at that step.  But if the pivot is small, the%    elements in the unreduced matrix might grow larger and subsequent steps%    might have larger roundoff errors.%%    You should know that "mulligan" is golf terminology for "OOPS, I want%    to take that shot over".  Good luck!%%    See also LUGUI.if nargin == 0   % Initial screen   shg   clf   set(gcf,'double','on','name','Pivot Pickin'' Golf', ...      'menu','none','numbertitle','off')   axes('pos',[.05 .25 .90 .50]);   set(gca,'xtick',[],'ytick',[],'color','white')   box on   uicontrol('style','text','units','norm','pos',[.25 .55 .50 .10], ...      'fore',[0 0.65 0],'back','w','fontweight','bold', ...      'string','Welcome to Pivot Pickin'' Golf')   uicontrol('style','text','units','norm','pos',[.08 .46 .12 .06], ...      'backg','white','fontweight','bold','string','Course:')   uicontrol('style','text','units','norm','pos',[.08 .35 .12 .06], ...      'backg','white','fontweight','bold','string','Strategy:')   for k = 1:5      switch k         case 1,             str = 'magic';         case 2,             str = 'testmats';         otherwise,            str = ['rand #' int2str(k-2)];      end      b(k) = uicontrol('units','norm','pos',[.14*k+.08 .47 .12 .06], ...         'style','toggle','string',str,'backg','w');   end   str = {'pick','diagonal','partial','complete'};   for k = 1:4      b(k+5) = uicontrol('units','norm','pos',[.14*k+.08 .37 .12 .06], ...         'style','toggle','string',str{k},'back','w');   end   stop = uicontrol('style','toggle','string','quit', ...      'back','white','units','norm','pos',[.85 .15 .10 .05]);   uicontrol('style','toggle','units','norm','pos',[.05 .15 .10 .05], ...      'string','help','back','white','callback','help pivotgolf')   bvals = [];   while sum(bvals) < 2      if get(stop,'val'), break, end      pause(.05)      bvals = cell2mat(get(b,'val'));   end   if get(stop,'val')      close(gcf)      return   end   for k = find(bvals)'      switch k         case 1, course = 'magic';         case 2, course = 'testmats';         case {3,4,5}, course = k-2;         otherwise, pivotstrat = get(b(k),'string');      end   endelseif nargin < 2      pivotstrat = 'pick';endif nargin < 3   nholes = 9;endif isnumeric(course)   rand('state',course)else   course = lower(course);   randn('state',0)end% Loop over nine holes (matrices).score = 0;hole = 1;A = [];while hole <= nholes   if isempty(A)            % Generate the matrix.         switch course         case 'magic'            n = 2+ceil(2/3*hole);            switch hole               case {3,6,9}                  A = golub(n);               otherwise                  A = magic(n);            end         case 'testmats'            n = hole;            switch hole               case 1                  n = 7;                  e = ones(n,1);                  A = full(spdiags([e (-3:3)' e],[-1 0 1],n,n));               case 2                  n = 5;                  A = vander((-2:2)');               case 3                  A = gallery(n);               case 4                  A = hadamard(n);               case 5                  A = gallery(n);               case 6                  A = pascal(n);               case 7                  n = 6;                  A = pascal(n);                  A(n,n) = A(n,n)-1;               case 8                  n = 5;                  A = 27720*hilb(n);               case 9                  n = 6;                  U = eye(n,n) - triu(ones(n,n),1);                  A = U'*U;            end         otherwise            n = ceil(2+3*rand);            A = round(10*(2*rand(n,n)-1));      end   end   % Use LUGUI to compute the LU decomposition   dx = 100;   dy = 30;   pos = get(gcf,'pos');   w = (n+1)*dx;   h = (n+3)*dy;   if pos(3) < w+40      pos = [pos(1)-(w+40-pos(3))/2 pos(2) w+40 pos(4)];   end   if pos(4) < h+150      pos = [pos(1) pos(2)-(h+150-pos(4))/2 pos(3) h+150];   end   set(gcf,'pos',pos)   [L,U,p,q] = lugui(A,pivotstrat);   pause(2);   % Score   R = (L*U - A(p,q));   Leps = L.*(abs(L)<1000*norm(L,1)*eps);   Ueps = U.*(abs(U)<1000*norm(U,1)*eps);   show(abs(R)+abs(Leps)+abs(Ueps));   if all(isfinite(R(:)))      s = ceil(4*(norm(R(:),1)+norm(Leps(:),1)+norm(Ueps(:),1))/eps)/4;   else      s = Inf;   end   % Report the score and decide what to do next.   set(gcf,'name','Pivot Pickin'' Golf')   set(gca,'units','norm');   pos = get(gca,'pos');   uicontrol('style','push','units','norm', ...      'pos',[pos(1)+pos(3)/2-.16 pos(2)+pos(4)+.10 .33 .06], ...       'fontweight','bold','backg','w', ...      'fore',[0 0.65 0],'string',sprintf('hole #%d',hole))   uicontrol('style','push','units','norm', ...      'pos',[pos(1)+pos(3)/2-.16 pos(2)+pos(4)+.02 .33 .06], ...       'fontweight','bold','fore',[0 0 0.90],'back','w',...      'string',sprintf('score = %s, total = %s',sph(s),sph(score+s)))   stop = uicontrol('style','toggle','string','quit', ...      'back','white','units','norm', ...      'pos',[pos(1)+pos(3)-.12 pos(2)-.07 .12 .05]);   if isequal(pivotstrat,'pick')      next = uicontrol('units','norm', ...         'style','toggle', ...         'pos',[pos(1) pos(2)-.07 .12 .05], ...         'style','toggle','fontweight','bold', ...         'back','white','string','next');         if hole==nholes, set(next,'string','finish'), end      mulligan = uicontrol('units','norm', ...         'style','toggle', ...         'pos',[pos(1)+pos(3)/2-.06 pos(2)-.07 .12 .05], ...         'style','toggle','fontweight','bold', ...         'back','white','string','mulligan');      uics = [stop next mulligan];      while all(cell2mat(get(uics,'val'))==0)         drawnow      end      if get(mulligan,'val'), continue, end   else      pause(3)   end   score = score + s;   if get(stop,'val'), break, end   hole = hole + 1;   A = [];end% Final screenclfset(gcf,'double','on','name','Pivot Pickin'' Golf', ...   'pos','default','menu','none','numbertitle','off')axes('pos',[.05 .25 .90 .50]);set(gca,'xtick',[],'ytick',[],'color','white')box onuicontrol('style','text','units','norm','pos',[.15 .60 .50 .10], ...   'fontweight','bold','fore',[0 0.65 0],'back','w','horiz','left', ...   'string',sprintf('Thanks for playing Pivot Pickin'' Golf.'))if score == 0   uicontrol('style','text','units','norm','pos',[.15 .50 .50 .10],...      'fontweight','bold','fore',[0 0.65 0],'back','w','horiz','left', ...      'string','Perfect score.  Congratulations!')elseif score == Inf   uicontrol('style','text','units','norm','pos',[.15 .50 .50 .10], ...      'fontweight','bold','fore',[0 0.65 0],'back','w', ...      'horiz','left', ...      'fore',[0 0.65 0],'string','Your score was infinite.')   uicontrol('style','text','units','norm','pos',[.15 .40 .50 .10], ...      'fontweight','bold','fore',[0 0.65 0],'back','w','horiz','left', ...      'fore',[0 0.65 0],'string','You have to avoid dividing by zero.')else   uicontrol('style','text','units','norm','pos',[.15 .50 .50 .10], ...      'fontweight','bold','fore',[0 0.65 0],'back','w','horiz','left', ...      'string',sprintf('Your score was %s eps.',sph(score)))   if score > 100      uicontrol('style','text','units','norm','pos',[.15 .40 .50 .10], ...         'fontweight','bold','fore',[0 0.65 0],'back','w','horiz','left', ...         'string','Better luck next time.')   endenduicontrol('style','toggle','units','norm','pos',[.85 .15 .10 .08], ...   'string','close','fontweight','bold','back','w','callback','close(gcf)')if nargout > 0   scoreout = score;   pause(3)end%------------------------------------------------------------function show(A)clf[m,n] = size(A);set(gcf,'double','on','name','LU Gui', ...   'menu','none','numbertitle','off', ...   'windowbuttonupfcn','set(gcf,''tag'',''pivot'')')pos = get(gcf,'pos');dx = 100;dy = 30;w = (n+1)*dx;h = (n+3)*dy;if pos(3) < w+40   pos = [pos(1)-(w+40-pos(3))/2 pos(2) w+40 pos(4)];endif pos(4) < h+150   pos = [pos(1) pos(2)-(h+150-pos(4))/2 pos(3) h+150];endif pos(3) < w+40   pos = [pos(1)-(w+40-pos(3))/2 pos(2) w+40 pos(4)];endif pos(4) < h+100   pos = [pos(1) pos(2)-(h+100-pos(4))/2 pos(3) h+100];endset(gcf,'pos',pos)axes('units','pixels','pos',[(pos(3)-w)/2 (pos(4)-h)/2 w h], ...   'xtick',[],'ytick',[])box onAcolor = [0 0 0];for j = 1:n   for i = 1:m      t(i,j) = text('units','pixels','string',spf(A(i,j)), ...         'fontname','courier','fontweight','bold','fontsize',14, ...         'horiz','right','color',Acolor, ...         'pos',[20+j*dx 20+(m+2-i)*dy]);   endend%------------------------------------------------------------function s = spf(aij)% Subfunction to format text stringsif aij == 0   f = '%10.0f';elseif (abs(aij) < 1.e-4) | (abs(aij) >= 1.e4)    f = '%10.1e';else   f = '%10.4f';ends = sprintf(f,aij);%------------------------------------------------------------function s = sph(x)% Format text strings that are integer multiples of 1/4.if x == 0   f = '%d';elseif x == round(x);   f = '%1.0f';elseif x == round(2*x)/2;   f = '%2.1f';else   f = '%3.2f';ends = sprintf(f,x);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -