Code covered by the BSD License  

Highlights from
Preferred Number Sequences

image thumbnail
from Preferred Number Sequences by Stephen Cobeldick
Generate vectors of "Preferred Number Sequence" values.

prefnum(rng,def,mrg,varargin)
function vec = prefnum(rng,def,mrg,varargin)
% Return a vector of Preferred Number Sequence values.
%
% (c) 2013 Stephen Cobeldick
%
% ### Function ###
%
% Return a vector of Preferred Number Sequence (PNS) values, selecting
% from any inbuilt PNS or defining custom numeric or function handle PNS.
%
% By default the vec values are the smallest sequence that encompasses the
% minimum and maximum values of input rng (a numeric scalar/vector/matrix).
% Optional input mrg selects a two-value margin around the min and max values.
%
% Syntax:
%  vec = prefnum(rng,StrTok)     % Select an inbuilt PNS using a string token.
%  vec = prefnum(rng,NumVec)     % Define a custom PNS using a numeric vector.
%  vec = prefnum(rng,FunHdl)     % Define a custom PNS using a function handle.
%  vec = prefnum(rng, ...  ,mrg) % Tight fit or margin around min&max of rng.
%
% See also HISTB HISTC HIST LOG10 PCHIP ROUND2SF ROUND2DP DATEROUND ROUND
%
% ### Examples ###
%
% prefnum([1,20],'E6')
%  ans = [1,1.5,2.2,3.3,4.7,6.8,10,15,22]
%
% prefnum([1,20],'125',true)
%  ans = [0.2,0.5,1,2,5,10,20,50,100]
%
% prefnum([1,20],[100,316])
%  ans = [1,3.16,10,31.6]
%
% prefnum([1,20],@(x)3*x)
%  ans = [0,3,6,9,12,15,18,21]
%
% ### Rounding to PNS Values ###
%
% X = [514,1.9;7.6,37]           % Matrix of finite positive values to round.
%
% vec = prefnum(X,'E6',true)     % Vector of 'E6' component values.
% [n,bin,edg] = histb(X,vec,'harmonic') % Place X-values into bins.
% vec(bin+1)                     % Use bin indices to select component values.
%  ans = [470,2.2;6.8,33]        % Best match to X, matching tolerances.
%
% vec = prefnum(X,'125',true)    % Generate vector of '125' series.
% [n,bin,edg] = histb(X,vec,'geometric') % Place X-values into bins.
% vec(bin+1)                     % Use bin indices to select series values.
%  ans = [500,2;10,50]           % Best match, closest geometrically.
%
% vec = prefnum(X,@(v)5*v,true)  % Generate vector of multiples of five.
% [n,bin,edg] = histb(X,vec,'arithmetic') % Place X-values into bins.
% vec(bin+1)                     % Use bin indices to select PNS values.
%  ans = [515,0;10,35]           % Best match, bin-edges at midpoints.
%
% # Find the paper size that fits the given dimension:
% Y = 234                        % Want paper side >= this dimension.
% vec = prefnum(Y,'paperA',true) % Generate vector of paper edge sizes.
% [n,bin,edg]=histb(Y,vec,'position',true) % Place Y-value into bins.
% vec(bin+[-1,0])                % Use bin indices to select paper size.
%  ans = [210,297]               % A4 paper is >= dimension Y.
%
% ### Inbuilt PNS String Tokens (StrTok) ###
%
% Repeating PNS are marked with 'R', Complete PNS with 'C'. The range
% for Repeating PNS = 0<rng<Inf, and for Complete PNS = -Inf<=rng<=Inf.
%
% PNS Series:   | StrTok Tokens:                                     Range:
% -------------------------------------------------------------------------
% 1-2-5         | 125  |      |      |      |      |      |      |      | R
% -------------------------------------------------------------------------
% Renard        | R5   | R10  | R20  | R40  | R80  |      |      |      | R
%               |------|------|------|------|------|------|------|------|--
%               | R'5  | R'10 | R'20 | R'40 |      |      |      |      | R
%               |------|------|------|------|------|------|------|------|--
%               | R"5  | R"10 | R"20 |      |      |      |      |      | R
% -------------------------------------------------------------------------
% Electronic    | E3   | E6   | E12  | E24  | E48  | E96  | E192 |      | R
% -------------------------------------------------------------------------
% Screw Thread  | M261 | M262 |      |      |      |      |      |      | C
% -------------------------------------------------------------------------
% Camera f-stop | f-full      | f-half      | f-third     | f-quarter   | C
% -------------------------------------------------------------------------
% Wire X-section| wire |      |      |      |      |      |      |      | C
% -------------------------------------------------------------------------
% Pen Thickness | pen  |      |      |      |      |      |      |      | C
% -------------------------------------------------------------------------
% Paper Length  | paperA      | paperB      | paperC      |      |      | C
% =========================================================================
%
% PNS Series:   | Definition:
% -------------------------------------------------------------------------
% 1-2-5         | [..,1,2,5,10,20,50,100,..] (= Renard R3 to one sig-fig)
% -------------------------------------------------------------------------
% Renard        | ISO 3, ISO 17, ISO 497 (fuse ratings, transformer power)
% -------------------------------------------------------------------------
% Electronic    | IEC 60063 (resistors, capacitors, inductors, zener diodes)
% -------------------------------------------------------------------------
% Screw Thread  | ISO 261, ISO 262  (from M1 to M64 / from 1mm to 64mm)
% -------------------------------------------------------------------------
% Camera f-stop | lens focal ratio (from 0.7 to 256)
% -------------------------------------------------------------------------
% Wire X-section| IEC 60228 (wire cross-section areas from 0.5mm^2 to 1000mm^2)
% -------------------------------------------------------------------------
% Pen Thickness | [0.13,0.18,0.25,0.35,0.5,0.7,1,1.4,2] (ISO 128 line widths)
% -------------------------------------------------------------------------
% Paper Length  | A, B & C series paper side lengths (mm) (ISO 216 & ISO 269)
% =========================================================================
%
% ### Custom PNS Numeric Vectors (NumVec) ###
%
% - NumVec element values must be strictly monotonic increasing.
%
% If the sequence digits repeat each decade (repeating):
% - NumVec element values must be positive and of the same order of magnitude.
% - An optimal NumVec = 10.^((0:N-1)/N), where N = numel(one_decade_of_PNS).
% - The values of rng must be finite and positive.
%
% If the sequence digits do not repeat (complete):
% - The first element value must be -Inf, the last element value must be Inf.
%
% ### Custom PNS Function Handles (FunHdl) ###
%
% - The function FunHdl(x) must be strictly monotonic increasing with x.
% - Returns FunHdl(x) that best match the InMat values, for integer x values.
% - Solution is found using "fzero", the optional inputs may be passed as well.
%
% ### Inputs & Output ###
%
% Inputs (*=default):
%  rng = Numeric (any size), min&max values will be encompassed by the output vec.
%  def = String Token, to select an inbuilt PNS (see tables above).
%      = Numeric Vector, finite, positive, strictly monotonic increasing values.
%      = Function Handle, a scalar function in one variable, monotonic increasing.
%  mrg = Logical scalar, true/false* -> 2-value/tight margin around min&max of rng.
% If using a function handle defined PNS, the following are passed to "fzero":
%  x0  = Numeric Scalar, an optional seed value, *mean(rng).
%  opt = Struct, optional settings structure.
%
% Output:
%  vec = Vector of PNS values ecompassing the min&max of rng, sequence defined by def.
%
% Inputs = (rng,def,mrg*,x0*,opt*)
% Output = vec

