I am trying to use SAS/IML to perform computations with what in some cases are very small numbers, e.g., less than constant('maceps') and am stymied by my inability to make the expression ndx = loc( vector= max( vector )) return only one value instead of > 1 . When, for example, vector = {8.372E-26 4.63E-103}, the variable ndx will contain {0 0} because the two values in vector are smaller than constant('maceps'), which is 2.2e-16.
I am enclosing the code of an IML module which demonstrates what I want to do, and have included a listing of the inputs and outputs to and from the module for your perusal. For small values of m and p, e.g., .01, computing ( x ## p - y ## p ) ## ( 1/p ) produces values close to 1, and I see that the results include 0 in the output, or some very small number such that computing 1 + number > 1 results in False, e.g., 0, and not True, e.g., 1 .
I will be appreciative for any suggestions because I have tried strategies such as scaling the x and y values by constant('maceps'') or constant('small') but to no avail. Perturbing x[ j ] and y[ i, j ] by adding a uniform random variate in [0,1] # constant('maceps') similarly fails when 1/p is large, e.g., 1/p >> 1. For example,
proc iml ;
a =8.372E-26 ;
b= 4.63E-103 ;
p = .01 ;
c = ( a ## p + b ## p ) ## (1/p) ;
print c ;
quit ;
----------
Output:
---------
c
4.985E-19
TIA,
Ross
options nonotes ;
proc iml ;
reset storage=featclus.featclus ;
load module=_all_ ;
start compute_similarity( x, y, m, p ) ;
/* compute unweighted Lukasiewicz ("normal" (unweighted) Lukasiewicz structure) similarity
*
* purpose: compute similarity between feature vector j, class mean(s) i
*
* parameters:
* x ::= 1 x n_feature vector of features, each column normalized into [0, 1]
*
* y ::= n_class x n_feature matrix of class means, produced from normalized x features
*/
if nrow( x ) ^= 1 then run error( 'compute_similarity', 'Feature vector x must be row vector' ) ;
n_classes = nrow( y ) ; /* # of class means in class mean matrix */
n_feat = ncol( x ) ; /* # of features in x vector */
dist = j( n_classes, n_feat, . ) ;
similarity = j( 1, n_classes, . ) ;
do i = 1 to n_classes ;
do j = 1 to n_feat ;
/* compute similarity btwn x, y for each feature element x[ j ], class mean value y[ i, j ] */
dist[ i, j ] = ( 1 - abs( x[ j ] ## p - y[ i, j ] ## p )) ## ( 1 / p ) ;
end ; /* j */
end ; /* i */
/* compute similarity btwn x, y for each class mean
* dist[ i , : ]` is mean of row vector for class mean i
*/
similarity = dist[ , : ]` ## ( 1 / m ) ;
return similarity ;
finish compute_similarity ;
x = { .1 .2, .3 .4, .5 .6, .7 .8 } ;
if any( x = 0 ) then x[ loc( x=0 ) ] = constant( 'maceps' ) ;
y = { .15 .35, .351 .45 } ;
print x y ;
rslt = compute_similarity( x[1,], y, 1,1 ) ;
print rslt ;
rslt = compute_similarity( x[2,], y, .5, .5 ) ;
print rslt ;
rslt = compute_similarity( x[3,], y, .001, .01 ) ;
print rslt ;
rslt = compute_similarity( x[4,], y, .05, .05 ) ;
print rslt ;
rslt = compute_similarity( x[1,], y, 0.000024943605419, 4.148552428951820) ;
print rslt ;
***store module=compute_similarity ;
quit ; ---------- Output: ----------
x
y
0.1
0.2
0.15
0.35
0.3
0.4
0.351
0.45
0.5
0.6
0.7
0.8
rslt
0.9
0.7495
rslt
0.6600432
0.8439022
rslt
0
6.03E-139
rslt
2.496E-10
3.9649E-6
rslt
8.372E-26
4.63E-103
... View more