<?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 CTA SAS macro in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/40452#M8231</link>
    <description>I am very new to SAS and I have an input matrix and an macro but I am getting results .&lt;BR /&gt;
My input matrix is:&lt;BR /&gt;
%CTA-SAS2(SAMPMAT1 = &lt;BR /&gt;
&lt;BR /&gt;
1&lt;BR /&gt;
&lt;BR /&gt;
0.564 1&lt;BR /&gt;
&lt;BR /&gt;
0.531 0.496 1&lt;BR /&gt;
&lt;BR /&gt;
0.466 0.436 0.449 1&lt;BR /&gt;
&lt;BR /&gt;
0.460 0.429 0.662 0.582 1,&lt;BR /&gt;
&lt;BR /&gt;
N = 134, vars = 5, nesttest = 0, pchor = 0, lisrel = 0, mplus = 0, lowdiag=1);&lt;BR /&gt;
&lt;BR /&gt;
My huge macro:&lt;BR /&gt;
&lt;BR /&gt;
%macro cta(N=, vars=, nesttest=0, pchor=0, lisrel=0, mplus=0, SAMPMAT1=,lowdiag=1);&lt;BR /&gt;
   title1 'Confirmatory Tetrad Analysis';&lt;BR /&gt;
&lt;BR /&gt;
   *................... Macro Functions ...........................*;&lt;BR /&gt;
   %macro _resid(a,b,c,d);&lt;BR /&gt;
        /* tetrad residual */&lt;BR /&gt;
        residual = S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;c,&amp;amp;d)-S(&amp;amp;a,&amp;amp;c)*S(&amp;amp;b,&amp;amp;d);&lt;BR /&gt;
&lt;BR /&gt;
        /* asymptotic variance */&lt;BR /&gt;
        AVAR = (1/&amp;amp;N) *&lt;BR /&gt;
               (S(&amp;amp;d,&amp;amp;b)*S(&amp;amp;d,&amp;amp;b)*S(&amp;amp;a,&amp;amp;a)*S(&amp;amp;c,&amp;amp;c) +&lt;BR /&gt;
                S(&amp;amp;a,&amp;amp;c)*S(&amp;amp;a,&amp;amp;c)*S(&amp;amp;d,&amp;amp;d)*S(&amp;amp;b,&amp;amp;b) +&lt;BR /&gt;
                S(&amp;amp;d,&amp;amp;c)*S(&amp;amp;d,&amp;amp;c)*S(&amp;amp;a,&amp;amp;a)*S(&amp;amp;b,&amp;amp;b) +&lt;BR /&gt;
                S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;d,&amp;amp;d)*S(&amp;amp;c,&amp;amp;c) +&lt;BR /&gt;
            2 *(S(&amp;amp;d,&amp;amp;b)*S(&amp;amp;a,&amp;amp;c)*S(&amp;amp;a,&amp;amp;d)*S(&amp;amp;b,&amp;amp;c) -&lt;BR /&gt;
                S(&amp;amp;d,&amp;amp;b)*S(&amp;amp;d,&amp;amp;c)*S(&amp;amp;a,&amp;amp;a)*S(&amp;amp;b,&amp;amp;c) -&lt;BR /&gt;
                S(&amp;amp;d,&amp;amp;b)*S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;a,&amp;amp;d)*S(&amp;amp;c,&amp;amp;c) -&lt;BR /&gt;
                S(&amp;amp;a,&amp;amp;c)*S(&amp;amp;d,&amp;amp;c)*S(&amp;amp;d,&amp;amp;a)*S(&amp;amp;b,&amp;amp;b) -&lt;BR /&gt;
                S(&amp;amp;a,&amp;amp;c)*S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;d,&amp;amp;d)*S(&amp;amp;b,&amp;amp;c) +&lt;BR /&gt;
                S(&amp;amp;d,&amp;amp;c)*S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;a,&amp;amp;d)*S(&amp;amp;b,&amp;amp;c))+&lt;BR /&gt;
           2 *((S(&amp;amp;d,&amp;amp;b)*S(&amp;amp;a,&amp;amp;c)-S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;d,&amp;amp;c))**2));&lt;BR /&gt;
&lt;BR /&gt;
        /* t-value */&lt;BR /&gt;
        tvalue = residual/sqrt(avar);&lt;BR /&gt;
&lt;BR /&gt;
        tetrad = compress('t('||&amp;amp;a||','||&amp;amp;b||','||&amp;amp;c||','||&amp;amp;d||')');&lt;BR /&gt;
   %mend _resid;&lt;BR /&gt;
&lt;BR /&gt;
   %macro _switch (first,second);&lt;BR /&gt;
         temp = &amp;amp;first;&lt;BR /&gt;
         &amp;amp;first = &amp;amp;second;&lt;BR /&gt;
         &amp;amp;second= temp;&lt;BR /&gt;
   %mend _switch;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Data Input ................................*;&lt;BR /&gt;
   /* count # of variables */&lt;BR /&gt;
   data _null_;&lt;BR /&gt;
     array varname (*) &amp;amp;vars;&lt;BR /&gt;
     call symput('k',left(dim(varname)));       /* &amp;amp;k = # vars */&lt;BR /&gt;
     call symput('m',left(dim(varname)**2));    /* &amp;amp;m = &amp;amp;k*&amp;amp;k  */&lt;BR /&gt;
   run;&lt;BR /&gt;
&lt;BR /&gt;
   %let nt = %eval(&amp;amp;k*(&amp;amp;k-1)*(&amp;amp;k-2)*(&amp;amp;k-3)/8);  /* # of tetrads*/&lt;BR /&gt;
&lt;BR /&gt;
   %if &amp;amp;data ne %str() %then %do;&lt;BR /&gt;
   /* compute covariance matrix */&lt;BR /&gt;
   /* exclude missing cases     */&lt;BR /&gt;
      proc corr data=&amp;amp;data nomiss nocorr cov out=covout noprint;&lt;BR /&gt;
        var &amp;amp;vars;&lt;BR /&gt;
      data matx; set covout;&lt;BR /&gt;
        if _type_ = 'N' then do;&lt;BR /&gt;
           maxn = max(of &amp;amp;vars);&lt;BR /&gt;
           call symput('n',maxn);               /* &amp;amp;n = # obs  */&lt;BR /&gt;
        end;&lt;BR /&gt;
        if _type_ = 'COV';&lt;BR /&gt;
        keep &amp;amp;vars;&lt;BR /&gt;
      proc print data=matx noobs;&lt;BR /&gt;
        var &amp;amp;vars;&lt;BR /&gt;
        title2 'Covariance Matrix Computed from Input Data';&lt;BR /&gt;
      data matx1rec; set matx;&lt;BR /&gt;
        retain s1 - s&amp;amp;m;&lt;BR /&gt;
        array v (*) &amp;amp;vars;&lt;BR /&gt;
        array s (&amp;amp;k,&amp;amp;k);&lt;BR /&gt;
        do i = 1 to &amp;amp;k;&lt;BR /&gt;
           s(_n_,i) = v(i);&lt;BR /&gt;
        end;&lt;BR /&gt;
        if _n_ = &amp;amp;k then output;&lt;BR /&gt;
   %end;&lt;BR /&gt;
&lt;BR /&gt;
   %else %do;&lt;BR /&gt;
   /* read covariance or correlation matrix */&lt;BR /&gt;
      data matx1rec;&lt;BR /&gt;
        %let lowtri = %eval((&amp;amp;k + 1)*(&amp;amp;k)/2);&lt;BR /&gt;
        array t(&amp;amp;lowtri) _temporary_ (&amp;amp;cmatrix);&lt;BR /&gt;
        array s(&amp;amp;k,&amp;amp;k);&lt;BR /&gt;
        do i = 1 to &amp;amp;k;&lt;BR /&gt;
           do j = 1 to i;&lt;BR /&gt;
              p + 1;&lt;BR /&gt;
              s(i,j) = t(p);&lt;BR /&gt;
              s(j,i) = t(p);&lt;BR /&gt;
           end;&lt;BR /&gt;
        end;&lt;BR /&gt;
      data matx; set matx1rec;&lt;BR /&gt;
        array v (*) &amp;amp;vars;&lt;BR /&gt;
        array s(&amp;amp;k,&amp;amp;k);&lt;BR /&gt;
        do i = 1 to &amp;amp;k;&lt;BR /&gt;
           do j = 1 to &amp;amp;k;&lt;BR /&gt;
              v(j) = s(i,j);&lt;BR /&gt;
           end;&lt;BR /&gt;
           keep &amp;amp;vars;&lt;BR /&gt;
           output;&lt;BR /&gt;
        end;&lt;BR /&gt;
      proc print data=matx noobs;&lt;BR /&gt;
        var &amp;amp;vars;&lt;BR /&gt;
        title2 'Covariance/Correlation Matrix Read from Input Matrix';&lt;BR /&gt;
   %end;&lt;BR /&gt;
&lt;BR /&gt;
   %if %upcase(&amp;amp;AC) = DFAC %then %do;&lt;BR /&gt;
   /* convert variables to deviation scores */&lt;BR /&gt;
      proc means noprint mean data=&amp;amp;data;&lt;BR /&gt;
        var &amp;amp;vars;&lt;BR /&gt;
        output out=meanout mean(&amp;amp;vars)=mean1 - mean&amp;amp;k;&lt;BR /&gt;
      data meanout; set meanout;&lt;BR /&gt;
        match=1;&lt;BR /&gt;
        keep mean1 - mean&amp;amp;k match;&lt;BR /&gt;
      data &amp;amp;data; set &amp;amp;data; match=1;&lt;BR /&gt;
      data ctrdata;&lt;BR /&gt;
        merge &amp;amp;data meanout; by match;&lt;BR /&gt;
        array x (&amp;amp;k) &amp;amp;vars;&lt;BR /&gt;
        array mean (&amp;amp;k);&lt;BR /&gt;
        do i = 1 to &amp;amp;k;&lt;BR /&gt;
           x(i) = x(i) - mean(i);&lt;BR /&gt;
        end;&lt;BR /&gt;
        keep match &amp;amp;vars;&lt;BR /&gt;
   %end;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Tetrad Construction .......................*;&lt;BR /&gt;
   data tetrad; set matx1rec;&lt;BR /&gt;
     array s (&amp;amp;k,&amp;amp;k);&lt;BR /&gt;
