| 
    SNAP Library 2.0, Developer Reference
    2013-05-13 16:33:57
    
   SNAP, a general purpose, high performance system for analysis and manipulation of large networks 
   | 
  
  
  
 
#include <linalg.h>
Static Public Member Functions | |
| static void | SymetricToTridiag (TFltVV &a, int n, TFltV &d, TFltV &e) | 
| static void | EigSymmetricTridiag (TFltV &d, TFltV &e, int n, TFltVV &z) | 
| static void | CholeskyDecomposition (TFltVV &A, TFltV &p) | 
| static void | CholeskySolve (const TFltVV &A, const TFltV &p, const TFltV &b, TFltV &x) | 
| static void | SolveSymetricSystem (TFltVV &A, const TFltV &b, TFltV &x) | 
| static void | InverseSubstitute (TFltVV &A, const TFltV &p) | 
| static void | InverseSymetric (TFltVV &A) | 
| static void | InverseTriagonal (TFltVV &A) | 
| static void | LUDecomposition (TFltVV &A, TIntV &indx, double &d) | 
| static void | LUSolve (const TFltVV &A, const TIntV &indx, TFltV &b) | 
| static void | SolveLinearSystem (TFltVV &A, const TFltV &b, TFltV &x) | 
Static Private Member Functions | |
| static double | sqr (double a) | 
| static double | sign (double a, double b) | 
| static double | pythag (double a, double b) | 
| static void | nrerror (const TStr &error_text) | 
| void TNumericalStuff::CholeskyDecomposition | ( | TFltVV & | A, | 
| TFltV & | p | ||
| ) |  [static] | 
        
Definition at line 794 of file linalg.cpp.
References Assert, TVVec< TVal >::GetCols(), TVVec< TVal >::GetRows(), nrerror(), and TVec< TVal, TSizeTy >::Reserve().
Referenced by InverseSymetric(), and SolveSymetricSystem().
                                                               {
  Assert(A.GetRows() == A.GetCols());
  int n = A.GetRows(); p.Reserve(n,n);
  int i,j,k;
  double sum;
  for (i=1;i<=n;i++) {
    for (j=i;j<=n;j++) {
      for (sum=A(i-1,j-1),k=i-1;k>=1;k--) sum -= A(i-1,k-1)*A(j-1,k-1);
      if (i == j) {
        if (sum <= 0.0)
          nrerror("choldc failed");
        p[i-1]=sqrt(sum);
      } else A(j-1,i-1)=sum/p[i-1];
    }
  }
}


| void TNumericalStuff::CholeskySolve | ( | const TFltVV & | A, | 
| const TFltV & | p, | ||
| const TFltV & | b, | ||
| TFltV & | x | ||
| ) |  [static] | 
        
Definition at line 812 of file linalg.cpp.
References TVVec< TVal >::GetCols(), TVVec< TVal >::GetRows(), IAssert, and TVec< TVal, TSizeTy >::Reserve().
Referenced by SolveSymetricSystem().
                                                                                             {
  IAssert(A.GetRows() == A.GetCols());
  int n = A.GetRows(); x.Reserve(n,n);
  int i,k;
  double sum;
  // Solve L * y = b, storing y in x
  for (i=1;i<=n;i++) {
    for (sum=b[i-1],k=i-1;k>=1;k--)
      sum -= A(i-1,k-1)*x[k-1];
    x[i-1]=sum/p[i-1];
  }
  // Solve L^T * x = y
  for (i=n;i>=1;i--) {
    for (sum=x[i-1],k=i+1;k<=n;k++)
      sum -= A(k-1,i-1)*x[k-1];
    x[i-1]=sum/p[i-1];
  }
}


| void TNumericalStuff::EigSymmetricTridiag | ( | TFltV & | d, | 
| TFltV & | e, | ||
| int | n, | ||
| TFltVV & | z | ||
| ) |  [static] | 
        