assert(isnumeric(rng),'Argument rng must be a numeric matrix/vector/scalar.')
rng = rng(:);
rmn = min(rng);
rmx = max(rng);
%
IsT = nargin<3||~mrg;
IsR = false;
%
if isnumeric(def) % Numeric
    def = def(:);
    assert(all(0<=diff(def)),'Numeric vector must be strictly monotonic increasing.')
    IsI = isinf(def);
    IsR = ~(IsI(1)||IsI(end));
    if IsR % Repeating PNS
        ord = floor(log10([min(def),max(def)]));
        assert(0==diff(ord),'Repeating PNS numeric elements must be same order of magnitude.')
        ord = ord(1);
    else
        vec = def;
    end
    %
elseif strncmp('E',def,1) % Electronic
    def = PrNmElec(def);
    ord = 2;
    IsR = true;
    %
elseif strncmp('R',def,1) % Renard
    def = PrNmRnrd(def);
    ord = 2;
    IsR = true;
    %
elseif strcmp('125',def) % 1-2-5
    def = [1;2;5];
    ord = 0;
    IsR = true;
    %
elseif strncmp('f-',def,2) % Camera f-stop
    vec = PrNmFstop(def);
    %
elseif strcmp('M261',def) % Metric screw thread
    vec = [-Inf;1;1.2;1.4;1.6;1.8;2;2.5;3;3.5;4;5;6;7;8;10;12;...
        14;16;18;20;22;24;27;30;33;36;39;42;45;48;52;56;60;64;Inf];
    %
elseif strcmp('M262',def) % Metric screw thread
    vec = [-Inf;1;1.2;1.6;2;2.5;3;4;5;6;8;10;12;16;20;24;30;36;42;48;56;64;Inf];
    %
