<?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: Complicated loop with PROC OPTMODEL in Mathematical Optimization, Discrete-Event Simulation, and OR</title>
    <link>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525471#M2542</link>
    <description>&lt;P&gt;I will compare and study this syntax to understand why my code, quite similar at first sight, didn't work while yours is working exactly as desired!&lt;/P&gt;&lt;P&gt;Thank you so much for your precious help!&lt;/P&gt;</description>
    <pubDate>Tue, 08 Jan 2019 16:26:19 GMT</pubDate>
    <dc:creator>Alain38</dc:creator>
    <dc:date>2019-01-08T16:26:19Z</dc:date>
    <item>
      <title>Complicated loop with PROC OPTMODEL</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525002#M2537</link>
      <description>&lt;P&gt;Dear all,&lt;BR /&gt;&lt;BR /&gt;I would like to solve an optimization problem, every month and over many decades.&lt;BR /&gt;&lt;BR /&gt;The parameters are determined beforehand with PROC IML and consist of a matrix called "MVC", which represents the covariance matrix of stock returns.&lt;BR /&gt;&lt;BR /&gt;The difficulty is that each month, not only the stocks can be different, but also their number (e.g. month 1: stocks A, B, C; month 2: stocks A, C, D, E, F). Nonetheless, I could standardize the names of the stocks (let say: month1: 1,2,3; month2: 1,2,3,4,5) to append the MVC for each month, one under the other, even if they have different sizes (until this point I would manage to do it). Then, the idea would be to create a temporary dataset including solely one MVC at a time to run the optimization problem, in the spirit of rolling-window regressions:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data Work.Rwin(keep= Y X1 X2 X3 X4) / view=Work.Rwin;
do grp = 0 to nrecs-60;
     do j = 1 + grp to 60 + grp;
          set Work.Sample nobs=nrecs point=j;
          output;
          end;
     end;
stop;
run;

proc reg data=Work.Rwin outest=Work.Coeff noprint;
	by grp;
	model Y = X1 X2 X3 X4;
run;
quit;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;the additional difficulty of course being that the number of observations is different for each group (grp), but hopefully could be determined thanks to the standardized name (1, 2, ..., N with N different for each grp).&lt;BR /&gt;&lt;BR /&gt;The optimization code is the following:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;ods select none; *Output weights without printing;
proc optmodel ;
	ods output PrintTable=Work.Weights;		/* Output results */

/* Declare the sets of parameters and data indexed by sets */
	set &amp;lt;string&amp;gt; Assets;				/* Stock names defined in the set "Assets" */
	number MVC{Assets, Assets};			/* MVC data indexed by the set "Assets" */

/* Populate the model by reading in the specific data instance */
	read data Work.MVC into Assets=[Name];		/* Read from the variable "Name" in Work.MVC */
	read data Work.MVC into [i=Name] {j in Assets} &amp;lt;MVC[i,j]=col(j)&amp;gt;;

/* Declare the variable */
	var W{Assets} &amp;gt;= 0;			/* Positive weights constraint */

/* Minimize the objective function (variance of the portfolio) */
	minimize Variance = sum{i in Assets, j in Assets}W[i]*MVC[i,j]*W[j];
/* Subject to the following constraints */
	con BUDGET: sum{i in Assets}W[i] = 1;

	solve with qp;
	print W;                                 /* print the optimal solution */
