<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: DO Loops : Struggling to save data in each iteration in SAS/IML Software and Matrix Computations</title>
    <link>https://communities.sas.com/t5/SAS-IML-Software-and-Matrix/DO-Loops-Struggling-to-save-data-in-each-iteration/m-p/710432#M5384</link>
    <description>&lt;P&gt;When you pass a matrix to a SAS/IML module, &lt;A href="https://blogs.sas.com/content/iml/2011/02/07/passing-arguments-by-reference-an-efficient-choice.html" target="_self"&gt;the matrix is passed by reference.&lt;/A&gt;&amp;nbsp;This means that if you change the matrix inside the module, that change will affect the matrix that is passed in. IN the WHITE module, you have the statement&lt;/P&gt;
&lt;P&gt;X=J(n,1,1)||X; &lt;/P&gt;
&lt;P&gt;which adds a new column to X. Therefore, each time you call the WHITE function within a loop, the matrix gets wider.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Change that line to something like&lt;/P&gt;
&lt;P&gt;Z =&amp;nbsp;=J(n,1,1)||X;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;and then use Z to estimate the parameters and to find the residuals.&lt;/P&gt;</description>
    <pubDate>Sun, 10 Jan 2021 12:02:17 GMT</pubDate>
    <dc:creator>Rick_SAS</dc:creator>
    <dc:date>2021-01-10T12:02:17Z</dc:date>
    <item>
      <title>DO Loops : Struggling to save data in each iteration</title>
      <link>https://communities.sas.com/t5/SAS-IML-Software-and-Matrix/DO-Loops-Struggling-to-save-data-in-each-iteration/m-p/710377#M5383</link>
      <description>&lt;P&gt;Hello SAS Community,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here are my functions :&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;proc iml;