elseif strcmp('wire',def) % Wire cross-section
    vec = [-Inf;0.5;0.75;1;1.5;2.5;4;6;10;16;25;35;50;70;...
        95;120;150;185;240;300;400;500;630;800;1000;Inf];
    %
elseif strcmp('pen',def) % Pen thickness
    vec = [-Inf;0.13;0.18;0.25;0.35;0.5;0.7;1;1.4;2;Inf];
    %
elseif strncmp('paper',def,5) % Paper Length
    vec = PrNmPaper(def);
    %
elseif isa(def,'function_handle') % Function Handle
    ErSt = 'No finite and real solution found such that %s=%6.4f.';
    % "fzero" optional arguments:
    DfAr = {mean(rng),struct('Display','notify','TolX',eps,...
    'FunValCheck','on','OutputFcn',[],'PlotFcns',[])};
    DfAr(1:numel(varargin)) = varargin;
    % Find min and max of PNS range:
    VlN = floor(fzero(@(x)def(x)-rmn,DfAr{1},DfAr{2}));
    assert(isfinite(VlN)&&isreal(VlN),ErSt,func2str(def),rmn)
    VlX =  ceil(fzero(@(x)def(x)-rmx,DfAr{1},DfAr{2}));
    assert(isfinite(VlX)&&isreal(VlX),ErSt,func2str(def),rmx)
    % PNS vector:
    vec = arrayfun(def,VlN-2:2+VlX).';
    %
else
    error('def is not supported.')
end
%
if IsR % Repeating PNS
    assert(rmn>0&&rmx>0,'The values of rng must be positive (repeating sequences only).')
    % Order of magnitude required:
    Pn = floor(log10(rmn));
    Px = ceil(log10(rmx));
    % Extrapolate PNS vector:
    switch numel(def)
        case 1
            vec = (def*10.^(Pn-2:2+Px)).'/10^ord;
        case 2
            vec = def*10.^(Pn-1:1+Px);
            vec = vec(:)/10^ord;
        otherwise
            vec = def*10.^(Pn:Px);
            vec = [def(end-1:end).*10^(Pn-1);vec(:);def(1:2).*10^(Px+1)]/10^ord;
    end
end
%
% Trim the PNS vector:
if IsT % Tight fit to rmn & rmx
    vec = vec([rmn<vec(2:end);true]&[true;vec(1:end-1)<rmx]).';
else % 2-value margin around rmn and rmx
    vec = vec([rmn<=vec(3:end);true;true]&[true;true;vec(1:end-2)<=rmx]).';
end
%
end
%--------------------------------------------------------------------------
function V = PrNmElec(def)
% Electronic PNS (IEC 60063)
%
switch def
    case 'E3'
        V =[100;220;470];
    case 'E6'
        V =[100;150;220;330;470;680];
    case 'E12'
        V =[100;120;150;180;220;270;330;390;470;560;680;820];
    case 'E24'
        V =[100;110;120;130;150;160;180;200;220;240;270;300;...
            330;360;390;430;470;510;560;620;680;750;820;910];
    case 'E48'
        V =[100;105;110;115;121;127;133;140;147;154;162;169;...
            178;187;196;205;215;226;237;249;261;274;287;301;...
            316;332;348;365;383;402;422;442;464;487;511;536;...
            562;590;619;649;681;715;750;787;825;866;909;953];
    case 'E96'
        V =[100;102;105;107;110;113;115;118;121;124;127;130;...
            133;137;140;143;147;150;154;158;162;165;169;174;...
            178;182;187;191;196;200;205;210;215;221;226;232;...
            237;243;249;255;261;267;274;280;287;294;301;309;...
            316;324;332;340;348;357;365;374;383;392;402;412;...
            422;432;442;453;464;475;487;499;511;523;536;549;...
            562;576;590;604;619;634;649;665;681;698;715;732;...
            750;768;787;806;825;845;866;887;909;931;953;976];
    case 'E192'
        V =[100;101;102;104;105;106;107;109;110;111;113;114;...
            115;117;118;120;121;123;124;126;127;129;130;132;...
            133;135;137;138;140;142;143;145;147;149;150;152;...
            154;156;158;160;162;164;165;167;169;172;174;176;...
            178;180;182;184;187;189;191;193;196;198;200;203;...
            205;208;210;213;215;218;221;223;226;229;232;234;...
            237;240;243;246;249;252;255;258;261;264;267;271;...
            274;277;280;284;287;291;294;298;301;305;309;312;...
            316;320;324;328;332;336;340;344;348;352;357;361;...
            365;370;374;379;383;388;392;397;402;407;412;417;...
            422;427;432;437;442;448;453;459;464;470;475;481;...
            487;493;499;505;511;517;523;530;536;542;549;556;...
            562;569;576;583;590;597;604;612;619;626;634;642;...
            649;657;665;673;681;690;698;706;715;723;732;741;...
            750;759;768;777;787;796;806;816;825;835;845;856;...
            866;876;887;898;909;920;931;942;953;965;976;988];
    otherwise
        error('Electronic token "%s" is not supported.',def)
end
%
end
%--------------------------------------------------------------------------
function V = PrNmRnrd(def)
% Renard PNS (ISO 3:1973, ISO 17:1973, ISO 497:1973)
%
switch def
    case 'R5'
        V =[100;160;250;400;630];
    case 'R10'
        V =[100;125;160;200;250;315;400;500;630;800];
    case 'R20'
        V =[100;112;125;140;160;180;200;224;250;280;...
            315;355;400;450;500;560;630;710;800;900];
    case 'R40'
        V =[100;106;112;118;125;132;140;150;160;170;...
            180;190;200;212;224;236;250;265;280;300;...
            315;335;355;375;400;425;450;475;500;530;...
            560;600;630;670;710;750;800;850;900;950];
    case 'R80'
        V =[100;103;106;109;112;115;118;122;125;128;...
            132;136;140;145;150;155;160;165;170;175;...
            180;185;190;195;200;206;212;218;224;230;...
            236;243;250;258;265;272;280;290;300;307;...
            315;325;335;345;355;365;375;387;400;412;...
            425;437;450;462;475;487;500;515;530;545;...
            560;580;600;615;630;650;670;690;710;730;...
            750;775;800;825;850;875;900;925;950;975];
    case 'R''5' % Not defined by ISO.
        V =[100;160;250;400;630];
    case 'R''10'
        V =[100;125;160;200;250;320;400;500;630;800];
    case 'R''20'
        V =[100;110;125;140;160;180;200;220;250;280;...
            320;360;400;450;500;560;630;710;800;900];
    case 'R''40'
        V =[100;105;110;120;125;130;140;150;160;170;...
            180;190;200;210;220;240;250;260;280;300;...
            320;340;360;380;400;420;450;480;500;530;...
            560;600;630;670;710;750;800;850;900;950];
    case 'R"5'
        V =[100;150;250;400;600];
    case 'R"10'
        V =[100;120;150;200;250;300;400;500;600;800];
    case 'R"20'
        V =[100;110;120;140;150;180;200;220;250;280;...
            300;350;400;450;500;550;600;700;800;900];
    otherwise
        error('Renard token "%s" is not supported.',def)
end
%
end
%--------------------------------------------------------------------------
function V = PrNmFstop(def)
% Camera f-stops
%
switch def
    case 'f-full'
        V =[-Inf;0.7;1;1.4;2;2.8;4;5.6;8;11;16;22;32;45;64;90;128;180;256;Inf];
    case 'f-half'
        V =[-Inf;0.7;0.8;1;1.2;1.4;1.7;2;2.4;2.8;3.3;4;4.8;5.6;6.7;8;9.5;...
            11;13;16;19;22;27;32;38;45;53;64;76;90;128;152;180;215;256;Inf];
    case 'f-third'
        V =[-Inf;0.7;0.8;0.9;1;1.1;1.2;1.4;1.6;1.8;2;2.2;2.5;2.8;3.2;3.5;4;...
            4.5;5;5.6;6.3;7.1;8;9;10;11;13;14;16;18;20;22;25;28;32;36;40;45;...
            50;57;64;71;80;90;101;114;128;143;128;143;161;181;203;228;256;Inf];
    case 'f-quarter'
        V =[-Inf;0.7;0.8;0.85;0.9;1;1.1;1.2;1.3;1.4;1.5;1.7;1.8;2;2.2;2.4;...
            2.6;2.8;3;3.4;3.7;4;4.4;4.8;5.2;5.6;6.2;6.7;7.3;8;8.7;9.5;10;...
            11;12;13.5;15;16;17;19;21;22;25;27;29;32;35;38;41;45;49;54;...
            59;64;70;83;90;99;107;128;140;152;166;181;197;215;235;256;Inf];
    otherwise
        error('Camera f-stop token "%s" is not supported.',def)
end
%
end
%--------------------------------------------------------------------------
function V = PrNmPaper(def)
% ISO 216 and ISO 296 paper side lengths for A, B and C series.
%
switch def
    case 'paperA'
        V =[-Inf;26;37;52;74;105;148;210;297;420;594;841;1189;Inf];
    case 'paperB'
        V =[-Inf;31;44;62;88;125;176;250;353;500;707;1000;1414;Inf];
    case 'paperC'
        V =[-Inf;28;40;57;81;114;162;229;324;458;648;917;1297;Inf];
    otherwise
        error('Paper side length token "%s" is not supported.',def)
end
%
end
%----------------------------------------------------------------------End!

Contact us