Definition at line 737 of file linalg.cpp.
References TFlt::Abs(), nrerror(), pythag(), and sign().
Referenced by TSparseSVD::Lanczos(), TSparseSVD::Lanczos2(), and TSparseSVD::SimpleLanczos().
                                                                              {
    int m,l,iter,i,k; // N = n+1;
    double s,r,p,g,f,dd,c,b;
    // Convenient to renumber the elements of e
    for (i=2;i<=n;i++) e[i-1]=e[i];
    e[n]=0.0;
    for (l=1;l<=n;l++) {
        iter=0;
        do {
            // Look for a single small subdiagonal element to split the matrix.
            for (m=l;m<=n-1;m++) {
        dd=TFlt::Abs(d[m])+TFlt::Abs(d[m+1]);
                if ((double)(TFlt::Abs(e[m])+dd) == dd) break;
            }
            if (m != l) {
                if (iter++ == 60) nrerror("Too many iterations in EigSymmetricTridiag");
                //Form shift.
                g=(d[l+1]-d[l])/(2.0*e[l]);
                r=pythag(g,1.0);
                //This is dm - ks.
                g=d[m]-d[l]+e[l]/(g+sign(r,g));
                s=c=1.0;
                p=0.0;
                // A plane rotation as in the original QL, followed by
                // Givens rotations to restore tridiagonal form
                for (i=m-1;i>=l;i--) {
                    f=s*e[i];
                    b=c*e[i];
                    e[i+1]=(r=pythag(f,g));
                    // Recover from underflow.
                    if (r == 0.0) {
                        d[i+1] -= p;
                        e[m]=0.0;
                        break;
                    }
                    s=f/r;
                    c=g/r;
                    g=d[i+1]-p;
                    r=(d[i]-g)*s+2.0*c*b;
                    d[i+1]=g+(p=s*r);
                    g=c*r-b;
                    // Next loop can be omitted if eigenvectors not wanted
                    for (k=0;k<n;k++) {
                        f=z(k,i);
                        z(k,i)=s*z(k,i-1)+c*f;
                        z(k,i-1)=c*z(k,i-1)-s*f;
                    }
                }
                if (r == 0.0 && i >= l) continue;
                d[l] -= p;
                e[l]=g;
                e[m]=0.0;
            }
        } while (m != l);
    }
}


| void TNumericalStuff::InverseSubstitute | ( | TFltVV & | A, | 
| const TFltV & | p | ||
| ) |  [static] | 
        
Definition at line 840 of file linalg.cpp.
References TVVec< TVal >::GetCols(), TVVec< TVal >::GetRows(), and IAssert.
Referenced by InverseSymetric().
                                                                 {
  IAssert(A.GetRows() == A.GetCols());
  int n = A.GetRows(); TFltV x(n);
    int i, j, k; double sum;
    for (i = 0; i < n; i++) {
      // solve L * y = e_i, store in x
        // elements from 0 to i-1 are 0.0
        for (j = 0; j < i; j++) x[j] = 0.0;
        // solve l_ii * y_i = 1 => y_i = 1/l_ii
        x[i] = 1/p[i];
        // solve y_j for j > i
        for (j = i+1; j < n; j++) {
            for (sum = 0.0, k = i; k < j; k++)
                sum -= A(j,k) * x[k];
            x[j] = sum / p[j];
        }
      // solve L'* x = y, store in upper triangule of A
        for (j = n-1; j >= i; j--) {
            for (sum = x[j], k = j+1; k < n; k++)
                sum -= A(k,j)*x[k];
            x[j] = sum/p[j];
        }
        for (int j = i; j < n; j++) A(i,j) = x[j];
    }
}


| void TNumericalStuff::InverseSymetric | ( | TFltVV & | A | ) |  [static] | 
        