quit;
ods select all;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Results (vectors of weights) would be all output in the same dataset.&lt;BR /&gt;&lt;BR /&gt;What do you think of this solution and if it is the best way to do, could you please help me implement it?&lt;BR /&gt;Otherwise, how could I proceed? I considered for example running the optimization problem directly in IML but I read on this forum that PROC OPTMODEL, being specifically designed for it, is the procedure to use for this kind of problems rather than a simple home-made IML program. There may be also much simpler solutions that I haven't thought about, so&lt;/P&gt;&lt;P&gt;any suggestion most welcomed, as well as assistance for writing the code,&lt;/P&gt;</description>
      <pubDate>Mon, 07 Jan 2019 11:40:29 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525002#M2537</guid>
      <dc:creator>Alain38</dc:creator>
      <dc:date>2019-01-07T11:40:29Z</dc:date>
    </item>
    <item>
      <title>Re: Complicated loop with PROC OPTMODEL</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525100#M2538</link>
      <description>&lt;P&gt;You might be interested in this Usage Note, which illustrates how to implement BY-group processing in PROC OPTMODEL:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://support.sas.com/kb/42/332.html" target="_blank"&gt;http://support.sas.com/kb/42/332.html&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 07 Jan 2019 16:25:45 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525100#M2538</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2019-01-07T16:25:45Z</dc:date>
    </item>
    <item>
      <title>Re: Complicated loop with PROC OPTMODEL</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525375#M2539</link>
      <description>&lt;P&gt;Thank you very much for this link, this is exactly what I need!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Could you please help me changing my PROC OPTMODEL code accordingly? My dataset MVC looks like:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data Work.MVC;
         input grp Name $ _1 _2 _3 _4 @@;
         datalines;
      1 _1 0.01  0.005 0.006 .
      1 _2 0.005 0.007 0.004 .
      1 _3 0.006 0.004 0.008 .
      2 _1 0.02  0.01  0.012 0.013
      2 _2 0.01  0.014 0.008 0.007
      2 _3 0.012 0.008 0.016 0.009
      2 _4 0.013 0.007 0.009 0.018
;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;I should notably have:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let byvar = grp;	/* BY group processing */&lt;BR /&gt;proc optmodel ;&lt;BR /&gt;/* Declare the sets of parameters and data indexed by sets */&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;set &amp;lt;string&amp;gt; Assets;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;/* Stock names in the set "Assets" */&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;string grp {Assets};&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;number MVC{Assets, Assets};&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;and&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/* Collect values of BY variable into an index set */
	set BYSET = setof {i in Assets} &amp;amp;byvar.[i];
	put BYSET=;
	string by;

/* Declare the variable */
	var W{Assets_BY} &amp;gt;= 0;
	set Assets_BY = {i in Assets: &amp;amp;byvar.[i] = by};&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;but I am lost for the remaining of the code (read, loop...), the example being quite different from my case and I do not master the proc optmodel syntax...&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you so much for your help,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 08 Jan 2019 11:18:11 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525375#M2539</guid>
      <dc:creator>Alain38</dc:creator>
      <dc:date>2019-01-08T11:18:11Z</dc:date>
    </item>
    <item>
      <title>Re: Complicated loop with PROC OPTMODEL</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525463#M2540</link>
      <description>&lt;P&gt;I think the following does what you want.&amp;nbsp; If you have a large number of BY groups, you might want to use PRINTLEVEL=0 in the PROC OPTMODEL statement.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let byvar = grp;
/* BY group processing */
proc optmodel;
   /* Declare the sets of parameters and data indexed by sets */
   set OBS;
   num grp {OBS};
   set &amp;lt;string&amp;gt; Assets;				/* Stock names defined in the set "Assets" */
   set &amp;lt;num,str&amp;gt; GROUPS_ASSETS;
   number MVC{GROUPS_ASSETS, Assets};

   /* Populate the model by reading in the specific data instance */
   read data Work.MVC into Assets=[Name];		/* Read from the variable "Name" in Work.MVC */
   read data Work.MVC into OBS=[_N_] grp;
   read data Work.MVC nomiss into GROUPS_ASSETS=[k=grp i=Name] {j in Assets} &amp;lt;MVC[k,i,j]=col(j)&amp;gt;;

   /* Collect values of BY variable into an index set */
   set BYSET = setof {i in OBS} &amp;amp;byvar.[i];
   num by;

   /* Declare the variable */
   set OBS_BY = {i in OBS: &amp;amp;byvar.[i] = by};
   set Assets_BY = setof {o in OBS_BY, &amp;lt;(grp[o]),a&amp;gt; in GROUPS_ASSETS} a;
   var W{Assets_BY} &amp;gt;= 0;

   /* Minimize the objective function (variance of the portfolio) */
   minimize Variance = sum{i in Assets_BY, j in Assets_BY}W[i]*MVC[by,i,j]*W[j];

   /* Subject to the following constraints */
   con BUDGET: sum{i in Assets_BY}W[i] = 1;

   /* Declare parameters to store solution values */
   num W_sol {GROUPS_ASSETS};&lt;BR /&gt;
   /* Loop over values of the BY variable, calling the QP solver once for each level.  
   Note that OBS_BY is automatically updated when the BY variable changes.  */
   do by = BYSET;
      put by=;
      solve;
      /* Store solution in numeric parameters */
      for {i in Assets_BY} W_sol[by,i] = W[i].sol;
   end;

   /* Save the solutions for all values of the BY variable simultaneously */
   create data weights from [&amp;amp;byvar i] W=W_sol;