start White(X,Y);

		DO i=1 to nrow(X);
		X1_carré = X1_carré//X[i,1]*X[i,1];
		end;

		DO i=1 to nrow(X);
		X2_carré = X2_carré//X[i,2]*X[i,2];
		end;

		DO i=1 to nrow(X);
		X3_carré = X3_carré//X[i,3]*X[i,3];
		end;

		DO i=1 to nrow(X);
		X4_carré = X4_carré//X[i,4]*X[i,4];
		end;

		DO i=1 to nrow(X);
		X1X2_carré = X1X2_carré//X[i,1]*X[i,2];
		end;

		DO i=1 to nrow(X);
		X1X3_carré = X1X3_carré//X[i,1]*X[i,3];
		end;

		DO i=1 to nrow(X);
		X1X4_carré = X1X4_carré//X[i,1]*X[i,4];
		end;

		DO i=1 to nrow(X);
		X2X3_carré = X2X3_carré//X[i,2]*X[i,3];
		end;

		DO i=1 to nrow(X);
		X2X4_carré = X2X4_carré//X[i,2]*X[i,4];
		end;

		DO i=1 to nrow(X);
		X3X4_carré = X3X4_carré//X[i,3]*X[i,4];
		end;

	    XW = X||X1_carré||X2_carré||X3_carré||X4_carré||X1X2_carré||X1X3_carré||X1X4_carré||X2X3_carré||X2X4_carré||X3X4_carré;
		

		n=nrow(X); 
		nw=nrow(XW); 
		X=J(n,1,1)||X; 

		XW=J(nw,1,1)||XW; 	
		k=ncol(X); 
		kw=ncol(XW); 
		
		C=inv(X`*X); 
		beta_hat=C*X`*y;
		resid=y-X*beta_hat; 
		
		resid_sq=resid#resid; 
		
		C_E=inv(XW`*XW); 
		b_hat_e=C_E*XW`*resid_sq;
		
		Mean_Y=Sum(resid_sq)/nw;
		SSR=b_hat_e`*XW`*resid_sq-nw*Mean_Y**2; 
		SSE=resid_sq`*resid_sq-b_hat_e`*XW`*resid_sq;
		SST=SSR+SSE;
		R_Square=SSR/SST;
	
		&lt;STRONG&gt;White=nw*R_Square;&lt;/STRONG&gt; /* NR² */
	    pvalue= 1 - probchi(White, kw-1); 
		*print(White);
		*print(R_Square);
		*print(W);
		*print(pvalue);
return White;
finish White;

start ImanConoverTransform(Y, C);
	X = Y;
	N = nrow(X);
	R = J(N, ncol(X));

	do i = 1 to ncol(X);
		h = quantile("Normal", rank(X[,i])/(N+1) );
		R[,i] = h;
	end;

	Q = root(corr(R));
	P = root(C);
	S = solve(Q,P); 
	M = R*S; 

	do i = 1 to ncol(M);
		rank = rank(M[,i]);
		y = X[,i];
		call sort(y);
		X[,i] = y[rank];
	end;
	return( X );
finish;&lt;/PRE&gt;&lt;P&gt;And this is the loop i want to work :&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;		C = { 1.00  0.75 -0.70  0,
			  0.75  1.00 -0.95  0,
			 -0.70 -0.95  1.00 -0.2,
			  0     0    -0.2   1.0};

&lt;STRONG&gt;*do i = 1 to 10; /* Theoritically -------&amp;gt; Starting DO Loop here */&lt;/STRONG&gt;
		call randseed(2);
		N = 500;
		A = j(N,4); y = j(N,1);
		distrib = {"Normal" "Lognormal" "Expo" "Uniform"};
		do i = 1 to ncol(distrib);
			call randgen(y, distrib[i]);
			A[,i] = y;
		end;

		X = ImanConoverTransform(A, C);

		call randseed(2);
		B = j(4,1);
		distrib = {"Normal"};
		call randgen(B, distrib);
		

		call randseed(2);
		e = j(nrow(X),1);
		distrib = {"Normal"};
		call randgen(e, distrib);

		/* nos résidus */

		Y = X*B+e;

		/* et donc notre Y */

		FITWHITE = Y||X; /* pour la proc model */

		&lt;STRONG&gt;stat = stat//White(X,Y);&lt;/STRONG&gt; 

		print(stat);

&lt;STRONG&gt;*end;&lt;/STRONG&gt;&lt;/PRE&gt;&lt;P&gt;I'm going to explain my self briefly. The functions are basically, White test for Heteroskedasticity, and the Iman-Conover algorithm (proposed by Rick Wicklin). In themselves, they work perfectly and if don't try to make a DO Loop, it actually returns me the correct stats and pvalue.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The issue is when i try to make a loop. What i want is just for each iteration (1 to 10 for example) having the NR² (&lt;STRONG&gt;White=nw*R_Square;&lt;/STRONG&gt;) for a random seed of number and stocking its value in a vector (&lt;STRONG&gt;stat = stat//White(X,Y);&lt;/STRONG&gt;&amp;nbsp;).&amp;nbsp; &amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;So in this example, what i'm expecting by printing the stat variable is a vector of 10 rows with differents NR² values.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And... here is the result :&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Capture.PNG" style="width: 999px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/53363iBF5B95D6D121F9A0/image-size/large?v=v2&amp;amp;px=999" role="button" title="Capture.PNG" alt="Capture.PNG" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;That's weird and it seems to be repeated not then 10 times but actually 500 times !(maybe linked to the N under the first call randseed?)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'll be glad to be helped on this one !&lt;/P&gt;</description>
      <pubDate>Sat, 09 Jan 2021 14:27:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-IML-Software-and-Matrix/DO-Loops-Struggling-to-save-data-in-each-iteration/m-p/710377#M5383</guid>
      <dc:creator>gabsas</dc:creator>
      <dc:date>2021-01-09T14:27:54Z</dc:date>
    </item>
    <item>
      <title>Re: DO Loops : Struggling to save data in each iteration</title>
      <link>https://communities.sas.com/t5/SAS-IML-Software-and-Matrix/DO-Loops-Struggling-to-save-data-in-each-iteration/m-p/710432#M5384</link>
      <description>&lt;P&gt;When you pass a matrix to a SAS/IML module, &lt;A href="https://blogs.sas.com/content/iml/2011/02/07/passing-arguments-by-reference-an-efficient-choice.html" target="_self"&gt;the matrix is passed by reference.&lt;/A&gt;&amp;nbsp;This means that if you change the matrix inside the module, that change will affect the matrix that is passed in. IN the WHITE module, you have the statement&lt;/P&gt;
&lt;P&gt;X=J(n,1,1)||X; &lt;/P&gt;
&lt;P&gt;which adds a new column to X. Therefore, each time you call the WHITE function within a loop, the matrix gets wider.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Change that line to something like&lt;/P&gt;
&lt;P&gt;Z =&amp;nbsp;=J(n,1,1)||X;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;and then use Z to estimate the parameters and to find the residuals.&lt;/P&gt;</description>
      <pubDate>Sun, 10 Jan 2021 12:02:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-IML-Software-and-Matrix/DO-Loops-Struggling-to-save-data-in-each-iteration/m-p/710432#M5384</guid>
      <dc:creator>Rick_SAS</dc:creator>
      <dc:date>2021-01-10T12:02:17Z</dc:date>
    </item>
    <item>
      <title>Re: DO Loops : Struggling to save data in each iteration</title>
      <link>https://communities.sas.com/t5/SAS-IML-Software-and-Matrix/DO-Loops-Struggling-to-save-data-in-each-iteration/m-p/710433#M5385</link>
      <description>&lt;P&gt;Two unrelated comments:&lt;/P&gt;
&lt;P&gt;1. You can improve the efficiency of the WHITE function by using elementwise multiplication of vectors instead of DO loops when you form the quadratic interaction terms:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;		X1_carré = X[,1] # X[,1];
		X2_carré = X[,2] # X[,2];
		X3_carré = X[,3] # X[,3];
		X4_carré = X[,4] # X[,4];
		X1X2_carré = X[,1] # X[,2];
		X1X3_carré = X[,1] # X[,3];
		X1X4_carré = X[,1] # X[,4];
		X2X3_carré = X[,2] # X[,3];
		X2X4_carré = X[,2] # X[,4];
		X3X4_carré = X[,3] # X[,4];
      XW = X||X1_carré||X2_carré||X3_carré||X4_carré||X1X2_carré||X1X3_carré||X1X4_carré||X2X3_carré||X2X4_carré||X3X4_carré;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;2. You can put the allocations and the call to RANDSEED outside of the loop:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;call randseed(2);
N = 500;
A = j(N,4); y = j(N,1);
B = j(4,1);
e = j(nrow(X),1);
numSamples = 10;
stat = j(numSamples,1,.);  /* allocate result vector */
do i = 1 to 10; /* Theoritically -------&amp;gt; Starting DO Loop here */
   ...
   stat[i] = White(X,Y); 
end;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Sun, 10 Jan 2021 12:17:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-IML-Software-and-Matrix/DO-Loops-Struggling-to-save-data-in-each-iteration/m-p/710433#M5385</guid>
      <dc:creator>Rick_SAS</dc:creator>
      <dc:date>2021-01-10T12:17:54Z</dc:date>
    </item>
  </channel>
</rss>