Definition at line 869 of file linalg.cpp.
References CholeskyDecomposition(), TVVec< TVal >::GetCols(), TVVec< TVal >::GetRows(), IAssert, and InverseSubstitute().
                                               {
    IAssert(A.GetRows() == A.GetCols());
    TFltV p;
    // first we calculate cholesky decomposition of A
    CholeskyDecomposition(A, p);
    // than we solve system A x_i = e_i for i = 1..n
    InverseSubstitute(A, p);
}

| void TNumericalStuff::InverseTriagonal | ( | TFltVV & | A | ) |  [static] | 
        
Definition at line 878 of file linalg.cpp.
References TVVec< TVal >::GetCols(), TVVec< TVal >::GetRows(), and IAssert.
                                                {
  IAssert(A.GetRows() == A.GetCols());
  int n = A.GetRows(); TFltV x(n), p(n);
    int i, j, k; double sum;
    // copy upper triangle to lower one as we'll overwrite upper one
    for (i = 0; i < n; i++) {
        p[i] = A(i,i);
        for (j = i+1; j < n; j++)
            A(j,i) = A(i,j);
    }
    // solve
    for (i = 0; i < n; i++) {
        // solve R * x = e_i, store in x
        // elements from 0 to i-1 are 0.0
        for (j = n-1; j > i; j--) x[j] = 0.0;
        // solve l_ii * y_i = 1 => y_i = 1/l_ii
        x[i] = 1/p[i];
        // solve y_j for j > i
        for (j = i-1; j >= 0; j--) {
            for (sum = 0.0, k = i; k > j; k--)
                sum -= A(k,j) * x[k];
            x[j] = sum / p[j];
        }
        for (int j = 0; j <= i; j++) A(j,i) = x[j];
    }
}

| void TNumericalStuff::LUDecomposition | ( | TFltVV & | A, | 
| TIntV & | indx, | ||
| double & | d | ||
| ) |  [static] | 
        
Definition at line 906 of file linalg.cpp.
References TFlt::Abs(), Assert, TVVec< TVal >::GetCols(), TVVec< TVal >::GetRows(), nrerror(), and TVec< TVal, TSizeTy >::Reserve().
Referenced by SolveLinearSystem().
                                                                       {
  Assert(A.GetRows() == A.GetCols());
  int n = A.GetRows(); indx.Reserve(n,n);
    int i=0,imax=0,j=0,k=0;
    double big,dum,sum,temp;
    TFltV vv(n); // vv stores the implicit scaling of each row.
    d=1.0;       // No row interchanges yet.
    // Loop over rows to get the implicit scaling information.
    for (i=1;i<=n;i++) {
        big=0.0;
        for (j=1;j<=n;j++)
            if ((temp=TFlt::Abs(A(i-1,j-1))) > big) big=temp;
        if (big == 0.0) nrerror("Singular matrix in routine LUDecomposition");
        vv[i-1]=1.0/big;
    }
    for (j=1;j<=n;j++) {
        for (i=1;i<j;i++) {
            sum=A(i-1,j-1);
            for (k=1;k<i;k++) sum -= A(i-1,k-1)*A(k-1,j-1);
            A(i-1,j-1)=sum;
        }
        big=0.0; //Initialize for the search for largest pivot element.
        for (i=j;i<=n;i++) {
            sum=A(i-1,j-1);
            for (k=1;k<j;k++)
                sum -= A(i-1,k-1)*A(k-1,j-1);
            A(i-1,j-1)=sum;
            //Is the figure of merit for the pivot better than the best so far?
            if ((dum=vv[i-1] * TFlt::Abs(sum)) >= big) {
                big=dum;
                imax=i;
            }
        }
        //Do we need to interchange rows?
        if (j != imax) {
            //Yes, do so...
            for (k=1;k<=n;k++) {
                dum=A(imax-1,k-1);
            A(imax-1,k-1)=A(j-1,k-1); // Tadej: imax-1,k looks wrong
            A(j-1,k-1)=dum;
            }
            //...and change the parity of d.
            d = -d;
            vv[imax-1]=vv[j-1]; //Also interchange the scale factor.
        }
        indx[j-1]=imax;
        //If the pivot element is zero the matrix is singular (at least to the precision of the
        //algorithm). For some applications on singular matrices, it is desirable to substitute
        //TINY for zero.
        if (A(j-1,j-1) == 0.0) A(j-1,j-1)=1e-20;
         //Now, finally, divide by the pivot element.
        if (j != n) {
            dum=1.0/(A(j-1,j-1));
            for (i=j+1;i<=n;i++) A(i-1,j-1) *= dum;
        }
    } //Go back for the next column in the reduction.
}


| void TNumericalStuff::LUSolve | ( | const TFltVV & | A, | 
| const TIntV & | indx, | ||
| TFltV & | b | ||
| ) |  [static] | 
        
Definition at line 971 of file linalg.cpp.
References Assert, TVVec< TVal >::GetCols(), and TVVec< TVal >::GetRows().
Referenced by SolveLinearSystem().
                                                                          {
  Assert(A.GetRows() == A.GetCols());
  int n = A.GetRows();
    int i,ii=0,ip,j;
    double sum;
    for (i=1;i<=n;i++) {
        ip=indx[i-1];
        sum=b[ip-1];
        b[ip-1]=b[i-1];
        if (ii)
            for (j=ii;j<=i-1;j++) sum -= A(i-1,j-1)*b[j-1];
        else if (sum) ii=i;b[i-1]=sum;
    }
    for (i=n;i>=1;i--) {
        sum=b[i-1];
        for (j=i+1;j<=n;j++) sum -= A(i-1,j-1)*b[j-1];
        b[i-1]=sum/A(i-1,i-1);
    }
}


| void TNumericalStuff::nrerror | ( | const TStr & | error_text | ) |  [static, private] | 
        
Definition at line 652 of file linalg.cpp.
References TStr::CStr().
Referenced by CholeskyDecomposition(), EigSymmetricTridiag(), and LUDecomposition().
                                                    {
    printf("NR_ERROR: %s", error_text.CStr());
    throw new TNSException(error_text);
}


| double TNumericalStuff::pythag | ( | double | a, | 
| double | b | ||
| ) |  [static, private] | 
        
Definition at line 657 of file linalg.cpp.
References sqr().
Referenced by EigSymmetricTridiag().
                                                 {
    double absa = fabs(a), absb = fabs(b);
    if (absa > absb)
        return absa*sqrt(1.0+sqr(absb/absa));
    else
        return (absb == 0.0 ? 0.0 : absb*sqrt(1.0+sqr(absa/absb)));
}


| double TNumericalStuff::sign | ( | double | a, | 
| double | b | ||
| ) |  [static, private] | 
        
Definition at line 648 of file linalg.cpp.
Referenced by EigSymmetricTridiag().
                                               {
  return b >= 0.0 ? fabs(a) : -fabs(a);
}

| void TNumericalStuff::SolveLinearSystem | ( | TFltVV & | A, | 
| const TFltV & | b, | ||
| TFltV & | x | ||
| ) |  [static] | 
        
Definition at line 991 of file linalg.cpp.
References LUDecomposition(), and LUSolve().
                                                                           {
    TIntV indx; double d;
    LUDecomposition(A, indx, d);
    x = b;
    LUSolve(A, indx, x);
}

| void TNumericalStuff::SolveSymetricSystem | ( | TFltVV & | A, | 
| const TFltV & | b, | ||
| TFltV & | x | ||
| ) |  [static] | 
        
Definition at line 834 of file linalg.cpp.
References CholeskyDecomposition(), CholeskySolve(), TVVec< TVal >::GetCols(), TVVec< TVal >::GetRows(), and IAssert.
Referenced by TLogRegFit::GetNewtonStep().
                                                                             {
  IAssert(A.GetRows() == A.GetCols());
  TFltV p; CholeskyDecomposition(A, p);
  CholeskySolve(A, p, b, x);
}


| double TNumericalStuff::sqr | ( | double | a | ) |  [static, private] | 
        
Definition at line 644 of file linalg.cpp.
Referenced by pythag().
                                    {
  return a == 0.0 ? 0.0 : a*a;
}

| void TNumericalStuff::SymetricToTridiag | ( | TFltVV & | a, | 
| int | n, | ||
| TFltV & | d, | ||
| TFltV & | e | ||
| ) |  [static] | 
        
Definition at line 665 of file linalg.cpp.
References Assert, TFlt::GetStr(), and IAssertR.
                                                                            {
    int l,k,j,i;
    double scale,hh,h,g,f;
    for (i=n;i>=2;i--) {
        l=i-1;
        h=scale=0.0;
        if (l > 1) {
            for (k=1;k<=l;k++)
                scale += fabs(a(i-1,k-1).Val);
            if (scale == 0.0) //Skip transformation.
                e[i]=a(i-1,l-1);
            else {
                for (k=1;k<=l;k++) {
                    a(i-1,k-1) /= scale; //Use scaled a's for transformation.
                    h += a(i-1,k-1)*a(i-1,k-1);
                }
                f=a(i-1,l-1);
                g=(f >= 0.0 ? -sqrt(h) : sqrt(h));
                IAssertR(_isnan(g) == 0, TFlt::GetStr(h));
                e[i]=scale*g;
                h -= f*g; //Now h is equation (11.2.4).
                a(i-1,l-1)=f-g; //Store u in the ith row of a.
                f=0.0;
                for (j=1;j<=l;j++) {
                    // Next statement can be omitted if eigenvectors not wanted
                    a(j-1,i-1)=a(i-1,j-1)/h; //Store u=H in ith column of a.
                    g=0.0; //Form an element of A  u in g.
                    for (k=1;k<=j;k++)
                        g += a(j-1,k-1)*a(i-1,k-1);
                    for (k=j+1;k<=l;k++)
                        g += a(k-1,j-1)*a(i-1,k-1);
                    e[j]=g/h; //Form element of p in temporarily unused element of e.
                    f += e[j]*a(i-1,j-1);
                }
                hh=f/(h+h); //Form K, equation (11.2.11).
                for (j=1;j<=l;j++) { //Form q and store in e overwriting p.
                    f=a(i-1,j-1);
                    e[j]=g=e[j]-hh*f;
                    for (k=1;k<=j;k++) { //Reduce a, equation (11.2.13).
                        a(j-1,k-1) -= (f*e[k]+g*a(i-1,k-1));
                        Assert(_isnan(a(j-1,k-1)) == 0);
                    }
                }
            }
        } else
            e[i]=a(i-1,l-1);
        d[i]=h;
    }
    // Next statement can be omitted if eigenvectors not wanted
    d[1]=0.0;
    e[1]=0.0;
    // Contents of this loop can be omitted if eigenvectors not
    // wanted except for statement d[i]=a[i][i];
    for (i=1;i<=n;i++) { //Begin accumulation of transformationmatrices.
        l=i-1;
        if (d[i]) { //This block skipped when i=1.
            for (j=1;j<=l;j++) {
                g=0.0;
                for (k=1;k<=l;k++) //Use u and u=H stored in a to form PQ.
                    g += a(i-1,k-1)*a(k-1,j-1);
                for (k=1;k<=l;k++) {
                    a(k-1,j-1) -= g*a(k-1,i-1);
                    Assert(_isnan(a(k-1,j-1)) == 0);
                }
            }
        }
        d[i]=a(i-1,i-1); //This statement remains.
        a(i-1,i-1)=1.0; //Reset row and column of a to identity  matrix for next iteration.
        for (j=1;j<=l;j++) a(j-1,i-1)=a(i-1,j-1)=0.0;
    }
}