quit;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 08 Jan 2019 16:13:55 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525463#M2540</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2019-01-08T16:13:55Z</dc:date>
    </item>
    <item>
      <title>Re: Complicated loop with PROC OPTMODEL</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525468#M2541</link>
      <description>&lt;P&gt;By the way, you can also solve these problems concurrently by replacing the DO loop with a COFOR loop:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/*   do by = BYSET;*/
   cofor {b in BYSET} do;
      by = b;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Tue, 08 Jan 2019 16:20:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525468#M2541</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2019-01-08T16:20:23Z</dc:date>
    </item>
    <item>
      <title>Re: Complicated loop with PROC OPTMODEL</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525471#M2542</link>
      <description>&lt;P&gt;I will compare and study this syntax to understand why my code, quite similar at first sight, didn't work while yours is working exactly as desired!&lt;/P&gt;&lt;P&gt;Thank you so much for your precious help!&lt;/P&gt;</description>
      <pubDate>Tue, 08 Jan 2019 16:26:19 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525471#M2542</guid>
      <dc:creator>Alain38</dc:creator>
      <dc:date>2019-01-08T16:26:19Z</dc:date>
    </item>
    <item>
      <title>Re: Complicated loop with PROC OPTMODEL</title>
      <link>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525864#M2543</link>
      <description>&lt;P&gt;Here's another approach that might be simpler to digest.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let n = 4;
data MVC_sparse(keep=grp name name2 cov);
   set MVC;
   array covarray [&amp;amp;n] _1-_&amp;amp;n;
   do j = 1 to &amp;amp;n;
      Name2 = '_'||put(j,1.);
      cov = covarray[j];
      if cov ne . then output;
   end;
run;

%let byvar = grp;
/* BY group processing */
proc optmodel;
   /* Declare the sets of parameters and data indexed by sets */
   set OBS;
   num grp {OBS};
   str asset_i {OBS};
   str asset_j {OBS};
   number MVC{OBS};

   /* Populate the model by reading in the specific data instance */
   read data Work.MVC_sparse into OBS=[_N_] grp asset_i=Name asset_j=Name2 MVC=cov;
   set ASSETS = setof {o in OBS} asset_i[o];

   /* Collect values of BY variable into an index set */
   set BYSET = setof {i in OBS} &amp;amp;byvar.[i];
   num by;

   /* Declare the variable */
   set OBS_BY = {i in OBS: &amp;amp;byvar.[i] = by};
   set Assets_BY = setof {o in OBS_BY} asset_i[o];
   var W{Assets_BY} &amp;gt;= 0;

   /* Minimize the objective function (variance of the portfolio) */
   minimize Variance = sum{o in OBS_BY}W[asset_i[o]]*MVC[o]*W[asset_j[o]];

   /* Subject to the following constraints */
   con BUDGET: sum{i in Assets_BY}W[i] = 1;

   /* Declare parameters to store solution values */
   num W_sol {BYSET, ASSETS};

   /* Loop over values of the BY variable, calling the QP solver once for each level.  
   Note that OBS_BY is automatically updated when the BY variable changes.  */
/*   do by = BYSET;*/
   cofor {b in BYSET} do;
      by = b;
      put by=;
      solve;
      /* Store solution in numeric parameters */
      for {i in Assets_BY} W_sol[by,i] = W[i].sol;
   end;

   /* Save the solutions for all values of the BY variable simultaneously */
   create data weights_sparse(where=(W ne .)) from [&amp;amp;byvar i] W=W_sol;
quit;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 10 Jan 2019 21:38:11 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Mathematical-Optimization/Complicated-loop-with-PROC-OPTMODEL/m-p/525864#M2543</guid>
      <dc:creator>RobPratt</dc:creator>
      <dc:date>2019-01-10T21:38:11Z</dc:date>
    </item>
  </channel>
</rss>