&lt;BR /&gt;
     /* generate all tetrads equations */&lt;BR /&gt;
     a=1; b=2; c=3; d=3;&lt;BR /&gt;
     do until (a &amp;gt; &amp;amp;k-3);&lt;BR /&gt;
        do until (b &amp;gt; &amp;amp;k-2);&lt;BR /&gt;
           do until (c &amp;gt; &amp;amp;k-1);&lt;BR /&gt;
              do until (d = &amp;amp;k);&lt;BR /&gt;
                 d=d+1;&lt;BR /&gt;
&lt;BR /&gt;
                 cov1 = a * 1000 + b; cov2 = c * 1000 + d;&lt;BR /&gt;
                 cov3 = a * 1000 + c; cov4 = b * 1000 + d;&lt;BR /&gt;
                 %_resid(a,b,c,d);&lt;BR /&gt;
                 id+1;&lt;BR /&gt;
                 output;&lt;BR /&gt;
&lt;BR /&gt;
                 cov1 = a * 1000 + b; cov2 = c * 1000 + d;&lt;BR /&gt;
                 cov3 = a * 1000 + d; cov4 = b * 1000 + c;&lt;BR /&gt;
                 %_resid(a,b,d,c);&lt;BR /&gt;
                 id+1;&lt;BR /&gt;
                 output;&lt;BR /&gt;
&lt;BR /&gt;
                 cov1 = a * 1000 + c; cov2 = b * 1000 + d;&lt;BR /&gt;
                 cov3 = a * 1000 + d; cov4 = b * 1000 + c;&lt;BR /&gt;
                 %_resid(a,c,d,b);&lt;BR /&gt;
                 id+1;&lt;BR /&gt;
                 output;&lt;BR /&gt;
&lt;BR /&gt;
              end;&lt;BR /&gt;
              c=c+1;&lt;BR /&gt;
              d=c;&lt;BR /&gt;
           end;&lt;BR /&gt;
           b=b+1;&lt;BR /&gt;
           c=b+1;&lt;BR /&gt;
           d=c;&lt;BR /&gt;
        end;&lt;BR /&gt;
        a=a+1;&lt;BR /&gt;
        b=a+1;&lt;BR /&gt;
        c=b+1;&lt;BR /&gt;
        d=c;&lt;BR /&gt;
     end;&lt;BR /&gt;
&lt;BR /&gt;
   proc print noobs;&lt;BR /&gt;
     var id tetrad residual tvalue;&lt;BR /&gt;
     title2 'List of Tetrads';&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   /* Execution Control */&lt;BR /&gt;
   %if %upcase(&amp;amp;EXEC) ne PARTIAL %then %do;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Model Implied Vanishing Tetrads ...........*;&lt;BR /&gt;
   data mivt;&lt;BR /&gt;
     set tetrad;&lt;BR /&gt;
     /* select tetrads for test */&lt;BR /&gt;
     /* first keep then drop if both options specified */&lt;BR /&gt;
     %if &amp;amp;keept ne %str() %then %do;&lt;BR /&gt;
          array keeptd (&amp;amp;nt) _temporary_ (&amp;amp;keept);&lt;BR /&gt;
          do i = 1 to &amp;amp;nt;&lt;BR /&gt;
             if keeptd(i) = . then go to exit1;&lt;BR /&gt;
             if keeptd(i) = id then keeplist = 'keep';&lt;BR /&gt;
          end;&lt;BR /&gt;
          exit1:&lt;BR /&gt;
          if keeplist = 'keep';&lt;BR /&gt;
     %end;&lt;BR /&gt;
     %if &amp;amp;dropt ne %str() %then %do;&lt;BR /&gt;
          array droptd (&amp;amp;nt) _temporary_ (&amp;amp;dropt);&lt;BR /&gt;
          do i = 1 to &amp;amp;nt;&lt;BR /&gt;
             if droptd(i) = . then go to exit2;&lt;BR /&gt;
             if droptd(i) = id then droplist = 'drop';&lt;BR /&gt;
          end;&lt;BR /&gt;
          exit2:&lt;BR /&gt;
          if droplist = 'drop' then delete;&lt;BR /&gt;
     %end;&lt;BR /&gt;
&lt;BR /&gt;
     eq+1;&lt;BR /&gt;
     call symput('eqs',left(eq));           /* &amp;amp;eqs = # of vt */&lt;BR /&gt;
&lt;BR /&gt;
     /* sort tetrads */&lt;BR /&gt;
     %if &amp;amp;sort ne %str() %then %do;&lt;BR /&gt;
        data mivt; set mivt;&lt;BR /&gt;
        array sort(&amp;amp;eqs) _temporary_ (&amp;amp;sort);&lt;BR /&gt;
        do i = 1 to &amp;amp;eqs;&lt;BR /&gt;
           if sort(i) = . then do;&lt;BR /&gt;
              rank = &amp;amp;eqs + 1;&lt;BR /&gt;
              go to exit1;&lt;BR /&gt;
           end; else&lt;BR /&gt;
           if id = sort(i) then do;&lt;BR /&gt;
              rank = i;&lt;BR /&gt;
              go to exit1;&lt;BR /&gt;
           end;&lt;BR /&gt;
        end;&lt;BR /&gt;
        exit1:&lt;BR /&gt;
     proc sort; by rank;&lt;BR /&gt;
     proc print;&lt;BR /&gt;
       var id tetrad residual cov1 cov2 cov3 cov4;&lt;BR /&gt;
       title2 'sorted tetrads';&lt;BR /&gt;
     %end;&lt;BR /&gt;
&lt;BR /&gt;
   /* Convert MIVT to single record */&lt;BR /&gt;
   data mivt1rec;&lt;BR /&gt;
     set mivt (keep = id tetrad residual cov1 cov2 cov3 cov4)&lt;BR /&gt;
         end = eof;&lt;BR /&gt;
     retain a1 - a&amp;amp;eqs&lt;BR /&gt;
            b1 - b&amp;amp;eqs&lt;BR /&gt;
            c1 - c&amp;amp;eqs&lt;BR /&gt;
            d1 - d&amp;amp;eqs&lt;BR /&gt;
            e1 - e&amp;amp;eqs 4.;&lt;BR /&gt;
&lt;BR /&gt;
     array a (*) a1 - a&amp;amp;eqs;&lt;BR /&gt;
     array b (*) b1 - b&amp;amp;eqs;&lt;BR /&gt;
     array c (*) c1 - c&amp;amp;eqs;&lt;BR /&gt;
     array d (*) d1 - d&amp;amp;eqs;&lt;BR /&gt;
     array e (*) e1 - e&amp;amp;eqs;&lt;BR /&gt;
&lt;BR /&gt;
     a(_n_) = cov1;&lt;BR /&gt;
     b(_n_) = cov2;&lt;BR /&gt;
     c(_n_) = cov3;&lt;BR /&gt;
     d(_n_) = cov4;&lt;BR /&gt;
     e(_n_) = id;&lt;BR /&gt;
&lt;BR /&gt;
     keep a1-a&amp;amp;eqs b1-b&amp;amp;eqs c1-c&amp;amp;eqs d1-d&amp;amp;eqs e1-e&amp;amp;eqs;&lt;BR /&gt;
     if eof then output;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Remove Redundant Tetrads ..................*;&lt;BR /&gt;
   data nrvt; set mivt1rec;&lt;BR /&gt;
     array a (*) a1 - a&amp;amp;eqs;&lt;BR /&gt;
     array b (*) b1 - b&amp;amp;eqs;&lt;BR /&gt;
     array c (*) c1 - c&amp;amp;eqs;&lt;BR /&gt;
     array d (*) d1 - d&amp;amp;eqs;&lt;BR /&gt;
     array e  (*) e1  - e&amp;amp;eqs;&lt;BR /&gt;
     array nr (*) nr01 - nr&amp;amp;eqs;&lt;BR /&gt;
     array im (*) im01 - im&amp;amp;eqs;&lt;BR /&gt;
&lt;BR /&gt;
     do i = 1 to dim(nr);&lt;BR /&gt;
        if im(i) ne 1 then nr(i) = 1;                /* NR VT */&lt;BR /&gt;
&lt;BR /&gt;
        /* check implied VTs from VT1 to VTi */&lt;BR /&gt;
        do p = 1 to i-1, i+1 to dim(nr);&lt;BR /&gt;
           if p &amp;lt; i or im(p) = 1 then do;&lt;BR /&gt;
              /* step 1: find 2 share covs */&lt;BR /&gt;
              cu1=a(i); cu2=b(i); cu3=c(i); cu4=d(i);&lt;BR /&gt;
              ps1=a(p); ps2=b(p); ps3=c(p); ps4=d(p);&lt;BR /&gt;
              array cu (*) cu1 cu2 cu3 cu4;  /* current  VT */&lt;BR /&gt;
              array ps (*) ps1 ps2 ps3 ps4;  /* previous VT */&lt;BR /&gt;
              share = 0;&lt;BR /&gt;
              lhs = 0;&lt;BR /&gt;
              rhs = 0;&lt;BR /&gt;
              xhs = 0;&lt;BR /&gt;
&lt;BR /&gt;
              /* find shared covs from 2 tetrads */&lt;BR /&gt;
              do x = 1 to 4;&lt;BR /&gt;
                 do y = 1 to 4;&lt;BR /&gt;
                    if cu(x) = ps(y) then do;&lt;BR /&gt;
                       share = share + 1;&lt;BR /&gt;
                       if x &amp;lt;= 2 &amp;amp; y &amp;lt;= 2 then lhs = lhs + 1;&lt;BR /&gt;
                       if x &amp;gt;= 3 &amp;amp; y &amp;gt;= 3 then rhs = rhs + 1;&lt;BR /&gt;
                       if x &amp;lt;= 2          then xhs = xhs + 1;&lt;BR /&gt;
                    end;&lt;BR /&gt;
&lt;BR /&gt;
                    if share = 2 then do;&lt;BR /&gt;
                       if lhs = 1 &amp;amp; rhs = 1 then do;&lt;BR /&gt;
                          do x = 1 to 4;&lt;BR /&gt;
                             do y = 1 to 4;&lt;BR /&gt;
                                if cu(x) = ps(y) then do;&lt;BR /&gt;
                                   if x = 1 then cv1 = cu(2); else&lt;BR /&gt;
                                   if x = 2 then cv1 = cu(1); else&lt;BR /&gt;
                                   if x = 3 then cv4 = cu(4); else&lt;BR /&gt;
                                   if x = 4 then cv4 = cu(3);&lt;BR /&gt;
