V_FINISHAT print estimated finish time of a long computation (FRAC,TOL,FMT) Usage: (1) for i=1:many v_finishat((i-1)/many); % initializes on first pass when i=1 ... computation ... end (3) v_finishat(0); % explicit initialization before loop for i=1:many ... computation ... v_finishat(i/many); % calculate fraction completed end (5) for i=MI:NI for j=MJ:NJ for k=MK:NK v_finishat([i MI NI; j MJ NJ; k MK NK]); % one row per nested loop ... computation ... end end end (6) for i=MI:DI:NI for j=MJ:DJ:NJ for k=MK:DK:NK v_finishat([i MI DI NI; j MJ DJ NJ; k MK DK NK]); % one row per nested loop ... computation ... end end end Inputs: FRAC = fraction of total comutation that has been completed Alternatively at start of inner loop: [i MI DI NI; j MJ DJ NJ; k MK DK NK; ...] where i, j, k are nested loop indices and MI:DI:NI, MJ:DJ:NJ, MK:DK:NK their limits. If the DI, DJ, DK, ... all equal 1 The may be omitted. Use k+1 instead of k if placed at the end of the inner loop. As a special case, FRAC=0 initializes the routine. TOL = Tolerance in minutes. If the estimated time has changed by less than this, then nothing will be printed. [default 10% of remaining time] FMT = Format string which should include: %s for estimated finish time %d for remaining minutes %t for remaining hr:min:sec %f for fraction complete %p for % complete The %t, %f and %p options can include optional width and/or decimal-place dimensions (e.g. %.2f) Output: ETA = string containing the expected finish time specifying this will suppress printing message to std err (fid=2) ETAF = expected finish time as a daynumber Example: v_finishat(0); for i=1:many long computation; v_finishat(i/many); end
0001 function [eta,etaf]=v_finishat(frac,tol,fmt) 0002 %V_FINISHAT print estimated finish time of a long computation (FRAC,TOL,FMT) 0003 % Usage: (1) for i=1:many 0004 % v_finishat((i-1)/many); % initializes on first pass when i=1 0005 % ... computation ... 0006 % end 0007 % 0008 % (3) v_finishat(0); % explicit initialization before loop 0009 % for i=1:many 0010 % ... computation ... 0011 % v_finishat(i/many); % calculate fraction completed 0012 % end 0013 % 0014 % (5) for i=MI:NI 0015 % for j=MJ:NJ 0016 % for k=MK:NK 0017 % v_finishat([i MI NI; j MJ NJ; k MK NK]); % one row per nested loop 0018 % ... computation ... 0019 % end 0020 % end 0021 % end 0022 % 0023 % (6) for i=MI:DI:NI 0024 % for j=MJ:DJ:NJ 0025 % for k=MK:DK:NK 0026 % v_finishat([i MI DI NI; j MJ DJ NJ; k MK DK NK]); % one row per nested loop 0027 % ... computation ... 0028 % end 0029 % end 0030 % end 0031 % 0032 % Inputs: FRAC = fraction of total comutation that has been completed 0033 % Alternatively at start of inner loop: [i MI DI NI; j MJ DJ NJ; k MK DK NK; ...] where i, j, k are 0034 % nested loop indices and MI:DI:NI, MJ:DJ:NJ, MK:DK:NK their limits. If the DI, DJ, DK, ... all equal 1 0035 % The may be omitted. Use k+1 instead of k if placed at the end of the inner loop. 0036 % As a special case, FRAC=0 initializes the routine. 0037 % TOL = Tolerance in minutes. If the estimated time has changed by less 0038 % than this, then nothing will be printed. [default 10% of remaining time] 0039 % FMT = Format string which should include: 0040 % %s for estimated finish time 0041 % %d for remaining minutes 0042 % %t for remaining hr:min:sec 0043 % %f for fraction complete 0044 % %p for % complete 0045 % The %t, %f and %p options can include optional width and/or decimal-place dimensions (e.g. %.2f) 0046 % 0047 % Output: ETA = string containing the expected finish time 0048 % specifying this will suppress printing message to std err (fid=2) 0049 % ETAF = expected finish time as a daynumber 0050 % 0051 % Example: v_finishat(0); 0052 % for i=1:many 0053 % long computation; 0054 % v_finishat(i/many); 0055 % end 0056 0057 % Copyright (C) Mike Brookes 1998-2023 0058 % Version: $Id: v_finishat.m 10865 2018-09-21 17:22:45Z dmb $ 0059 % 0060 % VOICEBOX is a MATLAB toolbox for speech processing. 0061 % Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html 0062 % 0063 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0064 % This program is free software; you can redistribute it and/or modify 0065 % it under the terms of the GNU General Public License as published by 0066 % the Free Software Foundation; either version 2 of the License, or 0067 % (at your option) any later version. 0068 % 0069 % This program is distributed in the hope that it will be useful, 0070 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0071 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0072 % GNU General Public License for more details. 0073 % 0074 % You can obtain a copy of the GNU General Public License from 0075 % http://www.gnu.org/copyleft/gpl.html or by writing to 0076 % Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. 0077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0078 0079 persistent oldt oldnw tstart 0080 [nf,nv]=size(frac); 0081 if nargin<3 0082 fmt='Estimated finish at %s (%.0p done, %t remaining)\n'; 0083 end 0084 if isempty(tstart) || nv<3 && all(frac(:,1)<=[ones(nf-1,1); 0]) || nv>=3 && all(frac(:,1)==frac(:,2)) % initialize if fraction done is <=0 0085 oldt=0; 0086 eta='Unknown'; 0087 tstart=tic; 0088 else 0089 if nv==2 % obsolete format that assumes all loop indices start at 1 0090 fp=cumprod(frac(:,2)); 0091 frac=sum((frac(:,1)-1)./fp)+1/fp(end); 0092 elseif nv==3 0093 fp=cumprod(frac(:,3)-frac(:,2)+1); 0094 frac=sum((frac(:,1)-frac(:,2))./fp); 0095 else 0096 fp=cumprod(floor((frac(:,4)-frac(:,2))./frac(:,3))+1); 0097 frac=sum(round((frac(:,1)-frac(:,2))./frac(:,3))./fp); 0098 end 0099 nw=now; % current time as serial number 0100 sectogo=(1/frac-1)*toc(tstart); % seconds to go 0101 newt=nw+sectogo/86400; % add estimated time in days 0102 if nargin<2 || ~numel(tol) 0103 tol=max(0.1*(newt-nw)*1440,1); 0104 end 0105 if ~exist('oldt','var') || length(oldt)~=1 || oldt==0 || (abs(newt-oldt)>tol/1440 && (nw-oldnw)>10/86400) || (nw-oldnw)>10/1440 || nargout>0 0106 oldt=newt; 0107 if floor(oldt)==floor(nw) 0108 df='HH:MM'; 0109 else 0110 df='HH:MM dd-mmm-yyyy'; 0111 end 0112 eta=datestr(oldt,df); 0113 if ~nargout 0114 ix=find(fmt=='%',1); 0115 while ~isempty(ix) 0116 fprintf(2,fmt(1:ix-1)); 0117 fmt=fmt(ix:end); 0118 ix=find(fmt>='a' & fmt<='z',1); % find letter 0119 switch fmt(ix) 0120 case 's' 0121 fprintf(2,fmt(1:ix),eta); 0122 case 'd' 0123 fprintf(2,fmt(1:ix),round(sectogo/60)); 0124 case 'f' 0125 if ix>2 0126 fprintf(2,fmt(1:ix),frac); 0127 else 0128 fprintf(2,'%.2f',frac); 0129 end 0130 case 'p' 0131 if ix>2 0132 fprintf(2,[fmt(1:ix-1) 'f%%'],frac*100); 0133 else 0134 fprintf(2,'%.0f%%',frac*100); 0135 end 0136 case 't' 0137 if ix>2 0138 if sectogo>=3600 0139 fprintf(2,[fmt(1:ix-1) 'f hr'],sectogo/3600); 0140 elseif sectogo>=60 0141 fprintf(2,[fmt(1:ix-1) 'f min'],sectogo/60); 0142 else 0143 fprintf(2,[fmt(1:ix-1) 'f sec'],sectogo); 0144 end 0145 else 0146 if sectogo>=36000 0147 fprintf(2,'%.0f hr',sectogo/3600); 0148 elseif sectogo>=3600 0149 fprintf(2,'%.1f hr',sectogo/3600); 0150 elseif sectogo>=600 0151 fprintf(2,'%.0f min',sectogo/60); 0152 elseif sectogo>=60 0153 fprintf(2,'%.1f min',sectogo/60); 0154 else 0155 fprintf(2,'%.0f sec',sectogo); 0156 end 0157 end 0158 end 0159 fmt=fmt(ix+1:end); 0160 ix=find(fmt=='%',1); 0161 end 0162 fprintf(2,fmt); 0163 end 0164 oldnw=nw; % 0165 end 0166 end 0167 etaf=oldt;