Date: Wed, 17 Apr 1996 21:01:49 GMT
Reply-To: Michael Friendly <friendly@HOTSPUR.PSYCH.YORKU.CA>
Sender: "SAS(r) Discussion" <SAS-L@UGA.CC.UGA.EDU>
From: Michael Friendly <friendly@HOTSPUR.PSYCH.YORKU.CA>
Organization: York University, Ontario, Canada
Subject: Finding the number of decimals in an IML matrix
Here's a problem that seems to point to either a flaw in my thinking
or a bug in SAS/IML.
I'm working on a general routine to print
multidimensional arrays, and need to determine the field width and
number of decimal places. I'm using the mod function in a loop to
find the first decimal place where all remainders are zero.
t = mod(abs(table),1);
do dec = 1 to maxdec until( max(t)<.001 );
t = mod((10##dec)#abs(table),1);
minmax = max(t) || sum(t > .1);
print dec (10##-dec) minmax;
print 'remainders', t;
end;
For a 2-decimal table like this, the loop should stop after two iterations,
but it doesn't (always). mod(number,1) or number - int(number) should
always return a fraction less than 1, but don't seem to. WHY???
Here's some output. I'll include a complete
program (just for this part) at the end, in case someone wants to play with
it
TABLE
945.81 986.63 460.59 730.36 238.34 363.17 943.16 586.99 503.8
943.19 929.82 480.89 652.31 611.29 418.31 709.56 447.54 288.22
621.26 723.58 45.29 414.13 979.55 294.81 827.86 943.32 769.95
843.95 555.65 657.07 218.15 493.81 83.17 12.07 644.11 919.06
292.31 741.31 78.2 600.97 546.04 724.1 235.78 509.51 729.45
581.7 907.33 743 506.36 498.34 482.92 495.21 61.48 866.29
528.4 184.35 293.06 577.02 660.7 139.05 429.51 499.19 772.71
962.78 179.67 516.67 383.19 34.99 347.64 78.56 71.36 431.71
DEC #TEM1002 MINMAX
1 0.1 0.9 58
remainders
T
0.1 0.3 0.9 0.6 0.4 0.7 0.6 0.9 0
0.9 0.2 0.9 0.1 0.9 0.1 0.6 0.4 0.2
0.6 0.8 0.9 0.3 0.5 0.1 0.6 0.2 0.5
0.5 0.5 0.7 0.5 0.1 0.7 0.7 0.1 0.6
0.1 0.1 0 0.7 0.4 0 0.8 0.1 0.5
0 0.3 0 0.6 0.4 0.2 0.1 0.8 0.9
0 0.5 0.6 0.2 0 0.5 0.1 0.9 0.1
0.8 0.7 0.7 0.9 0.9 0.4 0.6 0.6 0.1
[so far, so good]
DEC #TEM1002 MINMAX
2 0.01 1 2
remainders
T
0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 36E-13
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
73E-13 0 0 0 0 0 0 0 0
0 0 0 0 0 18E-13 0 0 0
0 0 1 0 0 0 0 0 0
[why these 1's??]
DEC #TEM1002 MINMAX
3 0.001 1 1
remainders
T
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0
[next iteration deleted]
FW DEC
Field width, decimals 9 4
-- Here's the program ---
proc iml;
start mdprint(dim, table, vnames, lnames)
global (ls, maxdec);
if type(ls) = 'U' then ls=80; *-- output linesize;
if type(maxdec) = 'U' then maxdec = 4; *-- maximum decimal places;
nf = max( nrow(dim), ncol(dim) );
dw = 60; *-- display width;
debug=0;
*-- determine field width, format;
fw = 8;
fw = 2 + floor( log10( max(abs(table)) ) ) + any( table<0 );
if all( mod(table,1) < .0001 ) then do;
dec = 0;
end;
else do;
t = mod(abs(table),1);
do dec = 1 to maxdec until( max(t)<.001 );
t = mod((10##dec)#abs(table),1);
*-- tried this way too;
* t = ((10##dec)#abs(table)) - int((10##dec)#abs(table));
minmax = max(t) || sum(t > .1);
print dec (10##-dec) minmax;
print 'remainders', t;
end;
dec = dec-1;
fw = fw + dec + 1;
end;
print 'Field width, decimals' fw dec;
** enough for now ;
finish;
reset fw=6;
dim = {8 3 3};
table = 1000 * uniform( j(dim[#], 1, 284241 ));
table = shape(table,8, 9);
table = round(table,.01);
print table;
vnames ={'Var A' 'Var B' 'Var C'};
lnames ={ A1 A2 A3 A4 A5,
B1 B2 B3 '' '',
C1 C2 C3 '' ''};
run mdprint(dim, table, vnames, lnames);
--
Michael Friendly Internet: friendly@hotspur.psych.yorku.ca (NeXTmail
OK)
Psychology Department
York University Voice: 416 736-5118
4700 Keele Street http://www.math.yorku.ca/SCS/friendly.html
Toronto, ONT M3J 1P3 CANADA