&lt;BR /&gt;
                                   if y = 1 then cv3 = ps(2); else&lt;BR /&gt;
                                   if y = 2 then cv3 = ps(1); else&lt;BR /&gt;
                                   if y = 3 then cv2 = ps(4); else&lt;BR /&gt;
                                   if y = 4 then cv2 = ps(3);&lt;BR /&gt;
                                end;&lt;BR /&gt;
                             end;&lt;BR /&gt;
                          end;&lt;BR /&gt;
                       end;&lt;BR /&gt;
                       if lhs = 2 then do;&lt;BR /&gt;
                          cv1 = cu(3);&lt;BR /&gt;
                          cv2 = cu(4);&lt;BR /&gt;
                          cv3 = ps(3);&lt;BR /&gt;
                          cv4 = ps(4);&lt;BR /&gt;
                       end;&lt;BR /&gt;
                       if rhs = 2 then do;&lt;BR /&gt;
                          cv1 = cu(1);&lt;BR /&gt;
                          cv2 = cu(2);&lt;BR /&gt;
                          cv3 = ps(1);&lt;BR /&gt;
                          cv4 = ps(2);&lt;BR /&gt;
                       end;&lt;BR /&gt;
                       if lhs = 0 &amp;amp; rhs = 0 then do;&lt;BR /&gt;
                          if xhs = 1 then do;&lt;BR /&gt;
                             do x = 1 to 4;&lt;BR /&gt;
                                do y = 1 to 4;&lt;BR /&gt;
                                   if cu(x) = ps(y) then do;&lt;BR /&gt;
                                      if x = 1 then cv1 = cu(2); else&lt;BR /&gt;
                                      if x = 2 then cv1 = cu(1); else&lt;BR /&gt;
                                      if x = 3 then cv3 = cu(4); else&lt;BR /&gt;
                                      if x = 4 then cv3 = cu(3);&lt;BR /&gt;
&lt;BR /&gt;
                                      if y = 1 then cv2 = ps(2); else&lt;BR /&gt;
                                      if y = 2 then cv2 = ps(1); else&lt;BR /&gt;
                                      if y = 3 then cv4 = ps(4); else&lt;BR /&gt;
                                      if y = 4 then cv4 = ps(3);&lt;BR /&gt;
                                   end;&lt;BR /&gt;
                                end;&lt;BR /&gt;
                             end;&lt;BR /&gt;
                          end;&lt;BR /&gt;
                          if xhs = 0 then do;&lt;BR /&gt;
                             cv1 = cu(1);&lt;BR /&gt;
                             cv2 = cu(2);&lt;BR /&gt;
                             cv3 = ps(3);&lt;BR /&gt;
                             cv4 = ps(4);&lt;BR /&gt;
                          end;&lt;BR /&gt;
                          if xhs = 2 then do;&lt;BR /&gt;
                             cv1 = cu(3);&lt;BR /&gt;
                             cv2 = cu(4);&lt;BR /&gt;
                             cv3 = ps(1);&lt;BR /&gt;
                             cv4 = ps(2);&lt;BR /&gt;
                          end;&lt;BR /&gt;
                       end;&lt;BR /&gt;
&lt;BR /&gt;
                    end;&lt;BR /&gt;
                 end;&lt;BR /&gt;
              end;&lt;BR /&gt;
&lt;BR /&gt;
              /* step 2: if 2 share covs is found, construct IM VT */&lt;BR /&gt;
              if share = 2 then do;&lt;BR /&gt;
                 if cv1 &amp;gt; cv2 then do;&lt;BR /&gt;
                    %_switch(cv1,cv2);&lt;BR /&gt;
                 end;&lt;BR /&gt;
                 if cv3 &amp;gt; cv4 then do;&lt;BR /&gt;
                    %_switch(cv3,cv4);&lt;BR /&gt;
                 end;&lt;BR /&gt;
&lt;BR /&gt;
                 if cv1 &amp;gt; cv3 then do;&lt;BR /&gt;
                    %_switch(cv1,cv3);&lt;BR /&gt;
                    %_switch(cv2,cv4);&lt;BR /&gt;
                 end;&lt;BR /&gt;
&lt;BR /&gt;
                 /* step 3: compare 4 covs from i+1 to last */&lt;BR /&gt;
                 do cp = i+1 to dim(nr);&lt;BR /&gt;
                    count = 0;&lt;BR /&gt;
                    cp1=a(cp); cp2=b(cp); cp3=c(cp); cp4=d(cp);&lt;BR /&gt;
                    array cv (*) cv1 cv2 cv3 cv4;&lt;BR /&gt;
                    array af (*) cp1 cp2 cp3 cp4;&lt;BR /&gt;
                    do m = 1 to 4;&lt;BR /&gt;
                       do n = 1 to 4;&lt;BR /&gt;
                          if cv(m) = af(n) then count = count+1;&lt;BR /&gt;
                          if count = 4 then do;&lt;BR /&gt;
                             if im(cp) ne 1 then do s=i+1 to dim(nr);&lt;BR /&gt;
                                if im(s) ne 1 then do;&lt;BR /&gt;
                                   %_switch(a(s),a(cp));&lt;BR /&gt;
                                   %_switch(b(s),b(cp));&lt;BR /&gt;
                                   %_switch(c(s),c(cp));&lt;BR /&gt;
                                   %_switch(d(s),d(cp));&lt;BR /&gt;
                                   %_switch(e(s),e(cp));&lt;BR /&gt;
                                   im(s)=1;&lt;BR /&gt;
                                   go to exit1;&lt;BR /&gt;
                                end;&lt;BR /&gt;
                             end;&lt;BR /&gt;
                          end;&lt;BR /&gt;
                       end;&lt;BR /&gt;
                    end;&lt;BR /&gt;
                 end;&lt;BR /&gt;
              end;&lt;BR /&gt;
              exit1:&lt;BR /&gt;
           end;&lt;BR /&gt;
        end;&lt;BR /&gt;
     end;&lt;BR /&gt;
&lt;BR /&gt;
     do i=1 to &amp;amp;eqs;&lt;BR /&gt;
       cov1 = a(i);&lt;BR /&gt;
       cov2 = b(i);&lt;BR /&gt;
       cov3 = c(i);&lt;BR /&gt;
       cov4 = d(i);&lt;BR /&gt;
       id   = e(i);&lt;BR /&gt;
       nr_  = nr(i);&lt;BR /&gt;
       match= 1;&lt;BR /&gt;
       keep id match nr_ cov1 - cov4;&lt;BR /&gt;
       output;&lt;BR /&gt;
     end;&lt;BR /&gt;
   proc sort; by id;&lt;BR /&gt;
&lt;BR /&gt;
   data cta;&lt;BR /&gt;
     merge tetrad (keep = id tetrad residual)&lt;BR /&gt;
           nrvt   (keep = cov1 - cov4 id match nr_);&lt;BR /&gt;
     by id;&lt;BR /&gt;
     cov1b = mod(cov1,1000);  cov1a = (cov1-cov1b)/1000;&lt;BR /&gt;
     cov2b = mod(cov2,1000);  cov2a = (cov2-cov2b)/1000;&lt;BR /&gt;
     cov3b = mod(cov3,1000);  cov3a = (cov3-cov3b)/1000;&lt;BR /&gt;
     cov4b = mod(cov4,1000);  cov4a = (cov4-cov4b)/1000;&lt;BR /&gt;
     if nr_ = 1;   /* keep only nonredundant VT */&lt;BR /&gt;
     nr+1;&lt;BR /&gt;
     call symput('nre',left(nr));  /* create macro variable &amp;amp;nre */&lt;BR /&gt;
&lt;BR /&gt;
   proc print noobs;&lt;BR /&gt;
     var id tetrad residual;&lt;BR /&gt;
     title2 'List of Nonredundant Tetrads';&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Covariances in Tetrads ....................*;&lt;BR /&gt;
   data covs;&lt;BR /&gt;
     set cta;&lt;BR /&gt;
     keep cov;&lt;BR /&gt;
     cov = cov1; output;&lt;BR /&gt;
     cov = cov2; output;&lt;BR /&gt;
     cov = cov3; output;&lt;BR /&gt;
     cov = cov4; output;&lt;BR /&gt;
     proc sort; by cov;&lt;BR /&gt;
&lt;BR /&gt;
   data nrc;    /* nonredundant covariances */&lt;BR /&gt;
     set covs; by cov;&lt;BR /&gt;
     if first.cov;&lt;BR /&gt;
     cov_b = mod(cov,1000);  cov_a = (cov-cov_b)/1000;&lt;BR /&gt;
     nc+1;&lt;BR /&gt;
     call symput('nrc',left(nc));               /* &amp;amp;nc = # cov */&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Distribution Free Estimator ...............*;&lt;BR /&gt;
   %if %upcase(&amp;amp;AC) = DFAC %then %do;&lt;BR /&gt;
      data nrc1rec;&lt;BR /&gt;
        set nrc;&lt;BR /&gt;
        retain ca1 - ca&amp;amp;nrc&lt;BR /&gt;
               cb1 - cb&amp;amp;nrc;&lt;BR /&gt;
        array ca (&amp;amp;nrc);&lt;BR /&gt;
        array cb (&amp;amp;nrc);&lt;BR /&gt;
        ca(_n_) = cov_a;&lt;BR /&gt;
        cb(_n_) = cov_b;&lt;BR /&gt;
        match = 1;&lt;BR /&gt;
        if _n_ = &amp;amp;nrc then output;&lt;BR /&gt;
        keep match ca1 - ca&amp;amp;nrc cb1 - cb&amp;amp;nrc;&lt;BR /&gt;
&lt;BR /&gt;
      data dfac;  /* distribution free AC */&lt;BR /&gt;
        merge ctrdata nrc1rec; by match;&lt;BR /&gt;
        %let nac = %eval(&amp;amp;nrc **2);           /* # AC elements */&lt;BR /&gt;
        array v (&amp;amp;k) &amp;amp;vars;&lt;BR /&gt;
        array ca (&amp;amp;nrc);&lt;BR /&gt;
        array cb (&amp;amp;nrc);&lt;BR /&gt;
        array efgh(&amp;amp;nrc,&amp;amp;nrc);&lt;BR /&gt;
        array cvab(&amp;amp;nrc);&lt;BR /&gt;
