📄 chaingui.m
字号:
function chaingui(action)%CHAINGUI Chain matrix multiply optimization GUI.% CHAINGUI performs optimization of a specified matrix multiply% chain by determining the parenthesization of multiplicands that% best minimizes two metrics:% - the maximum size of all temporary matrices that must be% stored in memory at any time during the evaluation, and% - the total number of floating point operations (flops)% required to compute the result.%% The GUI allows you to specify an N-element cell array,% where each entry in the array contains the size of each% matrix in the multiplication chain. For the chain multiply% A*B*C, the input argument could be specified as% "{size(A) size(B) size(C)}" assuming that A, B, and C are% matrices in the workspace.%% Alternatively, if the "Specify MATLAB Expression" menu item% is selected from the options menu, the program accepts simple% MATLAB expressions indicating a chain multiplication. For% example, "U'*V*U" or "rand(3,5)*magic(5)*rand(5)".%% See the context-sensitive help system (accessed by a right% mouse click while hovering over a GUI element) for more% details on program features.%% See also CHAINMULT.% Author: D. Orofino% Copyright 1984-2002 The MathWorks, Inc.% $Revision: 1.13.6.1 $ $Date: 2003/10/24 12:01:58 $InitGUI;% ---------------------------------------------------------------function reuse = ReuseOutput(ud)% Determine if user output buffer may be reused% Returns true if menu option checkedreuse = strcmpi(get(ud.h.ReuseOutput,'checked'),'on');% ---------------------------------------------------------------function str = ReuseOutputOpt(ud)if ReuseOutput(ud), str='reuse';else str='noreuse';end% ---------------------------------------------------------------function ConfigGUI_ReuseState(ud, reuseIsOn)if nargin<2, reuseIsOn = ReuseOutput(ud);end% Get list of handles to this menu AND all peer context% menu items:h = get(ud.h.ReuseOutput,'userdata');if reuseIsOn, newState='on'; else newState='off'; endset(h,'checked',newState);% Update toolbar button:set(ud.h.ReuseOutputButton,'state',newState);UpdateGUI(ud.h.Fig);% ---------------------------------------------------------------function ReuseOutputToggle(hco, eventStruct)% Toggle state of ReuseOutput menu optionhfig = gcbf;ud = get(hfig,'userdata');ConfigGUI_ReuseState(ud, ~ReuseOutput(ud));% ---------------------------------------------------------------function mode = isSizeMode(ud)% Determine user input mode from checked menu item% Returns true if in "matrix size list" mode,% false if MATLAB "expression" modemode = strcmpi(get(ud.h.SpecifySizes,'checked'),'on');% ---------------------------------------------------------------function ConfigGUI_SizeAndExpressionState(ud, sizeMode)if nargin<2, sizeMode = isSizeMode(ud); end% Configure prompts:%if sizeMode, % Matrix size mode: prompt = 'Matrix size list:'; RandomEna = 'on';else % MATLAB Expression mode: prompt = 'Expression:'; RandomEna = 'off';endset(ud.h.MatrixSizesText,'string',prompt);set([ud.h.RandomButton ud.h.RandomMenu],'enable',RandomEna);% Update size/expression menu checks and button states:%h=get(ud.h.SpecifyExpression,'userdata');hExpr = h(1:2);hSizes = h(3:4);if sizeMode, set(hSizes,'checked','on'); set(ud.h.SpecifySizesButton,'state','on'); set(hExpr,'checked','off'); set(ud.h.SpecifyExpressionButton,'state','off'); else set(hExpr,'checked','on'); set(ud.h.SpecifyExpressionButton,'state','on'); set(hSizes,'checked','off'); set(ud.h.SpecifySizesButton,'state','off');end% ---------------------------------------------------------------function SpecifyExpression(hco, eventStruct, hfig)if nargin<3, hfig = gcbf; endud = get(hfig,'userdata');sizeMode = isSizeMode(ud);% Always put into selected mode, in case toggle% button pressed a second time:ConfigGUI_SizeAndExpressionState(ud, 0);% If already in this mode, skip out:if ~sizeMode, return; end% Put in default expression:%defstr='rand(4,5)*magic(5)*rand(5,3)';set(ud.h.MatrixSizes,'string',defstr);UpdateGUI(ud.h.Fig);% ---------------------------------------------------------------function SpecifySizes(hco, eventStruct, hfig)if nargin<3, hfig = gcbf; endud = get(hfig,'userdata');sizeMode = isSizeMode(ud);ConfigGUI_SizeAndExpressionState(ud, 1);% If already in this mode, skip out:if sizeMode, return; end% Put in default expression:%ChangeRandomMatrixSizes;%defstr='{[4 5][5 5][5 3]}';%set(ud.h.MatrixSizes,'string',defstr);%UpdateGUI(ud.h.Fig);% ---------------------------------------------------------------function ConfigGUIforUserSpec(hfig)% Configure the GUI for the selected user specification mode% The two modes are:% - Specify MATLAB Expression, and% - Specify Matrix Sizesud = get(hfig,'userdata');ConfigGUI_SizeAndExpressionState(ud);ConfigGUI_ReuseState(ud);% ---------------------------------------------------------------function ChangeRandomMatrixSizes(hco, eventStruct)% Generate list of random matrix sizes,% then perform optimization.hfig = gcbf;ud = get(hfig,'userdata');% Generate random integers in range [2,5].% This yields 2 to 5 matrix size entries:N = 2+round(4*rand+.5);% Generate random size elements in range [1,20]S = 1+round(19 * rand(1,N));xstr='{';for i=1:N-1, xstr=[xstr mat2str(S([i i+1])) ',' ];endxstr=[xstr(1:end-1) '}'];% Put string into GUI, as if user typed expression:set(ud.h.MatrixSizes,'string',xstr);% Perform optimization:UpdateGUI(ud.h.Fig);% ---------------------------------------------------------------function ChangeMatrixSizes(hco, eventStruct)hfig = gcbf;ud = get(hfig,'userdata');UpdateGUI(ud.h.Fig);% ---------------------------------------------------------------function ListCallback(hco, eventStruct, hfig)if nargin<3, hfig = gcbf; endud = get(hfig,'userdata');i = get(ud.h.ResultList,'value');if i==1, ena='off';else ena='on';endset([ud.h.BuildButton ud.h.BuildMenu],'enable',ena);% ---------------------------------------------------------------function GenProgram(hco, eventStruct)% Generate program to execute the selected solution% using 2-matrix multiplies.hfig = gcbf;ud = get(hfig,'userdata');i = get(ud.h.ResultList,'value');% First line of list box is a title line, and we cannot% generate a program based on that.if i>1, i=i-1; UpdateStatus(hfig,'Generating program...'); yc = ChainMultProg(ud.Results,i); tname = [tempname '.m']; fid=fopen(tname,'wt'); for i=1:size(yc,1), fprintf(fid,'%s\n',yc(i,:)); end fclose(fid); edit(tname); UpdateStatus(hfig,'Ready.');end% ---------------------------------------------------------------function ResizeFigure(hfig, eventData)% ResizeFigure GUI layout manager. if nargin<1, hfig = gcbf; endud = get(hfig,'userdata');if isempty(ud), return; endfigpos = get(hfig,'pos');% Resize list box:%relOffset = get(ud.h.ResultList,'userdata');orig_list_pos = relOffset(5:8);relOffset = relOffset(1:4);newPos = [relOffset(1:2) max(60,figpos(3:4)-relOffset(3:4)) ];set(ud.h.ResultList, 'pos', newPos);list_end_y = newPos(2)+newPos(4);% Resize matrix-size text:%u = get(ud.h.MatrixSizesText,'userdata');orig_figpos = u(1:4);orig_textpos = u(5:8);newPos = get(ud.h.MatrixSizesText,'pos');%% Adjust starting height:new_start_y = figpos(4) - orig_figpos(4) + orig_textpos(2);%% Maintain vertical gutter between text and list box top:orig_gutter = orig_textpos(2) - (orig_list_pos(2)+orig_list_pos(4));curr_gutter = new_start_y - list_end_y;if curr_gutter < orig_gutter, % adjust y start new_start_y = orig_gutter + list_end_y;endnewPos(2) = new_start_y;set(ud.h.MatrixSizesText,'pos',newPos);% Resize edit box:%u = get(ud.h.MatrixSizes,'userdata');orig_figpos = u(1:4);orig_editpos = u(5:8);orig_edittop = orig_editpos(2) + orig_editpos(4);desired_edit_top = figpos(4) - orig_figpos(4) + orig_edittop;desired_edit_bottom = desired_edit_top - orig_editpos(4);fig_edit_gutter = orig_figpos(3) - (orig_editpos(1)+orig_editpos(3));desired_edit_end_x = figpos(3) - fig_edit_gutter;curr_editpos = get(ud.h.MatrixSizes,'pos');desired_width = max(120, desired_edit_end_x - curr_editpos(1));newPos = [orig_editpos(1) desired_edit_bottom desired_width orig_editpos(4)];%% Maintain vertical gutter between edit and list box:orig_gutter = orig_editpos(2) - (orig_list_pos(2)+orig_list_pos(4));curr_gutter = desired_edit_bottom - list_end_y;if curr_gutter < orig_gutter, % adjust y start desired_edit_bottom = orig_gutter + list_end_y; newPos(2) = desired_edit_bottom;end curr_editpos = newPos;set(ud.h.MatrixSizes, 'pos', newPos);if 0 % xxx % Random button:%figOffset = [figpos(3:4) 0 0];relOffset = get(ud.h.RandomButton,'userdata');orig_buttonpos = relOffset(5:8);relOffset = relOffset(1:4);newPos = relOffset+figOffset;curr_start_x = newPos(1);%% Maintain horiz gutter between end of edit box and buttons:orig_gutter = orig_buttonpos(1) - (orig_editpos(1)+orig_editpos(3));curr_edit_dx = curr_editpos(1)+curr_editpos(3);curr_gutter = curr_start_x - curr_edit_dx;if curr_gutter < orig_gutter, curr_start_x = orig_gutter + curr_edit_dx; newPos(1) = curr_start_x;endsave_start_x = newPos(1);save_orig_y = orig_buttonpos(2);%% Maintain vertical gutter between button and list box:desired_button_bottom = newPos(2);orig_gutter = orig_buttonpos(2) - (orig_list_pos(2)+orig_list_pos(4));curr_gutter = desired_button_bottom - list_end_y;if curr_gutter < orig_gutter, % adjust y start desired_button_bottom = orig_gutter + list_end_y; newPos(2) = desired_button_bottom;end save_start_y = newPos(2);set(ud.h.RandomButton, 'pos', newPos);% Build button:%relOffset = get(ud.h.BuildButton,'userdata');orig_buttonpos = relOffset(5:8);relOffset = relOffset(1:4);newPos = relOffset+figOffset;%% Maintain horiz gutter between end of edit box and buttons:newPos(1) = save_start_x;%% Maintain vertical gutter between button and list box:newPos(2) = save_start_y + orig_buttonpos(2) - save_orig_y;set(ud.h.BuildButton, 'pos', newPos);end% ---------------------------------------------------------------function InitGUI%InitGUI Create and initialize new GUI windowh=CreateGUI;UpdateGUI(h.Fig);% ---------------------------------------------------------------function h=CreateGUI% CreateGUI Create new GUI windowbgc=get(0,'defaultuicontrolback');cbh = @ResizeFigure;h.Fig=figure('numbertitle','off', ... 'menu','none', ... 'name','Chain Multiplication Optimization', ... 'paperpositionmode','auto', ... 'integerhandle','off', ... 'units','norm', ... 'resizefcn', cbh, ... 'color',bgc, ... 'pos',[.1 .2 .55 .35]);set(h.Fig,'units','pix');figpos=get(h.Fig,'pos');%bgc=get(h.Fig,'color');% GUI Elements:%h.ResultList = uicontrol('style','listbox', ... 'units','norm', ... 'backgr', 'w', ... 'fontname','courier', ... 'callback', @ListCallback, ... 'pos',[.025 .1 .965 .68]);set(h.ResultList,'units','pix');% Relative offset/size from top rightset(h.ResultList, 'units','pix');pos=get(h.ResultList,'pos');relOffset = [pos(1:2) figpos(3:4)-pos(3:4) pos];set(h.ResultList,'userdata',relOffset);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -