BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
CerditoSalvaje
Obsidian | Level 7

Hi everybody, I will explain my problem : 

 

I have a matrix with X and Y and the image of both by a funcion. Then I have 3 columns. 

I want the minimum image of the function but keeping X and Y. 

 

I have found the result but it is no so clean. I think that there is a better option. Look at the way I found it :

titi=min(pbest[,p+1]);

	/*then we iterate to assign the coordinates of this minimum to gbest*/
	do i=1 to n;
		if pbest[i,p+1]=titi then gbest=pbest[i,];
		else e=0;
	end;

and this is another option I have tried : 

 

titi=min(ncol(pbest[,p+1]));
print titi;

The idea is that I need what I have in the Row which has the minimum value in the column p+1

 

thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ

In general, you can use the LOC function to find rows that satisfy some criterion.  The LOC function is the most important function that new SAS/IML programmers need to discover.  Be aware, however, if your matrix has tied values, you might get more than one row that satisfies the criterion. In that case, I assume any row is okay? If so, take the first:

 

proc iml;
pbest = {1 2 9,
         4 5 6,
         1 3 10,
         4 1 3,
         1 1 8,
         5 2 3};
p = 2;
n = nrow(pbest);

titi=min(pbest[,p+1]);

/* 1. Use LOC to find row that satisfies criterion */
minIdx = loc(pbest[,p+1]=titi);  
gbest = pbest[minIdx, ];     /* in case of tied values, might get more than one row */
print gbest;

gbest = pbest[minIdx[1], ];  /* if you only want one row, take first */
print gbest;

In this case, the "criterion" is actually a minimum. In SAS/IML, there is a special operator (the '>:<' subscript reduction operator) that can return the row for wh... 

/* 2. For the MIN, you can also use v[>:,] to get the index directly */
v = pbest[,p+1];  
minIdx = v[>:<];
print minIdx;
gbest = pbest[minIdx, ];     /* always returns one row */
print gbest;

 

View solution in original post

3 REPLIES 3
PaigeMiller
Diamond | Level 26

You can find the minimum of a column (or minimum of a matrix, or minimum of a row) by using subscript reduction operators. https://documentation.sas.com/doc/en/imlug/15.2/imlug_workmatrix_sect025.htm

 

It's really hard to visualize what the matrix is that you have and what matrix you want by reading your description in words. Also, at one point you say "minimum of a matrix" and at other times you appear to want the minimum of a column. It would help greatly if you could provide a small example.  Show us what you have and what you want.

--
Paige Miller
CerditoSalvaje
Obsidian | Level 7

Thank you for your answer. In fact, I can show you my code. And I will try to explain it better, sorry. 

 

I have a matrix with 3 columns and 20 lines. The first column is the value for X, the second one for Y and the third one is f(X,Y), the image of x and y by a function f. I want the minimum of the function, then it is the minimum of the third column. This is easy, it is min(X[,p+1]). With p the number of variables (2) and all the lines. And I have the result which is the minimum. BUT I don't have the values for the other columns for this minimum. I would like to have the entire row where the value of the image is minimum. 

 

Here the code. In this case we are talking about gbest and pbest. 

 

proc iml;
xmin=0;     /* min has to be >= 0 or else x^(1/4) and x^(3/4) are undefined */
xmax=100;
/***parameters and variables***/
n=20;			   			/*number of particles*/
p=2;
maxt=1000;					/*maximum iteration*/
maxrun=1;					/*trials of the algorithm*/
X=j(n,p+1,0);				/*initialization of the particle's matrix*/
lb=j(1,p,xmin);
ub=j(1,p,xmax);

/* vectorization of f: R^2 --> R */
start f(x);
   con=100*x[,1]+200*x[,2]-1500;
   fc = 3*(x[,1]##0.25) # (x[,2]##0.75);
   pen=10**9;
   idx = loc(con > 0);
   if ncol(type)>0 then 
		fc[idx] = pen*con[idx];
   return(fc);
finish f;

call randseed(1234);
Y = j(n,P);/* allocate for random values */
do run=1 to maxrun; /*this line is not important in this example*/
   /***initialization of the pso***/
   call randgen(Y, 'uniform');

	/*sample in a uniform distribution to initialize the particles position*/
   X[,1:p] = lb + (ub-lb)#Y;
	/*to fill the third column of X (which corresponds to the output of the function), we evaluate the fitting for each particule*/
	X[,p+1]= f(X);

pbest=X;			/*initialization of pbest so we can iterate then*/
V=0.1*X;
/*we find the current minimum of f, given the current values of X (if we want to minimize the function)*/	
titi=min(pbest[,p+1]);
/*then we iterate to assign the coordinates of this minimum to gbest*/
	do i=1 to n;
		if pbest[i,p+1]=titi then gbest=pbest[i,];
		else e=0;
	end;
end;
print gbest;

I would like to take away the titi and all this stuff.

 

 

Rick_SAS
SAS Super FREQ

In general, you can use the LOC function to find rows that satisfy some criterion.  The LOC function is the most important function that new SAS/IML programmers need to discover.  Be aware, however, if your matrix has tied values, you might get more than one row that satisfies the criterion. In that case, I assume any row is okay? If so, take the first:

 

proc iml;
pbest = {1 2 9,
         4 5 6,
         1 3 10,
         4 1 3,
         1 1 8,
         5 2 3};
p = 2;
n = nrow(pbest);

titi=min(pbest[,p+1]);

/* 1. Use LOC to find row that satisfies criterion */
minIdx = loc(pbest[,p+1]=titi);  
gbest = pbest[minIdx, ];     /* in case of tied values, might get more than one row */
print gbest;

gbest = pbest[minIdx[1], ];  /* if you only want one row, take first */
print gbest;

In this case, the "criterion" is actually a minimum. In SAS/IML, there is a special operator (the '>:<' subscript reduction operator) that can return the row for wh... 

/* 2. For the MIN, you can also use v[>:,] to get the index directly */
v = pbest[,p+1];  
minIdx = v[>:<];
print minIdx;
gbest = pbest[minIdx, ];     /* always returns one row */
print gbest;

 

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

Multiple Linear Regression in SAS

Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.

Find more tutorials on the SAS Users YouTube channel.

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 3 replies
  • 489 views
  • 2 likes
  • 3 in conversation