&lt;BR /&gt;
        do i = 1 to &amp;amp;nrc;&lt;BR /&gt;
           cvab(i) = v(ca(i))*v(cb(i));&lt;BR /&gt;
           do j = 1 to i;&lt;BR /&gt;
              efgh(i,j) = v(ca(i))*v(cb(i))*v(ca(j))*v(cb(j));&lt;BR /&gt;
              efgh(j,i) = efgh(i,j);&lt;BR /&gt;
           end;&lt;BR /&gt;
        end;&lt;BR /&gt;
        keep efgh1 - efgh&amp;amp;nac cvab1 - cvab&amp;amp;nrc;&lt;BR /&gt;
&lt;BR /&gt;
      proc means data=dfac noprint mean;&lt;BR /&gt;
        var efgh1 - efgh&amp;amp;nac cvab1 - cvab&amp;amp;nrc;&lt;BR /&gt;
        output out=meanout mean=;&lt;BR /&gt;
      data dfac2; set meanout;&lt;BR /&gt;
        array efgh(&amp;amp;nrc,&amp;amp;nrc);&lt;BR /&gt;
        array cvab(&amp;amp;nrc);&lt;BR /&gt;
        array dfac(&amp;amp;nrc);&lt;BR /&gt;
&lt;BR /&gt;
        do i = 1 to &amp;amp;nrc;&lt;BR /&gt;
           do j = 1 to &amp;amp;nrc;&lt;BR /&gt;
              dfac(j) = efgh(i,j) - cvab(i)*cvab(j);&lt;BR /&gt;
           end;&lt;BR /&gt;
           keep dfac1 - dfac&amp;amp;nrc;&lt;BR /&gt;
           output;&lt;BR /&gt;
        end;&lt;BR /&gt;
   %end;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Construct CTA Test ........................*;&lt;BR /&gt;
   proc iml;&lt;BR /&gt;
     start cta;&lt;BR /&gt;
&lt;BR /&gt;
     /* read data  */&lt;BR /&gt;
     use matx;&lt;BR /&gt;
       read all into s var _all_;&lt;BR /&gt;
     close matx;&lt;BR /&gt;
&lt;BR /&gt;
     use cta;&lt;BR /&gt;
       read all into nrvt var {cov1 cov2 cov3 cov4};&lt;BR /&gt;
       read all into covs&lt;BR /&gt;
            var {cov1a cov1b cov2a cov2b cov3a cov3b cov4a cov4b};&lt;BR /&gt;
       read all into td var {residual};&lt;BR /&gt;
     close cta;&lt;BR /&gt;
&lt;BR /&gt;
     use nrc;&lt;BR /&gt;
       read all into nrc  var {cov};&lt;BR /&gt;
       read all into nrcs var {cov_a cov_b};&lt;BR /&gt;
     close nrc;&lt;BR /&gt;
&lt;BR /&gt;
     /* construct derivative matrix: d */&lt;BR /&gt;
     d=j(&amp;amp;nrc,&amp;amp;nre,0);&lt;BR /&gt;
     do r=1 to &amp;amp;nrc;&lt;BR /&gt;
        do c=1 to &amp;amp;nre;&lt;BR /&gt;
           if nrc(|r,1|) = nrvt(|c,1|)&lt;BR /&gt;
              then d(|r,c|) =   s(| covs(|c,3|),covs(|c,4|) |);&lt;BR /&gt;
           if nrc(|r,1|) = nrvt(|c,2|)&lt;BR /&gt;
              then d(|r,c|) =   s(| covs(|c,1|),covs(|c,2|) |);&lt;BR /&gt;
           if nrc(|r,1|) = nrvt(|c,3|)&lt;BR /&gt;
              then d(|r,c|) = - s(| covs(|c,7|),covs(|c,8|) |);&lt;BR /&gt;
           if nrc(|r,1|) = nrvt(|c,4|)&lt;BR /&gt;
              then d(|r,c|) = - s(| covs(|c,5|),covs(|c,6|) |);&lt;BR /&gt;
        end;&lt;BR /&gt;
     end;&lt;BR /&gt;
&lt;BR /&gt;
     /* construct asymptotic cov matrix: ac */&lt;BR /&gt;
     %if %upcase(&amp;amp;AC) = DFAC %then %do;&lt;BR /&gt;
     /* distribution free AC */&lt;BR /&gt;
        use dfac2;&lt;BR /&gt;
          read all into ac var _all_;&lt;BR /&gt;
        close dfac2;&lt;BR /&gt;
        mtype = '                         ';&lt;BR /&gt;
     %end;&lt;BR /&gt;
&lt;BR /&gt;
     %else %do;&lt;BR /&gt;
     /* normal distribution  */&lt;BR /&gt;
        ac=j(&amp;amp;nrc,&amp;amp;nrc);&lt;BR /&gt;
        do i=1 to &amp;amp;nrc;&lt;BR /&gt;
           do j=1 to &amp;amp;nrc;&lt;BR /&gt;
              e=nrcs(|i,1|);&lt;BR /&gt;
              f=nrcs(|i,2|);&lt;BR /&gt;
              g=nrcs(|j,1|);&lt;BR /&gt;
              h=nrcs(|j,2|);&lt;BR /&gt;
              if diag(s) = i(&amp;amp;k) then do;&lt;BR /&gt;
                 mtype = 'Matrix Used: Correlation Matrix';&lt;BR /&gt;
                 ac(|i,j|)&lt;BR /&gt;
                   =(1/2)&lt;BR /&gt;
                    * (s(|e,f|)*s(|g,h|))&lt;BR /&gt;
                    * (s(|e,g|)**2 + s(|e,h|)**2 + s(|f,g|)**2&lt;BR /&gt;
                    + s(|f,h|)**2)&lt;BR /&gt;
                    + s(|e,g|)*s(|f,h|) + s(|e,h|)*s(|f,g|)&lt;BR /&gt;
                    - s(|e,f|)*(s(|f,g|)*s(|f,h|)+s(|e,g|)*s(|e,h|))&lt;BR /&gt;
                    - s(|g,h|)*(s(|f,g|)*s(|e,g|)+s(|f,h|)*s(|e,h|));&lt;BR /&gt;
              end;&lt;BR /&gt;
              else do;&lt;BR /&gt;
                 mtype = 'Matrix Used: Covariance Matrix ';&lt;BR /&gt;
                 ac(|i,j|)=s(|e,g|)*s(|f,h|) + s(|e,h|)*s(|f,g|);&lt;BR /&gt;
              end;&lt;BR /&gt;
           end;&lt;BR /&gt;
        end;&lt;BR /&gt;
     %end;&lt;BR /&gt;
&lt;BR /&gt;
     dacd=d`*ac*d;&lt;BR /&gt;
&lt;BR /&gt;
     df=nrow(dacd);&lt;BR /&gt;
     chi=&amp;amp;n * td` * inv(dacd) * td;&lt;BR /&gt;
     prob=1-probchi(chi,df);&lt;BR /&gt;
&lt;BR /&gt;
     title2 'Test Results';&lt;BR /&gt;
     print 'Matrix Used for the Test';&lt;BR /&gt;
     print S;&lt;BR /&gt;
     print chi (|format=8.2|)&lt;BR /&gt;
           df  (|format=8.0|)&lt;BR /&gt;
           prob(|format=8.4|);&lt;BR /&gt;
&lt;BR /&gt;
   finish;&lt;BR /&gt;
   run cta;&lt;BR /&gt;
&lt;BR /&gt;
   %end;  /* end of &amp;amp;EXEC control */&lt;BR /&gt;
%mend  cta;</description>
    <pubDate>Wed, 03 Jun 2009 04:42:16 GMT</pubDate>
    <dc:creator>deleted_user</dc:creator>
    <dc:date>2009-06-03T04:42:16Z</dc:date>
    <item>
      <title>CTA SAS macro</title>
      <link>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/40452#M8231</link>
      <description>I am very new to SAS and I have an input matrix and an macro but I am getting results .&lt;BR /&gt;
My input matrix is:&lt;BR /&gt;
%CTA-SAS2(SAMPMAT1 = &lt;BR /&gt;
&lt;BR /&gt;
1&lt;BR /&gt;
&lt;BR /&gt;
0.564 1&lt;BR /&gt;
&lt;BR /&gt;
0.531 0.496 1&lt;BR /&gt;
&lt;BR /&gt;
0.466 0.436 0.449 1&lt;BR /&gt;
&lt;BR /&gt;
0.460 0.429 0.662 0.582 1,&lt;BR /&gt;
&lt;BR /&gt;
N = 134, vars = 5, nesttest = 0, pchor = 0, lisrel = 0, mplus = 0, lowdiag=1);&lt;BR /&gt;
&lt;BR /&gt;
My huge macro:&lt;BR /&gt;
&lt;BR /&gt;
%macro cta(N=, vars=, nesttest=0, pchor=0, lisrel=0, mplus=0, SAMPMAT1=,lowdiag=1);&lt;BR /&gt;
   title1 'Confirmatory Tetrad Analysis';&lt;BR /&gt;
&lt;BR /&gt;
   *................... Macro Functions ...........................*;&lt;BR /&gt;
   %macro _resid(a,b,c,d);&lt;BR /&gt;
        /* tetrad residual */&lt;BR /&gt;
        residual = S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;c,&amp;amp;d)-S(&amp;amp;a,&amp;amp;c)*S(&amp;amp;b,&amp;amp;d);&lt;BR /&gt;
&lt;BR /&gt;
        /* asymptotic variance */&lt;BR /&gt;
        AVAR = (1/&amp;amp;N) *&lt;BR /&gt;
               (S(&amp;amp;d,&amp;amp;b)*S(&amp;amp;d,&amp;amp;b)*S(&amp;amp;a,&amp;amp;a)*S(&amp;amp;c,&amp;amp;c) +&lt;BR /&gt;
                S(&amp;amp;a,&amp;amp;c)*S(&amp;amp;a,&amp;amp;c)*S(&amp;amp;d,&amp;amp;d)*S(&amp;amp;b,&amp;amp;b) +&lt;BR /&gt;
                S(&amp;amp;d,&amp;amp;c)*S(&amp;amp;d,&amp;amp;c)*S(&amp;amp;a,&amp;amp;a)*S(&amp;amp;b,&amp;amp;b) +&lt;BR /&gt;
                S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;d,&amp;amp;d)*S(&amp;amp;c,&amp;amp;c) +&lt;BR /&gt;
            2 *(S(&amp;amp;d,&amp;amp;b)*S(&amp;amp;a,&amp;amp;c)*S(&amp;amp;a,&amp;amp;d)*S(&amp;amp;b,&amp;amp;c) -&lt;BR /&gt;
                S(&amp;amp;d,&amp;amp;b)*S(&amp;amp;d,&amp;amp;c)*S(&amp;amp;a,&amp;amp;a)*S(&amp;amp;b,&amp;amp;c) -&lt;BR /&gt;
                S(&amp;amp;d,&amp;amp;b)*S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;a,&amp;amp;d)*S(&amp;amp;c,&amp;amp;c) -&lt;BR /&gt;
                S(&amp;amp;a,&amp;amp;c)*S(&amp;amp;d,&amp;amp;c)*S(&amp;amp;d,&amp;amp;a)*S(&amp;amp;b,&amp;amp;b) -&lt;BR /&gt;
                S(&amp;amp;a,&amp;amp;c)*S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;d,&amp;amp;d)*S(&amp;amp;b,&amp;amp;c) +&lt;BR /&gt;
                S(&amp;amp;d,&amp;amp;c)*S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;a,&amp;amp;d)*S(&amp;amp;b,&amp;amp;c))+&lt;BR /&gt;
           2 *((S(&amp;amp;d,&amp;amp;b)*S(&amp;amp;a,&amp;amp;c)-S(&amp;amp;a,&amp;amp;b)*S(&amp;amp;d,&amp;amp;c))**2));&lt;BR /&gt;
&lt;BR /&gt;
        /* t-value */&lt;BR /&gt;
        tvalue = residual/sqrt(avar);&lt;BR /&gt;
&lt;BR /&gt;
        tetrad = compress('t('||&amp;amp;a||','||&amp;amp;b||','||&amp;amp;c||','||&amp;amp;d||')');&lt;BR /&gt;
   %mend _resid;&lt;BR /&gt;
&lt;BR /&gt;
   %macro _switch (first,second);&lt;BR /&gt;
         temp = &amp;amp;first;&lt;BR /&gt;
         &amp;amp;first = &amp;amp;second;&lt;BR /&gt;
         &amp;amp;second= temp;&lt;BR /&gt;
   %mend _switch;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Data Input ................................*;&lt;BR /&gt;
   /* count # of variables */&lt;BR /&gt;
   data _null_;&lt;BR /&gt;
     array varname (*) &amp;amp;vars;&lt;BR /&gt;
     call symput('k',left(dim(varname)));       /* &amp;amp;k = # vars */&lt;BR /&gt;
     call symput('m',left(dim(varname)**2));    /* &amp;amp;m = &amp;amp;k*&amp;amp;k  */&lt;BR /&gt;
   run;&lt;BR /&gt;
&lt;BR /&gt;
   %let nt = %eval(&amp;amp;k*(&amp;amp;k-1)*(&amp;amp;k-2)*(&amp;amp;k-3)/8);  /* # of tetrads*/&lt;BR /&gt;
&lt;BR /&gt;
   %if &amp;amp;data ne %str() %then %do;&lt;BR /&gt;
   /* compute covariance matrix */&lt;BR /&gt;
   /* exclude missing cases     */&lt;BR /&gt;
      proc corr data=&amp;amp;data nomiss nocorr cov out=covout noprint;&lt;BR /&gt;
        var &amp;amp;vars;&lt;BR /&gt;
      data matx; set covout;&lt;BR /&gt;
        if _type_ = 'N' then do;&lt;BR /&gt;
           maxn = max(of &amp;amp;vars);&lt;BR /&gt;
           call symput('n',maxn);               /* &amp;amp;n = # obs  */&lt;BR /&gt;
        end;&lt;BR /&gt;
        if _type_ = 'COV';&lt;BR /&gt;
        keep &amp;amp;vars;&lt;BR /&gt;
      proc print data=matx noobs;&lt;BR /&gt;
        var &amp;amp;vars;&lt;BR /&gt;
        title2 'Covariance Matrix Computed from Input Data';&lt;BR /&gt;
      data matx1rec; set matx;&lt;BR /&gt;
        retain s1 - s&amp;amp;m;&lt;BR /&gt;
        array v (*) &amp;amp;vars;&lt;BR /&gt;
        array s (&amp;amp;k,&amp;amp;k);&lt;BR /&gt;
        do i = 1 to &amp;amp;k;&lt;BR /&gt;
           s(_n_,i) = v(i);&lt;BR /&gt;
        end;&lt;BR /&gt;
        if _n_ = &amp;amp;k then output;&lt;BR /&gt;
   %end;&lt;BR /&gt;
&lt;BR /&gt;
   %else %do;&lt;BR /&gt;
   /* read covariance or correlation matrix */&lt;BR /&gt;
      data matx1rec;&lt;BR /&gt;
        %let lowtri = %eval((&amp;amp;k + 1)*(&amp;amp;k)/2);&lt;BR /&gt;
        array t(&amp;amp;lowtri) _temporary_ (&amp;amp;cmatrix);&lt;BR /&gt;
        array s(&amp;amp;k,&amp;amp;k);&lt;BR /&gt;
        do i = 1 to &amp;amp;k;&lt;BR /&gt;
           do j = 1 to i;&lt;BR /&gt;
              p + 1;&lt;BR /&gt;
              s(i,j) = t(p);&lt;BR /&gt;
              s(j,i) = t(p);&lt;BR /&gt;
           end;&lt;BR /&gt;
        end;&lt;BR /&gt;
      data matx; set matx1rec;&lt;BR /&gt;
        array v (*) &amp;amp;vars;&lt;BR /&gt;
        array s(&amp;amp;k,&amp;amp;k);&lt;BR /&gt;
        do i = 1 to &amp;amp;k;&lt;BR /&gt;
           do j = 1 to &amp;amp;k;&lt;BR /&gt;
              v(j) = s(i,j);&lt;BR /&gt;
           end;&lt;BR /&gt;
           keep &amp;amp;vars;&lt;BR /&gt;
           output;&lt;BR /&gt;
        end;&lt;BR /&gt;
      proc print data=matx noobs;&lt;BR /&gt;
        var &amp;amp;vars;&lt;BR /&gt;
        title2 'Covariance/Correlation Matrix Read from Input Matrix';&lt;BR /&gt;
   %end;&lt;BR /&gt;
&lt;BR /&gt;
   %if %upcase(&amp;amp;AC) = DFAC %then %do;&lt;BR /&gt;
   /* convert variables to deviation scores */&lt;BR /&gt;
      proc means noprint mean data=&amp;amp;data;&lt;BR /&gt;
        var &amp;amp;vars;&lt;BR /&gt;
        output out=meanout mean(&amp;amp;vars)=mean1 - mean&amp;amp;k;&lt;BR /&gt;
      data meanout; set meanout;&lt;BR /&gt;
        match=1;&lt;BR /&gt;
        keep mean1 - mean&amp;amp;k match;&lt;BR /&gt;
      data &amp;amp;data; set &amp;amp;data; match=1;&lt;BR /&gt;
      data ctrdata;&lt;BR /&gt;
        merge &amp;amp;data meanout; by match;&lt;BR /&gt;
        array x (&amp;amp;k) &amp;amp;vars;&lt;BR /&gt;
        array mean (&amp;amp;k);&lt;BR /&gt;
        do i = 1 to &amp;amp;k;&lt;BR /&gt;
           x(i) = x(i) - mean(i);&lt;BR /&gt;
        end;&lt;BR /&gt;
        keep match &amp;amp;vars;&lt;BR /&gt;
   %end;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Tetrad Construction .......................*;&lt;BR /&gt;
   data tetrad; set matx1rec;&lt;BR /&gt;
     array s (&amp;amp;k,&amp;amp;k);&lt;BR /&gt;
&lt;BR /&gt;
     /* generate all tetrads equations */&lt;BR /&gt;
     a=1; b=2; c=3; d=3;&lt;BR /&gt;
     do until (a &amp;gt; &amp;amp;k-3);&lt;BR /&gt;
        do until (b &amp;gt; &amp;amp;k-2);&lt;BR /&gt;
           do until (c &amp;gt; &amp;amp;k-1);&lt;BR /&gt;
              do until (d = &amp;amp;k);&lt;BR /&gt;
                 d=d+1;&lt;BR /&gt;
&lt;BR /&gt;
                 cov1 = a * 1000 + b; cov2 = c * 1000 + d;&lt;BR /&gt;
                 cov3 = a * 1000 + c; cov4 = b * 1000 + d;&lt;BR /&gt;
                 %_resid(a,b,c,d);&lt;BR /&gt;
                 id+1;&lt;BR /&gt;
                 output;&lt;BR /&gt;
&lt;BR /&gt;
                 cov1 = a * 1000 + b; cov2 = c * 1000 + d;&lt;BR /&gt;
                 cov3 = a * 1000 + d; cov4 = b * 1000 + c;&lt;BR /&gt;
                 %_resid(a,b,d,c);&lt;BR /&gt;
                 id+1;&lt;BR /&gt;
                 output;&lt;BR /&gt;
&lt;BR /&gt;
                 cov1 = a * 1000 + c; cov2 = b * 1000 + d;&lt;BR /&gt;
                 cov3 = a * 1000 + d; cov4 = b * 1000 + c;&lt;BR /&gt;
                 %_resid(a,c,d,b);&lt;BR /&gt;
                 id+1;&lt;BR /&gt;
                 output;&lt;BR /&gt;
&lt;BR /&gt;
              end;&lt;BR /&gt;
              c=c+1;&lt;BR /&gt;
              d=c;&lt;BR /&gt;
           end;&lt;BR /&gt;
           b=b+1;&lt;BR /&gt;
           c=b+1;&lt;BR /&gt;
           d=c;&lt;BR /&gt;
        end;&lt;BR /&gt;
        a=a+1;&lt;BR /&gt;
        b=a+1;&lt;BR /&gt;
        c=b+1;&lt;BR /&gt;
        d=c;&lt;BR /&gt;
     end;&lt;BR /&gt;
&lt;BR /&gt;
   proc print noobs;&lt;BR /&gt;
     var id tetrad residual tvalue;&lt;BR /&gt;
     title2 'List of Tetrads';&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   /* Execution Control */&lt;BR /&gt;
   %if %upcase(&amp;amp;EXEC) ne PARTIAL %then %do;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Model Implied Vanishing Tetrads ...........*;&lt;BR /&gt;
   data mivt;&lt;BR /&gt;
     set tetrad;&lt;BR /&gt;
     /* select tetrads for test */&lt;BR /&gt;
     /* first keep then drop if both options specified */&lt;BR /&gt;
     %if &amp;amp;keept ne %str() %then %do;&lt;BR /&gt;
          array keeptd (&amp;amp;nt) _temporary_ (&amp;amp;keept);&lt;BR /&gt;
          do i = 1 to &amp;amp;nt;&lt;BR /&gt;
             if keeptd(i) = . then go to exit1;&lt;BR /&gt;
             if keeptd(i) = id then keeplist = 'keep';&lt;BR /&gt;
          end;&lt;BR /&gt;
          exit1:&lt;BR /&gt;
          if keeplist = 'keep';&lt;BR /&gt;
     %end;&lt;BR /&gt;
     %if &amp;amp;dropt ne %str() %then %do;&lt;BR /&gt;
          array droptd (&amp;amp;nt) _temporary_ (&amp;amp;dropt);&lt;BR /&gt;
          do i = 1 to &amp;amp;nt;&lt;BR /&gt;
             if droptd(i) = . then go to exit2;&lt;BR /&gt;
             if droptd(i) = id then droplist = 'drop';&lt;BR /&gt;
          end;&lt;BR /&gt;
          exit2:&lt;BR /&gt;
          if droplist = 'drop' then delete;&lt;BR /&gt;
     %end;&lt;BR /&gt;
&lt;BR /&gt;
     eq+1;&lt;BR /&gt;
     call symput('eqs',left(eq));           /* &amp;amp;eqs = # of vt */&lt;BR /&gt;
&lt;BR /&gt;
     /* sort tetrads */&lt;BR /&gt;
     %if &amp;amp;sort ne %str() %then %do;&lt;BR /&gt;
        data mivt; set mivt;&lt;BR /&gt;
        array sort(&amp;amp;eqs) _temporary_ (&amp;amp;sort);&lt;BR /&gt;
        do i = 1 to &amp;amp;eqs;&lt;BR /&gt;
           if sort(i) = . then do;&lt;BR /&gt;
              rank = &amp;amp;eqs + 1;&lt;BR /&gt;
              go to exit1;&lt;BR /&gt;
           end; else&lt;BR /&gt;
           if id = sort(i) then do;&lt;BR /&gt;
              rank = i;&lt;BR /&gt;
              go to exit1;&lt;BR /&gt;
           end;&lt;BR /&gt;
        end;&lt;BR /&gt;
        exit1:&lt;BR /&gt;
     proc sort; by rank;&lt;BR /&gt;
     proc print;&lt;BR /&gt;
       var id tetrad residual cov1 cov2 cov3 cov4;&lt;BR /&gt;
       title2 'sorted tetrads';&lt;BR /&gt;
     %end;&lt;BR /&gt;
&lt;BR /&gt;
   /* Convert MIVT to single record */&lt;BR /&gt;
   data mivt1rec;&lt;BR /&gt;
     set mivt (keep = id tetrad residual cov1 cov2 cov3 cov4)&lt;BR /&gt;
         end = eof;&lt;BR /&gt;
     retain a1 - a&amp;amp;eqs&lt;BR /&gt;
            b1 - b&amp;amp;eqs&lt;BR /&gt;
            c1 - c&amp;amp;eqs&lt;BR /&gt;
            d1 - d&amp;amp;eqs&lt;BR /&gt;
            e1 - e&amp;amp;eqs 4.;&lt;BR /&gt;
&lt;BR /&gt;
     array a (*) a1 - a&amp;amp;eqs;&lt;BR /&gt;
     array b (*) b1 - b&amp;amp;eqs;&lt;BR /&gt;
     array c (*) c1 - c&amp;amp;eqs;&lt;BR /&gt;
     array d (*) d1 - d&amp;amp;eqs;&lt;BR /&gt;
     array e (*) e1 - e&amp;amp;eqs;&lt;BR /&gt;
&lt;BR /&gt;
     a(_n_) = cov1;&lt;BR /&gt;
     b(_n_) = cov2;&lt;BR /&gt;
     c(_n_) = cov3;&lt;BR /&gt;
     d(_n_) = cov4;&lt;BR /&gt;
     e(_n_) = id;&lt;BR /&gt;
&lt;BR /&gt;
     keep a1-a&amp;amp;eqs b1-b&amp;amp;eqs c1-c&amp;amp;eqs d1-d&amp;amp;eqs e1-e&amp;amp;eqs;&lt;BR /&gt;
     if eof then output;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Remove Redundant Tetrads ..................*;&lt;BR /&gt;
   data nrvt; set mivt1rec;&lt;BR /&gt;
     array a (*) a1 - a&amp;amp;eqs;&lt;BR /&gt;
     array b (*) b1 - b&amp;amp;eqs;&lt;BR /&gt;
     array c (*) c1 - c&amp;amp;eqs;&lt;BR /&gt;
     array d (*) d1 - d&amp;amp;eqs;&lt;BR /&gt;
     array e  (*) e1  - e&amp;amp;eqs;&lt;BR /&gt;
     array nr (*) nr01 - nr&amp;amp;eqs;&lt;BR /&gt;
     array im (*) im01 - im&amp;amp;eqs;&lt;BR /&gt;
&lt;BR /&gt;
     do i = 1 to dim(nr);&lt;BR /&gt;
        if im(i) ne 1 then nr(i) = 1;                /* NR VT */&lt;BR /&gt;
&lt;BR /&gt;
        /* check implied VTs from VT1 to VTi */&lt;BR /&gt;
        do p = 1 to i-1, i+1 to dim(nr);&lt;BR /&gt;
           if p &amp;lt; i or im(p) = 1 then do;&lt;BR /&gt;
              /* step 1: find 2 share covs */&lt;BR /&gt;
              cu1=a(i); cu2=b(i); cu3=c(i); cu4=d(i);&lt;BR /&gt;
              ps1=a(p); ps2=b(p); ps3=c(p); ps4=d(p);&lt;BR /&gt;
              array cu (*) cu1 cu2 cu3 cu4;  /* current  VT */&lt;BR /&gt;
              array ps (*) ps1 ps2 ps3 ps4;  /* previous VT */&lt;BR /&gt;
              share = 0;&lt;BR /&gt;
              lhs = 0;&lt;BR /&gt;
              rhs = 0;&lt;BR /&gt;
              xhs = 0;&lt;BR /&gt;
&lt;BR /&gt;
              /* find shared covs from 2 tetrads */&lt;BR /&gt;
              do x = 1 to 4;&lt;BR /&gt;
                 do y = 1 to 4;&lt;BR /&gt;
                    if cu(x) = ps(y) then do;&lt;BR /&gt;
                       share = share + 1;&lt;BR /&gt;
                       if x &amp;lt;= 2 &amp;amp; y &amp;lt;= 2 then lhs = lhs + 1;&lt;BR /&gt;
                       if x &amp;gt;= 3 &amp;amp; y &amp;gt;= 3 then rhs = rhs + 1;&lt;BR /&gt;
                       if x &amp;lt;= 2          then xhs = xhs + 1;&lt;BR /&gt;
                    end;&lt;BR /&gt;
&lt;BR /&gt;
                    if share = 2 then do;&lt;BR /&gt;
                       if lhs = 1 &amp;amp; rhs = 1 then do;&lt;BR /&gt;
                          do x = 1 to 4;&lt;BR /&gt;
                             do y = 1 to 4;&lt;BR /&gt;
                                if cu(x) = ps(y) then do;&lt;BR /&gt;
                                   if x = 1 then cv1 = cu(2); else&lt;BR /&gt;
                                   if x = 2 then cv1 = cu(1); else&lt;BR /&gt;
                                   if x = 3 then cv4 = cu(4); else&lt;BR /&gt;
                                   if x = 4 then cv4 = cu(3);&lt;BR /&gt;
&lt;BR /&gt;
                                   if y = 1 then cv3 = ps(2); else&lt;BR /&gt;
                                   if y = 2 then cv3 = ps(1); else&lt;BR /&gt;
                                   if y = 3 then cv2 = ps(4); else&lt;BR /&gt;
                                   if y = 4 then cv2 = ps(3);&lt;BR /&gt;
                                end;&lt;BR /&gt;
                             end;&lt;BR /&gt;
                          end;&lt;BR /&gt;
                       end;&lt;BR /&gt;
                       if lhs = 2 then do;&lt;BR /&gt;
                          cv1 = cu(3);&lt;BR /&gt;
                          cv2 = cu(4);&lt;BR /&gt;
                          cv3 = ps(3);&lt;BR /&gt;
                          cv4 = ps(4);&lt;BR /&gt;
                       end;&lt;BR /&gt;
                       if rhs = 2 then do;&lt;BR /&gt;
                          cv1 = cu(1);&lt;BR /&gt;
                          cv2 = cu(2);&lt;BR /&gt;
                          cv3 = ps(1);&lt;BR /&gt;
                          cv4 = ps(2);&lt;BR /&gt;
                       end;&lt;BR /&gt;
                       if lhs = 0 &amp;amp; rhs = 0 then do;&lt;BR /&gt;
                          if xhs = 1 then do;&lt;BR /&gt;
                             do x = 1 to 4;&lt;BR /&gt;
                                do y = 1 to 4;&lt;BR /&gt;
                                   if cu(x) = ps(y) then do;&lt;BR /&gt;
                                      if x = 1 then cv1 = cu(2); else&lt;BR /&gt;
                                      if x = 2 then cv1 = cu(1); else&lt;BR /&gt;
                                      if x = 3 then cv3 = cu(4); else&lt;BR /&gt;
                                      if x = 4 then cv3 = cu(3);&lt;BR /&gt;
&lt;BR /&gt;
                                      if y = 1 then cv2 = ps(2); else&lt;BR /&gt;
                                      if y = 2 then cv2 = ps(1); else&lt;BR /&gt;
                                      if y = 3 then cv4 = ps(4); else&lt;BR /&gt;
                                      if y = 4 then cv4 = ps(3);&lt;BR /&gt;
                                   end;&lt;BR /&gt;
                                end;&lt;BR /&gt;
                             end;&lt;BR /&gt;
                          end;&lt;BR /&gt;
                          if xhs = 0 then do;&lt;BR /&gt;
                             cv1 = cu(1);&lt;BR /&gt;
                             cv2 = cu(2);&lt;BR /&gt;
                             cv3 = ps(3);&lt;BR /&gt;
                             cv4 = ps(4);&lt;BR /&gt;
                          end;&lt;BR /&gt;
                          if xhs = 2 then do;&lt;BR /&gt;
                             cv1 = cu(3);&lt;BR /&gt;
                             cv2 = cu(4);&lt;BR /&gt;
                             cv3 = ps(1);&lt;BR /&gt;
                             cv4 = ps(2);&lt;BR /&gt;
                          end;&lt;BR /&gt;
                       end;&lt;BR /&gt;
&lt;BR /&gt;
                    end;&lt;BR /&gt;
                 end;&lt;BR /&gt;
              end;&lt;BR /&gt;
&lt;BR /&gt;
              /* step 2: if 2 share covs is found, construct IM VT */&lt;BR /&gt;
              if share = 2 then do;&lt;BR /&gt;
                 if cv1 &amp;gt; cv2 then do;&lt;BR /&gt;
                    %_switch(cv1,cv2);&lt;BR /&gt;
                 end;&lt;BR /&gt;
                 if cv3 &amp;gt; cv4 then do;&lt;BR /&gt;
                    %_switch(cv3,cv4);&lt;BR /&gt;
                 end;&lt;BR /&gt;
&lt;BR /&gt;
                 if cv1 &amp;gt; cv3 then do;&lt;BR /&gt;
                    %_switch(cv1,cv3);&lt;BR /&gt;
                    %_switch(cv2,cv4);&lt;BR /&gt;
                 end;&lt;BR /&gt;
&lt;BR /&gt;
                 /* step 3: compare 4 covs from i+1 to last */&lt;BR /&gt;
                 do cp = i+1 to dim(nr);&lt;BR /&gt;
                    count = 0;&lt;BR /&gt;
                    cp1=a(cp); cp2=b(cp); cp3=c(cp); cp4=d(cp);&lt;BR /&gt;
                    array cv (*) cv1 cv2 cv3 cv4;&lt;BR /&gt;
                    array af (*) cp1 cp2 cp3 cp4;&lt;BR /&gt;
                    do m = 1 to 4;&lt;BR /&gt;
                       do n = 1 to 4;&lt;BR /&gt;
                          if cv(m) = af(n) then count = count+1;&lt;BR /&gt;
                          if count = 4 then do;&lt;BR /&gt;
                             if im(cp) ne 1 then do s=i+1 to dim(nr);&lt;BR /&gt;
                                if im(s) ne 1 then do;&lt;BR /&gt;
                                   %_switch(a(s),a(cp));&lt;BR /&gt;
                                   %_switch(b(s),b(cp));&lt;BR /&gt;
                                   %_switch(c(s),c(cp));&lt;BR /&gt;
                                   %_switch(d(s),d(cp));&lt;BR /&gt;
                                   %_switch(e(s),e(cp));&lt;BR /&gt;
                                   im(s)=1;&lt;BR /&gt;
                                   go to exit1;&lt;BR /&gt;
                                end;&lt;BR /&gt;
                             end;&lt;BR /&gt;
                          end;&lt;BR /&gt;
                       end;&lt;BR /&gt;
                    end;&lt;BR /&gt;
                 end;&lt;BR /&gt;
              end;&lt;BR /&gt;
              exit1:&lt;BR /&gt;
           end;&lt;BR /&gt;
        end;&lt;BR /&gt;
     end;&lt;BR /&gt;
&lt;BR /&gt;
     do i=1 to &amp;amp;eqs;&lt;BR /&gt;
       cov1 = a(i);&lt;BR /&gt;
       cov2 = b(i);&lt;BR /&gt;
       cov3 = c(i);&lt;BR /&gt;
       cov4 = d(i);&lt;BR /&gt;
       id   = e(i);&lt;BR /&gt;
       nr_  = nr(i);&lt;BR /&gt;
       match= 1;&lt;BR /&gt;
       keep id match nr_ cov1 - cov4;&lt;BR /&gt;
       output;&lt;BR /&gt;
     end;&lt;BR /&gt;
   proc sort; by id;&lt;BR /&gt;
&lt;BR /&gt;
   data cta;&lt;BR /&gt;
     merge tetrad (keep = id tetrad residual)&lt;BR /&gt;
           nrvt   (keep = cov1 - cov4 id match nr_);&lt;BR /&gt;
     by id;&lt;BR /&gt;
     cov1b = mod(cov1,1000);  cov1a = (cov1-cov1b)/1000;&lt;BR /&gt;
     cov2b = mod(cov2,1000);  cov2a = (cov2-cov2b)/1000;&lt;BR /&gt;
     cov3b = mod(cov3,1000);  cov3a = (cov3-cov3b)/1000;&lt;BR /&gt;
     cov4b = mod(cov4,1000);  cov4a = (cov4-cov4b)/1000;&lt;BR /&gt;
     if nr_ = 1;   /* keep only nonredundant VT */&lt;BR /&gt;
     nr+1;&lt;BR /&gt;
     call symput('nre',left(nr));  /* create macro variable &amp;amp;nre */&lt;BR /&gt;
&lt;BR /&gt;
   proc print noobs;&lt;BR /&gt;
     var id tetrad residual;&lt;BR /&gt;
     title2 'List of Nonredundant Tetrads';&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Covariances in Tetrads ....................*;&lt;BR /&gt;
   data covs;&lt;BR /&gt;
     set cta;&lt;BR /&gt;
     keep cov;&lt;BR /&gt;
     cov = cov1; output;&lt;BR /&gt;
     cov = cov2; output;&lt;BR /&gt;
     cov = cov3; output;&lt;BR /&gt;
     cov = cov4; output;&lt;BR /&gt;
     proc sort; by cov;&lt;BR /&gt;
&lt;BR /&gt;
   data nrc;    /* nonredundant covariances */&lt;BR /&gt;
     set covs; by cov;&lt;BR /&gt;
     if first.cov;&lt;BR /&gt;
     cov_b = mod(cov,1000);  cov_a = (cov-cov_b)/1000;&lt;BR /&gt;
     nc+1;&lt;BR /&gt;
     call symput('nrc',left(nc));               /* &amp;amp;nc = # cov */&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Distribution Free Estimator ...............*;&lt;BR /&gt;
   %if %upcase(&amp;amp;AC) = DFAC %then %do;&lt;BR /&gt;
      data nrc1rec;&lt;BR /&gt;
        set nrc;&lt;BR /&gt;
        retain ca1 - ca&amp;amp;nrc&lt;BR /&gt;
               cb1 - cb&amp;amp;nrc;&lt;BR /&gt;
        array ca (&amp;amp;nrc);&lt;BR /&gt;
        array cb (&amp;amp;nrc);&lt;BR /&gt;
        ca(_n_) = cov_a;&lt;BR /&gt;
        cb(_n_) = cov_b;&lt;BR /&gt;
        match = 1;&lt;BR /&gt;
        if _n_ = &amp;amp;nrc then output;&lt;BR /&gt;
        keep match ca1 - ca&amp;amp;nrc cb1 - cb&amp;amp;nrc;&lt;BR /&gt;
&lt;BR /&gt;
      data dfac;  /* distribution free AC */&lt;BR /&gt;
        merge ctrdata nrc1rec; by match;&lt;BR /&gt;
        %let nac = %eval(&amp;amp;nrc **2);           /* # AC elements */&lt;BR /&gt;
        array v (&amp;amp;k) &amp;amp;vars;&lt;BR /&gt;
        array ca (&amp;amp;nrc);&lt;BR /&gt;
        array cb (&amp;amp;nrc);&lt;BR /&gt;
        array efgh(&amp;amp;nrc,&amp;amp;nrc);&lt;BR /&gt;
        array cvab(&amp;amp;nrc);&lt;BR /&gt;
&lt;BR /&gt;
        do i = 1 to &amp;amp;nrc;&lt;BR /&gt;
           cvab(i) = v(ca(i))*v(cb(i));&lt;BR /&gt;
           do j = 1 to i;&lt;BR /&gt;
              efgh(i,j) = v(ca(i))*v(cb(i))*v(ca(j))*v(cb(j));&lt;BR /&gt;
              efgh(j,i) = efgh(i,j);&lt;BR /&gt;
           end;&lt;BR /&gt;
        end;&lt;BR /&gt;
        keep efgh1 - efgh&amp;amp;nac cvab1 - cvab&amp;amp;nrc;&lt;BR /&gt;
&lt;BR /&gt;
      proc means data=dfac noprint mean;&lt;BR /&gt;
        var efgh1 - efgh&amp;amp;nac cvab1 - cvab&amp;amp;nrc;&lt;BR /&gt;
        output out=meanout mean=;&lt;BR /&gt;
      data dfac2; set meanout;&lt;BR /&gt;
        array efgh(&amp;amp;nrc,&amp;amp;nrc);&lt;BR /&gt;
        array cvab(&amp;amp;nrc);&lt;BR /&gt;
        array dfac(&amp;amp;nrc);&lt;BR /&gt;
&lt;BR /&gt;
        do i = 1 to &amp;amp;nrc;&lt;BR /&gt;
           do j = 1 to &amp;amp;nrc;&lt;BR /&gt;
              dfac(j) = efgh(i,j) - cvab(i)*cvab(j);&lt;BR /&gt;
           end;&lt;BR /&gt;
           keep dfac1 - dfac&amp;amp;nrc;&lt;BR /&gt;
           output;&lt;BR /&gt;
        end;&lt;BR /&gt;
   %end;&lt;BR /&gt;
&lt;BR /&gt;
&lt;BR /&gt;
   *................... Construct CTA Test ........................*;&lt;BR /&gt;
   proc iml;&lt;BR /&gt;
     start cta;&lt;BR /&gt;
&lt;BR /&gt;
     /* read data  */&lt;BR /&gt;
     use matx;&lt;BR /&gt;
       read all into s var _all_;&lt;BR /&gt;
     close matx;&lt;BR /&gt;
&lt;BR /&gt;
     use cta;&lt;BR /&gt;
       read all into nrvt var {cov1 cov2 cov3 cov4};&lt;BR /&gt;
       read all into covs&lt;BR /&gt;
            var {cov1a cov1b cov2a cov2b cov3a cov3b cov4a cov4b};&lt;BR /&gt;
       read all into td var {residual};&lt;BR /&gt;
     close cta;&lt;BR /&gt;
&lt;BR /&gt;
     use nrc;&lt;BR /&gt;
       read all into nrc  var {cov};&lt;BR /&gt;
       read all into nrcs var {cov_a cov_b};&lt;BR /&gt;
     close nrc;&lt;BR /&gt;
&lt;BR /&gt;
     /* construct derivative matrix: d */&lt;BR /&gt;
     d=j(&amp;amp;nrc,&amp;amp;nre,0);&lt;BR /&gt;
     do r=1 to &amp;amp;nrc;&lt;BR /&gt;
        do c=1 to &amp;amp;nre;&lt;BR /&gt;
           if nrc(|r,1|) = nrvt(|c,1|)&lt;BR /&gt;
              then d(|r,c|) =   s(| covs(|c,3|),covs(|c,4|) |);&lt;BR /&gt;
           if nrc(|r,1|) = nrvt(|c,2|)&lt;BR /&gt;
              then d(|r,c|) =   s(| covs(|c,1|),covs(|c,2|) |);&lt;BR /&gt;
           if nrc(|r,1|) = nrvt(|c,3|)&lt;BR /&gt;
              then d(|r,c|) = - s(| covs(|c,7|),covs(|c,8|) |);&lt;BR /&gt;
           if nrc(|r,1|) = nrvt(|c,4|)&lt;BR /&gt;
              then d(|r,c|) = - s(| covs(|c,5|),covs(|c,6|) |);&lt;BR /&gt;
        end;&lt;BR /&gt;
     end;&lt;BR /&gt;
&lt;BR /&gt;
     /* construct asymptotic cov matrix: ac */&lt;BR /&gt;
     %if %upcase(&amp;amp;AC) = DFAC %then %do;&lt;BR /&gt;
     /* distribution free AC */&lt;BR /&gt;
        use dfac2;&lt;BR /&gt;
          read all into ac var _all_;&lt;BR /&gt;
        close dfac2;&lt;BR /&gt;
        mtype = '                         ';&lt;BR /&gt;
     %end;&lt;BR /&gt;
&lt;BR /&gt;
     %else %do;&lt;BR /&gt;
     /* normal distribution  */&lt;BR /&gt;
        ac=j(&amp;amp;nrc,&amp;amp;nrc);&lt;BR /&gt;
        do i=1 to &amp;amp;nrc;&lt;BR /&gt;
           do j=1 to &amp;amp;nrc;&lt;BR /&gt;
              e=nrcs(|i,1|);&lt;BR /&gt;
              f=nrcs(|i,2|);&lt;BR /&gt;
              g=nrcs(|j,1|);&lt;BR /&gt;
              h=nrcs(|j,2|);&lt;BR /&gt;
              if diag(s) = i(&amp;amp;k) then do;&lt;BR /&gt;
                 mtype = 'Matrix Used: Correlation Matrix';&lt;BR /&gt;
                 ac(|i,j|)&lt;BR /&gt;
                   =(1/2)&lt;BR /&gt;
                    * (s(|e,f|)*s(|g,h|))&lt;BR /&gt;
                    * (s(|e,g|)**2 + s(|e,h|)**2 + s(|f,g|)**2&lt;BR /&gt;
                    + s(|f,h|)**2)&lt;BR /&gt;
                    + s(|e,g|)*s(|f,h|) + s(|e,h|)*s(|f,g|)&lt;BR /&gt;
                    - s(|e,f|)*(s(|f,g|)*s(|f,h|)+s(|e,g|)*s(|e,h|))&lt;BR /&gt;
                    - s(|g,h|)*(s(|f,g|)*s(|e,g|)+s(|f,h|)*s(|e,h|));&lt;BR /&gt;
              end;&lt;BR /&gt;
              else do;&lt;BR /&gt;
                 mtype = 'Matrix Used: Covariance Matrix ';&lt;BR /&gt;
                 ac(|i,j|)=s(|e,g|)*s(|f,h|) + s(|e,h|)*s(|f,g|);&lt;BR /&gt;
              end;&lt;BR /&gt;
           end;&lt;BR /&gt;
        end;&lt;BR /&gt;
     %end;&lt;BR /&gt;
&lt;BR /&gt;
     dacd=d`*ac*d;&lt;BR /&gt;
&lt;BR /&gt;
     df=nrow(dacd);&lt;BR /&gt;
     chi=&amp;amp;n * td` * inv(dacd) * td;&lt;BR /&gt;
     prob=1-probchi(chi,df);&lt;BR /&gt;
&lt;BR /&gt;
     title2 'Test Results';&lt;BR /&gt;
     print 'Matrix Used for the Test';&lt;BR /&gt;
     print S;&lt;BR /&gt;
     print chi (|format=8.2|)&lt;BR /&gt;
           df  (|format=8.0|)&lt;BR /&gt;
           prob(|format=8.4|);&lt;BR /&gt;
&lt;BR /&gt;
   finish;&lt;BR /&gt;
   run cta;&lt;BR /&gt;
&lt;BR /&gt;
   %end;  /* end of &amp;amp;EXEC control */&lt;BR /&gt;
%mend  cta;</description>
      <pubDate>Wed, 03 Jun 2009 04:42:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/40452#M8231</guid>
      <dc:creator>deleted_user</dc:creator>
      <dc:date>2009-06-03T04:42:16Z</dc:date>
    </item>
    <item>
      <title>Re: CTA SAS macro</title>
      <link>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/40453#M8232</link>
      <description>There is a problem with line feeds in your post, which will make your code nearly impossible to understand. Even if I could, your question is too vague and the code too complex. Try to make your question more specified, and narrow down the code to more generic, and focused on your problem.&lt;BR /&gt;
&lt;BR /&gt;
/Linus</description>
      <pubDate>Wed, 03 Jun 2009 08:55:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/40453#M8232</guid>
      <dc:creator>LinusH</dc:creator>
      <dc:date>2009-06-03T08:55:26Z</dc:date>
    </item>
    <item>
      <title>CTA SAS macro</title>
      <link>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/40454#M8233</link>
      <description>I am trying to get output using Covariance matrix and the macro. The macro  defined as &lt;BR /&gt;
%macro cta(data=, cmatrix=, vars=, n=,&lt;BR /&gt;
           keept=, dropt=, sort=, exec=, ac=);&lt;BR /&gt;
where as my input matrix has no mention of them.&lt;BR /&gt;
&lt;BR /&gt;
Link to the macro :&lt;BR /&gt;
&lt;A href="http://www.cuhk.edu.hk/soc/ting/CTA-SAS2.MAC" target="_blank"&gt;http://www.cuhk.edu.hk/soc/ting/CTA-SAS2.MAC&lt;/A&gt;&lt;BR /&gt;
&lt;BR /&gt;
And my input matrix :&lt;BR /&gt;
%CTA-SAS2(SAMPMAT1 = &lt;BR /&gt;
1&lt;BR /&gt;
&lt;BR /&gt;
0.564 1&lt;BR /&gt;
&lt;BR /&gt;
0.531 0.496 1&lt;BR /&gt;
&lt;BR /&gt;
0.466 0.436 0.449 1&lt;BR /&gt;
&lt;BR /&gt;
0.460 0.429 0.662 0.582 1,&lt;BR /&gt;
&lt;BR /&gt;
N = 134, vars = 5, nesttest = 0, pchor = 0, lisrel = 0, mplus = 0, lowdiag=1);

Message was edited by: Varsha</description>
      <pubDate>Fri, 05 Jun 2009 06:57:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/40454#M8233</guid>
      <dc:creator>deleted_user</dc:creator>
      <dc:date>2009-06-05T06:57:46Z</dc:date>
    </item>
    <item>
      <title>Re: CTA SAS macro</title>
      <link>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/40455#M8234</link>
      <description>This forum couldn't possible be the right place for getting help on how to use/modify an extensive macro like that. &lt;BR /&gt;
If this is not a SAS Institute created macro, I suggest that you make contact with person who did.&lt;BR /&gt;
&lt;BR /&gt;
/Linus</description>
      <pubDate>Fri, 05 Jun 2009 15:24:24 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/40455#M8234</guid>
      <dc:creator>LinusH</dc:creator>
      <dc:date>2009-06-05T15:24:24Z</dc:date>
    </item>
    <item>
      <title>Re: CTA SAS macro</title>
      <link>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/40456#M8235</link>
      <description>Hi:&lt;BR /&gt;
  Possibly reading the documentation, written by the author and published at this UNC site might help:&lt;BR /&gt;
&lt;BR /&gt;
&lt;A href="http://www.unc.edu/~johnhipp/CTANEST1_documentation.doc" target="_blank"&gt;http://www.unc.edu/~johnhipp/CTANEST1_documentation.doc&lt;/A&gt;&lt;BR /&gt;
&lt;A href="http://www.unc.edu/~dbauer/manuscripts/hipp-bauer-bollen-SEM-2005.pdf" target="_blank"&gt;http://www.unc.edu/~dbauer/manuscripts/hipp-bauer-bollen-SEM-2005.pdf&lt;/A&gt;&lt;BR /&gt;
 &lt;BR /&gt;
cynthia</description>
      <pubDate>Sat, 06 Jun 2009 21:12:21 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/40456#M8235</guid>
      <dc:creator>Cynthia_sas</dc:creator>
      <dc:date>2009-06-06T21:12:21Z</dc:date>
    </item>
    <item>
      <title>Re: CTA SAS macro</title>
      <link>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/401619#M97483</link>
      <description>Dear professor, could u give me the macro CTA-SAS? I m a doctoral student from China, cause the website they give are not connected. And this macro is very important to my research. Thanks</description>
      <pubDate>Fri, 06 Oct 2017 05:54:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/CTA-SAS-macro/m-p/401619#M97483</guid>
      <dc:creator>JLUbussiness</dc:creator>
      <dc:date>2017-10-06T05:54:07Z</dc:date>
    </item>
  </channel>
</rss>

