コード例 #1
0
ファイル: linalg.cs プロジェクト: Kerbas-ad-astra/MechJeb2
        /*************************************************************************
        This function performs in-place conversion to SKS format.

        INPUT PARAMETERS
            S           -   sparse matrix in any format.

        OUTPUT PARAMETERS
            S           -   sparse matrix in SKS format.

        NOTE: this  function  has   no  effect  when  called with matrix which  is
              already in SKS mode.

        NOTE: in-place conversion involves allocation of temporary arrays. If  you
              perform a lot of repeated in- place  conversions,  it  may  lead  to
              memory fragmentation. Consider using out-of-place SparseCopyToSKSBuf()
              function in this case.
            
          -- ALGLIB PROJECT --
             Copyright 15.01.2014 by Bochkanov Sergey
        *************************************************************************/
        public static void sparseconverttosks(sparsematrix s)
        {
            int[] tridx = new int[0];
            int[] tdidx = new int[0];
            int[] tuidx = new int[0];
            double[] tvals = new double[0];
            int n = 0;
            int t0 = 0;
            int t1 = 0;
            int i = 0;
            int j = 0;
            int k = 0;
            double v = 0;

            alglib.ap.assert((s.matrixtype==0 || s.matrixtype==1) || s.matrixtype==2, "SparseConvertToSKS: invalid matrix type");
            alglib.ap.assert(s.m==s.n, "SparseConvertToSKS: rectangular matrices are not supported");
            n = s.n;
            if( s.matrixtype==2 )
            {
                
                //
                // Already in SKS mode
                //
                return;
            }
            
            //
            // Generate internal copy of SKS matrix
            //
            apserv.ivectorsetlengthatleast(ref tdidx, n+1);
            apserv.ivectorsetlengthatleast(ref tuidx, n+1);
            for(i=0; i<=n; i++)
            {
                tdidx[i] = 0;
                tuidx[i] = 0;
            }
            t0 = 0;
            t1 = 0;
            while( sparseenumerate(s, ref t0, ref t1, ref i, ref j, ref v) )
            {
                if( j<i )
                {
                    tdidx[i] = Math.Max(tdidx[i], i-j);
                }
                else
                {
                    tuidx[j] = Math.Max(tuidx[j], j-i);
                }
            }
            apserv.ivectorsetlengthatleast(ref tridx, n+1);
            tridx[0] = 0;
            for(i=1; i<=n; i++)
            {
                tridx[i] = tridx[i-1]+tdidx[i-1]+1+tuidx[i-1];
            }
            apserv.rvectorsetlengthatleast(ref tvals, tridx[n]);
            k = tridx[n];
            for(i=0; i<=k-1; i++)
            {
                tvals[i] = 0.0;
            }
            t0 = 0;
            t1 = 0;
            while( sparseenumerate(s, ref t0, ref t1, ref i, ref j, ref v) )
            {
                if( j<=i )
                {
                    tvals[tridx[i]+tdidx[i]-(i-j)] = v;
                }
                else
                {
                    tvals[tridx[j+1]-(j-i)] = v;
                }
            }
            for(i=0; i<=n-1; i++)
            {
                tdidx[n] = Math.Max(tdidx[n], tdidx[i]);
                tuidx[n] = Math.Max(tuidx[n], tuidx[i]);
            }
            s.matrixtype = 2;
            s.ninitialized = 0;
            s.nfree = 0;
            s.m = n;
            s.n = n;
            alglib.ap.swap(ref s.didx, ref tdidx);
            alglib.ap.swap(ref s.uidx, ref tuidx);
            alglib.ap.swap(ref s.ridx, ref tridx);
            alglib.ap.swap(ref s.vals, ref tvals);
        }
コード例 #2
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function calculates matrix-matrix product  S*A, when S  is  symmetric
            matrix.  Matrix  S  must  be stored  in  CRS  format  (exception  will  be
            thrown otherwise).

            INPUT PARAMETERS
                S           -   sparse M*M matrix in CRS format (you MUST convert  it
                                to CRS before calling this function).
                A           -   array[N][K], input dense matrix. For performance reasons
                                we make only quick checks - we check that array size is
                                at least N, but we do not check for NAN's or INF's.
                K           -   number of columns of matrix (A).  
                B           -   output buffer, possibly preallocated. In case  buffer
                                size is too small to store  result,  this  buffer  is
                                automatically resized.
            
            OUTPUT PARAMETERS
                B           -   array[M][K], S*A
            
            NOTE: this function throws exception when called for non-CRS matrix.  You
            must convert your matrix  with  SparseConvertToCRS()  before  using  this
            function.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparsesmm(sparsematrix s,
                bool isupper,
                double[,] a,
                int k,
                ref double[,] b)
            {
                int i = 0;
                int j = 0;
                int k0 = 0;
                int id = 0;
                int lt = 0;
                int rt = 0;
                double v = 0;
                double vb = 0;
                double va = 0;
                int i_ = 0;

                alglib.ap.assert(s.matrixtype == 1, "SparseSMM: incorrect matrix type (convert your matrix to CRS)");
                alglib.ap.assert(s.ninitialized == s.ridx[s.m], "SparseSMM: some rows/elements of the CRS matrix were not initialized (you must initialize everything you promised to SparseCreateCRS)");
                alglib.ap.assert(alglib.ap.rows(a) >= s.n, "SparseSMM: Rows(X)<N");
                alglib.ap.assert(s.m == s.n, "SparseSMM: matrix is non-square");
                apserv.rmatrixsetlengthatleast(ref b, s.m, k);
                for (i = 0; i <= s.m - 1; i++)
                {
                    for (j = 0; j <= k - 1; j++)
                    {
                        b[i, j] = 0;
                    }
                }
                if (k > linalgswitch)
                {
                    for (i = 0; i <= s.m - 1; i++)
                    {
                        for (j = 0; j <= k - 1; j++)
                        {
                            if (s.didx[i] != s.uidx[i])
                            {
                                id = s.didx[i];
                                b[i, j] = b[i, j] + s.vals[id] * a[s.idx[id], j];
                            }
                            if (isupper)
                            {
                                lt = s.uidx[i];
                                rt = s.ridx[i + 1];
                                vb = 0;
                                va = a[i, j];
                                for (k0 = lt; k0 <= rt - 1; k0++)
                                {
                                    id = s.idx[k0];
                                    v = s.vals[k0];
                                    vb = vb + a[id, j] * v;
                                    b[id, j] = b[id, j] + va * v;
                                }
                                b[i, j] = b[i, j] + vb;
                            }
                            else
                            {
                                lt = s.ridx[i];
                                rt = s.didx[i];
                                vb = 0;
                                va = a[i, j];
                                for (k0 = lt; k0 <= rt - 1; k0++)
                                {
                                    id = s.idx[k0];
                                    v = s.vals[k0];
                                    vb = vb + a[id, j] * v;
                                    b[id, j] = b[id, j] + va * v;
                                }
                                b[i, j] = b[i, j] + vb;
                            }
                        }
                    }
                }
                else
                {
                    for (i = 0; i <= s.m - 1; i++)
                    {
                        if (s.didx[i] != s.uidx[i])
                        {
                            id = s.didx[i];
                            v = s.vals[id];
                            for (i_ = 0; i_ <= k - 1; i_++)
                            {
                                b[i, i_] = b[i, i_] + v * a[s.idx[id], i_];
                            }
                        }
                        if (isupper)
                        {
                            lt = s.uidx[i];
                            rt = s.ridx[i + 1];
                            for (j = lt; j <= rt - 1; j++)
                            {
                                id = s.idx[j];
                                v = s.vals[j];
                                for (i_ = 0; i_ <= k - 1; i_++)
                                {
                                    b[i, i_] = b[i, i_] + v * a[id, i_];
                                }
                                for (i_ = 0; i_ <= k - 1; i_++)
                                {
                                    b[id, i_] = b[id, i_] + v * a[i, i_];
                                }
                            }
                        }
                        else
                        {
                            lt = s.ridx[i];
                            rt = s.didx[i];
                            for (j = lt; j <= rt - 1; j++)
                            {
                                id = s.idx[j];
                                v = s.vals[j];
                                for (i_ = 0; i_ <= k - 1; i_++)
                                {
                                    b[i, i_] = b[i, i_] + v * a[id, i_];
                                }
                                for (i_ = 0; i_ <= k - 1; i_++)
                                {
                                    b[id, i_] = b[id, i_] + v * a[i, i_];
                                }
                            }
                        }
                    }
                }
            }
コード例 #3
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function return average length of chain at hash-table.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static double sparsegetaveragelengthofchain(sparsematrix s)
            {
                double result = 0;
                int nchains = 0;
                int talc = 0;
                int l = 0;
                int i = 0;
                int ind0 = 0;
                int ind1 = 0;
                int hashcode = 0;


                //
                //if matrix represent in CRS then return zero and exit
                //
                if (s.matrixtype == 1)
                {
                    result = 0;
                    return result;
                }
                nchains = 0;
                talc = 0;
                l = alglib.ap.len(s.vals);
                for (i = 0; i <= l - 1; i++)
                {
                    ind0 = 2 * i;
                    if (s.idx[ind0] != -1)
                    {
                        nchains = nchains + 1;
                        hashcode = hash(s.idx[ind0], s.idx[ind0 + 1], l);
                        while (true)
                        {
                            talc = talc + 1;
                            ind1 = 2 * hashcode;
                            if (s.idx[ind0] == s.idx[ind1] && s.idx[ind0 + 1] == s.idx[ind1 + 1])
                            {
                                break;
                            }
                            hashcode = (hashcode + 1) % l;
                        }
                    }
                }
                if (nchains == 0)
                {
                    result = 0;
                }
                else
                {
                    result = (double)talc / (double)nchains;
                }
                return result;
            }
コード例 #4
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function simultaneously calculates two matrix-vector products:
                S*x and S^T*x.
            S must be square (non-rectangular) matrix stored in CRS format (exception  
            will be thrown otherwise).

            INPUT PARAMETERS
                S           -   sparse N*N matrix in CRS format (you MUST convert  it
                                to CRS before calling this function).
                X           -   array[N], input vector. For  performance  reasons  we 
                                make only quick checks - we check that array size  is
                                at least N, but we do not check for NAN's or INF's.
                Y0          -   output buffer, possibly preallocated. In case  buffer
                                size is too small to store  result,  this  buffer  is
                                automatically resized.
                Y1          -   output buffer, possibly preallocated. In case  buffer
                                size is too small to store  result,  this  buffer  is
                                automatically resized.
            
            OUTPUT PARAMETERS
                Y0          -   array[N], S*x
                Y1          -   array[N], S^T*x
            
            NOTE: this function throws exception when called for non-CRS matrix.  You
            must convert your matrix  with  SparseConvertToCRS()  before  using  this
            function. It also throws exception when S is non-square.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparsemv2(sparsematrix s,
                double[] x,
                ref double[] y0,
                ref double[] y1)
            {
                int l = 0;
                double tval = 0;
                int i = 0;
                int j = 0;
                double vx = 0;
                double vs = 0;
                int vi = 0;
                int j0 = 0;
                int j1 = 0;

                alglib.ap.assert(s.matrixtype == 1, "SparseMV2: incorrect matrix type (convert your matrix to CRS)");
                alglib.ap.assert(s.ninitialized == s.ridx[s.m], "SparseMV: some rows/elements of the CRS matrix were not initialized (you must initialize everything you promised to SparseCreateCRS)");
                alglib.ap.assert(s.m == s.n, "SparseMV2: matrix is non-square");
                l = alglib.ap.len(x);
                alglib.ap.assert(l >= s.n, "SparseMV2: Length(X)<N");
                apserv.rvectorsetlengthatleast(ref y0, l);
                apserv.rvectorsetlengthatleast(ref y1, l);
                for (i = 0; i <= s.n - 1; i++)
                {
                    y1[i] = 0;
                }
                for (i = 0; i <= s.m - 1; i++)
                {
                    tval = 0;
                    vx = x[i];
                    j0 = s.ridx[i];
                    j1 = s.ridx[i + 1] - 1;
                    for (j = j0; j <= j1; j++)
                    {
                        vi = s.idx[j];
                        vs = s.vals[j];
                        tval = tval + x[vi] * vs;
                        y1[vi] = y1[vi] + vx * vs;
                    }
                    y0[i] = tval;
                }
            }
コード例 #5
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function calculates matrix-matrix product  S^T*A. Matrix S  must  be
            stored in CRS format (exception will be thrown otherwise).

            INPUT PARAMETERS
                S           -   sparse M*N matrix in CRS format (you MUST convert  it
                                to CRS before calling this function).
                A           -   array[M][K], input dense matrix. For performance reasons
                                we make only quick checks - we check that array size  is
                                at least M, but we do not check for NAN's or INF's.
                K           -   number of columns of matrix (A).                    
                B           -   output buffer, possibly preallocated. In case  buffer
                                size is too small to store  result,  this  buffer  is
                                automatically resized.
            
            OUTPUT PARAMETERS
                B           -   array[N][K], S^T*A
            
            NOTE: this function throws exception when called for non-CRS matrix.  You
            must convert your matrix  with  SparseConvertToCRS()  before  using  this
            function.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparsemtm(sparsematrix s,
                double[,] a,
                int k,
                ref double[,] b)
            {
                int i = 0;
                int j = 0;
                int k0 = 0;
                int lt = 0;
                int rt = 0;
                int ct = 0;
                double v = 0;
                int i_ = 0;

                alglib.ap.assert(s.matrixtype == 1, "SparseMTM: incorrect matrix type (convert your matrix to CRS)");
                alglib.ap.assert(s.ninitialized == s.ridx[s.m], "SparseMTM: some rows/elements of the CRS matrix were not initialized (you must initialize everything you promised to SparseCreateCRS)");
                alglib.ap.assert(alglib.ap.rows(a) >= s.m, "SparseMTM: Rows(A)<M");
                alglib.ap.assert(k > 0, "SparseMTM: K<=0");
                apserv.rmatrixsetlengthatleast(ref b, s.n, k);
                for (i = 0; i <= s.n - 1; i++)
                {
                    for (j = 0; j <= k - 1; j++)
                    {
                        b[i, j] = 0;
                    }
                }
                if (k < linalgswitch)
                {
                    for (i = 0; i <= s.m - 1; i++)
                    {
                        lt = s.ridx[i];
                        rt = s.ridx[i + 1];
                        for (k0 = lt; k0 <= rt - 1; k0++)
                        {
                            v = s.vals[k0];
                            ct = s.idx[k0];
                            for (j = 0; j <= k - 1; j++)
                            {
                                b[ct, j] = b[ct, j] + v * a[i, j];
                            }
                        }
                    }
                }
                else
                {
                    for (i = 0; i <= s.m - 1; i++)
                    {
                        lt = s.ridx[i];
                        rt = s.ridx[i + 1];
                        for (j = lt; j <= rt - 1; j++)
                        {
                            v = s.vals[j];
                            ct = s.idx[j];
                            for (i_ = 0; i_ <= k - 1; i_++)
                            {
                                b[ct, i_] = b[ct, i_] + v * a[i, i_];
                            }
                        }
                    }
                }
            }
コード例 #6
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function returns S[i,j] - element of the sparse matrix.  Matrix  can
            be in any mode (Hash-Table or CRS), but this function is  less  efficient
            for CRS matrices.  Hash-Table  matrices can  find element  in O(1)  time, 
            while  CRS  matrices  need  O(RS) time, where RS is an number of non-zero
            elements in a row.

            INPUT PARAMETERS
                S           -   sparse M*N matrix in Hash-Table representation.
                                Exception will be thrown for CRS matrix.
                I           -   row index of the element to modify, 0<=I<M
                J           -   column index of the element to modify, 0<=J<N

            RESULT
                value of S[I,J] or zero (in case no element with such index is found)

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static double sparseget(sparsematrix s,
                int i,
                int j)
            {
                double result = 0;
                int hashcode = 0;
                int k = 0;
                int k0 = 0;
                int k1 = 0;

                alglib.ap.assert(i >= 0, "SparseGet: I<0");
                alglib.ap.assert(i < s.m, "SparseGet: I>=M");
                alglib.ap.assert(j >= 0, "SparseGet: J<0");
                alglib.ap.assert(j < s.n, "SparseGet: J>=N");
                k = alglib.ap.len(s.vals);
                result = 0;
                if (s.matrixtype == 0)
                {
                    hashcode = hash(i, j, k);
                    while (true)
                    {
                        if (s.idx[2 * hashcode] == -1)
                        {
                            return result;
                        }
                        if (s.idx[2 * hashcode] == i && s.idx[2 * hashcode + 1] == j)
                        {
                            result = s.vals[hashcode];
                            return result;
                        }
                        hashcode = (hashcode + 1) % k;
                    }
                }
                if (s.matrixtype == 1)
                {
                    alglib.ap.assert(s.ninitialized == s.ridx[s.m], "SparseGet: some rows/elements of the CRS matrix were not initialized (you must initialize everything you promised to SparseCreateCRS)");
                    k0 = s.ridx[i];
                    k1 = s.ridx[i + 1] - 1;
                    for (k = k0; k <= k1; k++)
                    {
                        if (s.idx[k] == j)
                        {
                            result = s.vals[k];
                            return result;
                        }
                    }
                    return result;
                }
                return result;
            }
コード例 #7
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function calculates matrix-vector product  S*x.  Matrix  S  must  be
            stored in CRS format (exception will be thrown otherwise).

            INPUT PARAMETERS
                S           -   sparse M*N matrix in CRS format (you MUST convert  it
                                to CRS before calling this function).
                X           -   array[N], input vector. For  performance  reasons  we 
                                make only quick checks - we check that array size  is
                                at least N, but we do not check for NAN's or INF's.
                Y           -   output buffer, possibly preallocated. In case  buffer
                                size is too small to store  result,  this  buffer  is
                                automatically resized.
            
            OUTPUT PARAMETERS
                Y           -   array[M], S*x
            
            NOTE: this function throws exception when called for non-CRS matrix.  You
            must convert your matrix  with  SparseConvertToCRS()  before  using  this
            function.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparsemv(sparsematrix s,
                double[] x,
                ref double[] y)
            {
                double tval = 0;
                int i = 0;
                int j = 0;
                int lt = 0;
                int rt = 0;

                alglib.ap.assert(s.matrixtype == 1, "SparseMV: incorrect matrix type (convert your matrix to CRS)");
                alglib.ap.assert(s.ninitialized == s.ridx[s.m], "SparseMV: some rows/elements of the CRS matrix were not initialized (you must initialize everything you promised to SparseCreateCRS)");
                alglib.ap.assert(alglib.ap.len(x) >= s.n, "SparseMV: length(X)<N");
                apserv.rvectorsetlengthatleast(ref y, s.m);
                for (i = 0; i <= s.m - 1; i++)
                {
                    tval = 0;
                    lt = s.ridx[i];
                    rt = s.ridx[i + 1];
                    for (j = lt; j <= rt - 1; j++)
                    {
                        tval = tval + x[s.idx[j]] * s.vals[j];
                    }
                    y[i] = tval;
                }
            }
コード例 #8
0
ファイル: linalg.cs プロジェクト: Kerbas-ad-astra/MechJeb2
        /*************************************************************************
        The function returns number of rows of a sparse matrix.

        RESULT: number of rows of a sparse matrix.
            
          -- ALGLIB PROJECT --
             Copyright 23.08.2012 by Bochkanov Sergey
        *************************************************************************/
        public static int sparsegetnrows(sparsematrix s)
        {
            int result = 0;

            result = s.m;
            return result;
        }
コード例 #9
0
ファイル: linalg.cs プロジェクト: Kerbas-ad-astra/MechJeb2
        /*************************************************************************
        The function returns number of columns of a sparse matrix.

        RESULT: number of columns of a sparse matrix.
            
          -- ALGLIB PROJECT --
             Copyright 23.08.2012 by Bochkanov Sergey
        *************************************************************************/
        public static int sparsegetncols(sparsematrix s)
        {
            int result = 0;

            result = s.n;
            return result;
        }
コード例 #10
0
ファイル: linalg.cs プロジェクト: Kerbas-ad-astra/MechJeb2
        /*************************************************************************
        This function checks matrix storage format and returns True when matrix is
        stored using SKS representation.

        INPUT PARAMETERS:
            S   -   sparse matrix.

        RESULT:
            True if matrix type is SKS
            False if matrix type is not SKS
            
          -- ALGLIB PROJECT --
             Copyright 20.07.2012 by Bochkanov Sergey
        *************************************************************************/
        public static bool sparseissks(sparsematrix s)
        {
            bool result = new bool();

            alglib.ap.assert((s.matrixtype==0 || s.matrixtype==1) || s.matrixtype==2, "SparseIsSKS: invalid matrix type");
            result = s.matrixtype==2;
            return result;
        }
コード例 #11
0
ファイル: linalg.cs プロジェクト: Kerbas-ad-astra/MechJeb2
        /*************************************************************************
        The function frees all memory occupied by  sparse  matrix.  Sparse  matrix
        structure becomes unusable after this call.

        OUTPUT PARAMETERS
            S   -   sparse matrix to delete
            
          -- ALGLIB PROJECT --
             Copyright 24.07.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void sparsefree(sparsematrix s)
        {
            s.matrixtype = -1;
            s.m = 0;
            s.n = 0;
            s.nfree = 0;
            s.ninitialized = 0;
            s.tablesize = 0;
        }
コード例 #12
0
ファイル: linalg.cs プロジェクト: Kerbas-ad-astra/MechJeb2
        /*************************************************************************
        This function returns type of the matrix storage format.

        INPUT PARAMETERS:
            S           -   sparse matrix.

        RESULT:
            sparse storage format used by matrix:
                0   -   Hash-table
                1   -   CRS (compressed row storage)
                2   -   SKS (skyline)

        NOTE: future  versions  of  ALGLIB  may  include additional sparse storage
              formats.

            
          -- ALGLIB PROJECT --
             Copyright 20.07.2012 by Bochkanov Sergey
        *************************************************************************/
        public static int sparsegetmatrixtype(sparsematrix s)
        {
            int result = 0;

            alglib.ap.assert((s.matrixtype==0 || s.matrixtype==1) || s.matrixtype==2, "SparseGetMatrixType: invalid matrix type");
            result = s.matrixtype;
            return result;
        }
コード例 #13
0
ファイル: linalg.cs プロジェクト: Kerbas-ad-astra/MechJeb2
        /*************************************************************************
        This  function  performs  out-of-place  conversion  to SKS format.  S0  is
        copied to S1 and converted on-the-fly. Memory  allocated  in S1 is  reused
        to maximum extent possible.

        INPUT PARAMETERS
            S0          -   sparse matrix in any format.

        OUTPUT PARAMETERS
            S1          -   sparse matrix in SKS format.

        NOTE: if S0 is stored as SKS, it is just copied without conversion.

          -- ALGLIB PROJECT --
             Copyright 20.07.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void sparsecopytosksbuf(sparsematrix s0,
            sparsematrix s1)
        {
            double v = 0;
            int n = 0;
            int t0 = 0;
            int t1 = 0;
            int i = 0;
            int j = 0;
            int k = 0;

            alglib.ap.assert((s0.matrixtype==0 || s0.matrixtype==1) || s0.matrixtype==2, "SparseCopyToSKSBuf: invalid matrix type");
            alglib.ap.assert(s0.m==s0.n, "SparseCopyToSKSBuf: rectangular matrices are not supported");
            n = s0.n;
            if( s0.matrixtype==2 )
            {
                
                //
                // Already SKS, just copy
                //
                sparsecopybuf(s0, s1);
                return;
            }
            
            //
            // Generate copy of matrix in the SKS format
            //
            apserv.ivectorsetlengthatleast(ref s1.didx, n+1);
            apserv.ivectorsetlengthatleast(ref s1.uidx, n+1);
            for(i=0; i<=n; i++)
            {
                s1.didx[i] = 0;
                s1.uidx[i] = 0;
            }
            t0 = 0;
            t1 = 0;
            while( sparseenumerate(s0, ref t0, ref t1, ref i, ref j, ref v) )
            {
                if( j<i )
                {
                    s1.didx[i] = Math.Max(s1.didx[i], i-j);
                }
                else
                {
                    s1.uidx[j] = Math.Max(s1.uidx[j], j-i);
                }
            }
            apserv.ivectorsetlengthatleast(ref s1.ridx, n+1);
            s1.ridx[0] = 0;
            for(i=1; i<=n; i++)
            {
                s1.ridx[i] = s1.ridx[i-1]+s1.didx[i-1]+1+s1.uidx[i-1];
            }
            apserv.rvectorsetlengthatleast(ref s1.vals, s1.ridx[n]);
            k = s1.ridx[n];
            for(i=0; i<=k-1; i++)
            {
                s1.vals[i] = 0.0;
            }
            t0 = 0;
            t1 = 0;
            while( sparseenumerate(s0, ref t0, ref t1, ref i, ref j, ref v) )
            {
                if( j<=i )
                {
                    s1.vals[s1.ridx[i]+s1.didx[i]-(i-j)] = v;
                }
                else
                {
                    s1.vals[s1.ridx[j+1]-(j-i)] = v;
                }
            }
            for(i=0; i<=n-1; i++)
            {
                s1.didx[n] = Math.Max(s1.didx[n], s1.didx[i]);
                s1.uidx[n] = Math.Max(s1.uidx[n], s1.uidx[i]);
            }
            s1.matrixtype = 2;
            s1.ninitialized = 0;
            s1.nfree = 0;
            s1.m = n;
            s1.n = n;
        }
コード例 #14
0
ファイル: linalg.cs プロジェクト: Kerbas-ad-astra/MechJeb2
        /*************************************************************************
        This  function  performs  out-of-place  conversion  to SKS storage format.
        S0 is copied to S1 and converted on-the-fly.

        INPUT PARAMETERS
            S0          -   sparse matrix in any format.

        OUTPUT PARAMETERS
            S1          -   sparse matrix in SKS format.

        NOTE: if S0 is stored as SKS, it is just copied without conversion.

        NOTE: this function de-allocates memory  occupied  by  S1 before  starting
              conversion. If you perform a  lot  of  repeated  conversions, it may
              lead to memory fragmentation. In this case we recommend you  to  use
              SparseCopyToSKSBuf() function which re-uses memory in S1 as much  as
              possible.

          -- ALGLIB PROJECT --
             Copyright 20.07.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void sparsecopytosks(sparsematrix s0,
            sparsematrix s1)
        {
            alglib.ap.assert((s0.matrixtype==0 || s0.matrixtype==1) || s0.matrixtype==2, "SparseCopyToSKS: invalid matrix type");
            sparsecopytosksbuf(s0, s1);
        }
コード例 #15
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function adds value to S[i,j] - element of the sparse matrix. Matrix
            must be in a Hash-Table mode.

            In case S[i,j] already exists in the table, V i added to  its  value.  In
            case  S[i,j]  is  non-existent,  it  is  inserted  in  the  table.  Table
            automatically grows when necessary.

            INPUT PARAMETERS
                S           -   sparse M*N matrix in Hash-Table representation.
                                Exception will be thrown for CRS matrix.
                I           -   row index of the element to modify, 0<=I<M
                J           -   column index of the element to modify, 0<=J<N
                V           -   value to add, must be finite number

            OUTPUT PARAMETERS
                S           -   modified matrix
            
            NOTE 1:  when  S[i,j]  is exactly zero after modification, it is  deleted
            from the table.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparseadd(sparsematrix s,
                int i,
                int j,
                double v)
            {
                int hashcode = 0;
                int tcode = 0;
                int k = 0;

                alglib.ap.assert(s.matrixtype == 0, "SparseAdd: matrix must be in the Hash-Table mode to do this operation");
                alglib.ap.assert(i >= 0, "SparseAdd: I<0");
                alglib.ap.assert(i < s.m, "SparseAdd: I>=M");
                alglib.ap.assert(j >= 0, "SparseAdd: J<0");
                alglib.ap.assert(j < s.n, "SparseAdd: J>=N");
                alglib.ap.assert(math.isfinite(v), "SparseAdd: V is not finite number");
                if ((double)(v) == (double)(0))
                {
                    return;
                }
                tcode = -1;
                k = alglib.ap.len(s.vals);
                if ((double)((1 - maxloadfactor) * k) >= (double)(s.nfree))
                {
                    sparseresizematrix(s);
                    k = alglib.ap.len(s.vals);
                }
                hashcode = hash(i, j, k);
                while (true)
                {
                    if (s.idx[2 * hashcode] == -1)
                    {
                        if (tcode != -1)
                        {
                            hashcode = tcode;
                        }
                        s.vals[hashcode] = v;
                        s.idx[2 * hashcode] = i;
                        s.idx[2 * hashcode + 1] = j;
                        if (tcode == -1)
                        {
                            s.nfree = s.nfree - 1;
                        }
                        return;
                    }
                    else
                    {
                        if (s.idx[2 * hashcode] == i && s.idx[2 * hashcode + 1] == j)
                        {
                            s.vals[hashcode] = s.vals[hashcode] + v;
                            if ((double)(s.vals[hashcode]) == (double)(0))
                            {
                                s.idx[2 * hashcode] = -2;
                            }
                            return;
                        }

                        //
                        //is it deleted element?
                        //
                        if (tcode == -1 && s.idx[2 * hashcode] == -2)
                        {
                            tcode = hashcode;
                        }

                        //
                        //next step
                        //
                        hashcode = (hashcode + 1) % k;
                    }
                }
            }
コード例 #16
0
ファイル: linalg.cs プロジェクト: Kerbas-ad-astra/MechJeb2
        /*************************************************************************
        The function returns number of strictly lower triangular non-zero elements
        in  the  matrix.  It  counts  SYMBOLICALLY non-zero elements, i.e. entries
        in the sparse matrix data structure. If some element  has  zero  numerical
        value, it is still counted.

        This function has different cost for different types of matrices:
        * for hash-based matrices it involves complete pass over entire hash-table
          with O(NNZ) cost, where NNZ is number of non-zero elements
        * for CRS and SKS matrix types cost of counting is O(N) (N - matrix size).

        RESULT: number of non-zero elements strictly below main diagonal
            
          -- ALGLIB PROJECT --
             Copyright 12.02.2014 by Bochkanov Sergey
        *************************************************************************/
        public static int sparsegetlowercount(sparsematrix s)
        {
            int result = 0;
            int sz = 0;
            int i0 = 0;
            int i = 0;

            result = -1;
            if( s.matrixtype==0 )
            {
                
                //
                // Hash-table matrix
                //
                result = 0;
                sz = s.tablesize;
                for(i0=0; i0<=sz-1; i0++)
                {
                    i = s.idx[2*i0];
                    if( i>=0 && s.idx[2*i0+1]<i )
                    {
                        result = result+1;
                    }
                }
                return result;
            }
            if( s.matrixtype==1 )
            {
                
                //
                // CRS matrix
                //
                alglib.ap.assert(s.ninitialized==s.ridx[s.m], "SparseGetUpperCount: some rows/elements of the CRS matrix were not initialized (you must initialize everything you promised to SparseCreateCRS)");
                result = 0;
                sz = s.m;
                for(i=0; i<=sz-1; i++)
                {
                    result = result+(s.didx[i]-s.ridx[i]);
                }
                return result;
            }
            if( s.matrixtype==2 )
            {
                
                //
                // SKS matrix
                //
                alglib.ap.assert(s.m==s.n, "SparseGetUpperCount: non-square SKS matrices are not supported");
                result = 0;
                sz = s.m;
                for(i=0; i<=sz-1; i++)
                {
                    result = result+s.didx[i];
                }
                return result;
            }
            alglib.ap.assert(false, "SparseGetUpperCount: internal error");
            return result;
        }
コード例 #17
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function modifies S[i,j] - element of the sparse matrix. Matrix must
            be in a Hash-Table mode.

            In  case  new  value  of S[i,j] is zero, this element is deleted from the 
            table.

            INPUT PARAMETERS
                S           -   sparse M*N matrix in Hash-Table representation.
                                Exception will be thrown for CRS matrix.
                I           -   row index of the element to modify, 0<=I<M
                J           -   column index of the element to modify, 0<=J<N
                V           -   value to set, must be finite number, can be zero

            OUTPUT PARAMETERS
                S           -   modified matrix
            
            NOTE:  this  function  has  no  effect  when  called with zero V for non-
            existent element.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparseset(sparsematrix s,
                int i,
                int j,
                double v)
            {
                int hashcode = 0;
                int tcode = 0;
                int k = 0;

                alglib.ap.assert(i >= 0, "SparseSet: I<0");
                alglib.ap.assert(i < s.m, "SparseSet: I>=M");
                alglib.ap.assert(j >= 0, "SparseSet: J<0");
                alglib.ap.assert(j < s.n, "SparseSet: J>=N");
                alglib.ap.assert(math.isfinite(v), "SparseSet: V is not finite number");

                //
                // Hash-table matrix
                //
                if (s.matrixtype == 0)
                {
                    tcode = -1;
                    k = alglib.ap.len(s.vals);
                    if ((double)((1 - maxloadfactor) * k) >= (double)(s.nfree))
                    {
                        sparseresizematrix(s);
                        k = alglib.ap.len(s.vals);
                    }
                    hashcode = hash(i, j, k);
                    while (true)
                    {
                        if (s.idx[2 * hashcode] == -1)
                        {
                            if ((double)(v) != (double)(0))
                            {
                                if (tcode != -1)
                                {
                                    hashcode = tcode;
                                }
                                s.vals[hashcode] = v;
                                s.idx[2 * hashcode] = i;
                                s.idx[2 * hashcode + 1] = j;
                                if (tcode == -1)
                                {
                                    s.nfree = s.nfree - 1;
                                }
                            }
                            return;
                        }
                        else
                        {
                            if (s.idx[2 * hashcode] == i && s.idx[2 * hashcode + 1] == j)
                            {
                                if ((double)(v) == (double)(0))
                                {
                                    s.idx[2 * hashcode] = -2;
                                }
                                else
                                {
                                    s.vals[hashcode] = v;
                                }
                                return;
                            }
                            if (tcode == -1 && s.idx[2 * hashcode] == -2)
                            {
                                tcode = hashcode;
                            }

                            //
                            // next step
                            //
                            hashcode = (hashcode + 1) % k;
                        }
                    }
                }

                //
                // CRS matrix
                //
                if (s.matrixtype == 1)
                {
                    alglib.ap.assert((double)(v) != (double)(0), "SparseSet: CRS format does not allow you to write zero elements");
                    alglib.ap.assert(s.ridx[i] <= s.ninitialized, "SparseSet: too few initialized elements at some row (you have promised more when called SparceCreateCRS)");
                    alglib.ap.assert(s.ridx[i + 1] > s.ninitialized, "SparseSet: too many initialized elements at some row (you have promised less when called SparceCreateCRS)");
                    alglib.ap.assert(s.ninitialized == s.ridx[i] || s.idx[s.ninitialized - 1] < j, "SparseSet: incorrect column order (you must fill every row from left to right)");
                    s.vals[s.ninitialized] = v;
                    s.idx[s.ninitialized] = j;
                    s.ninitialized = s.ninitialized + 1;

                    //
                    //if matrix has been created then
                    //initiale 'S.UIdx' and 'S.DIdx'
                    //
                    if (s.ninitialized == s.ridx[s.m])
                    {
                        sparseinitduidx(s);
                    }
                }
            }
コード例 #18
0
ファイル: linalg.cs プロジェクト: Kerbas-ad-astra/MechJeb2
        /*************************************************************************
        Procedure for initialization 'S.DIdx' and 'S.UIdx'


          -- ALGLIB PROJECT --
             Copyright 14.10.2011 by Bochkanov Sergey
        *************************************************************************/
        private static void sparseinitduidx(sparsematrix s)
        {
            int i = 0;
            int j = 0;
            int lt = 0;
            int rt = 0;

            alglib.ap.assert(s.matrixtype==1, "SparseInitDUIdx: internal error, incorrect matrix type");
            apserv.ivectorsetlengthatleast(ref s.didx, s.m);
            apserv.ivectorsetlengthatleast(ref s.uidx, s.m);
            for(i=0; i<=s.m-1; i++)
            {
                s.uidx[i] = -1;
                s.didx[i] = -1;
                lt = s.ridx[i];
                rt = s.ridx[i+1];
                for(j=lt; j<=rt-1; j++)
                {
                    if( i<s.idx[j] && s.uidx[i]==-1 )
                    {
                        s.uidx[i] = j;
                        break;
                    }
                    else
                    {
                        if( i==s.idx[j] )
                        {
                            s.didx[i] = j;
                        }
                    }
                }
                if( s.uidx[i]==-1 )
                {
                    s.uidx[i] = s.ridx[i+1];
                }
                if( s.didx[i]==-1 )
                {
                    s.didx[i] = s.uidx[i];
                }
            }
        }
コード例 #19
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function converts matrix to CRS format.

            Some  algorithms  (linear  algebra ones, for example) require matrices in
            CRS format.

            INPUT PARAMETERS
                S           -   sparse M*N matrix.

            OUTPUT PARAMETERS
                S           -   matrix in CRS format
            
            NOTE:  this  function  has  no  effect  when  called with matrix which is 
            already in CRS mode.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparseconverttocrs(sparsematrix s)
            {
                int i = 0;
                double[] tvals = new double[0];
                int[] tidx = new int[0];
                int[] temp = new int[0];
                int nonne = 0;
                int k = 0;

                alglib.ap.assert(s.matrixtype == 0 || s.matrixtype == 1, "SparseConvertToCRS: invalid matrix type");
                if (s.matrixtype == 1)
                {
                    return;
                }
                s.matrixtype = 1;
                nonne = 0;
                k = alglib.ap.len(s.vals);
                alglib.ap.swap(ref s.vals, ref tvals);
                alglib.ap.swap(ref s.idx, ref tidx);
                s.ridx = new int[s.m + 1];
                for (i = 0; i <= s.m; i++)
                {
                    s.ridx[i] = 0;
                }
                temp = new int[s.m];
                for (i = 0; i <= s.m - 1; i++)
                {
                    temp[i] = 0;
                }

                //
                // Number of elements per row
                //
                for (i = 0; i <= k - 1; i++)
                {
                    if (tidx[2 * i] >= 0)
                    {
                        s.ridx[tidx[2 * i] + 1] = s.ridx[tidx[2 * i] + 1] + 1;
                        nonne = nonne + 1;
                    }
                }

                //
                // Fill RIdx (offsets of rows)
                //
                for (i = 0; i <= s.m - 1; i++)
                {
                    s.ridx[i + 1] = s.ridx[i + 1] + s.ridx[i];
                }

                //
                // Allocate memory
                //
                s.vals = new double[nonne];
                s.idx = new int[nonne];
                for (i = 0; i <= k - 1; i++)
                {
                    if (tidx[2 * i] >= 0)
                    {
                        s.vals[s.ridx[tidx[2 * i]] + temp[tidx[2 * i]]] = tvals[i];
                        s.idx[s.ridx[tidx[2 * i]] + temp[tidx[2 * i]]] = tidx[2 * i + 1];
                        temp[tidx[2 * i]] = temp[tidx[2 * i]] + 1;
                    }
                }

                //
                // Set NInitialized
                //
                s.ninitialized = s.ridx[s.m];

                //
                //sorting of elements
                //
                for (i = 0; i <= s.m - 1; i++)
                {
                    tsort.tagsortmiddleir(ref s.idx, ref s.vals, s.ridx[i], s.ridx[i + 1] - s.ridx[i]);
                }

                //
                //initialization 'S.UIdx' and 'S.DIdx'
                //
                sparseinitduidx(s);
            }
コード例 #20
0
        /*************************************************************************
        This  function  is  used  to enumerate all elements of the sparse matrix.
        Before  first  call  user  initializes  T0 and T1 counters by zero. These
        counters are used to remember current position in a  matrix;  after  each
        call they are updated by the function.

        Subsequent calls to this function return non-zero elements of the  sparse
        matrix, one by one. If you enumerate CRS matrix, matrix is traversed from
        left to right, from top to bottom. In case you enumerate matrix stored as
        Hash table, elements are returned in random order.

        EXAMPLE
            > T0=0
            > T1=0
            > while SparseEnumerate(S,T0,T1,I,J,V) do
            >     ....do something with I,J,V

        INPUT PARAMETERS
            S           -   sparse M*N matrix in Hash-Table or CRS representation.
            T0          -   internal counter
            T1          -   internal counter
            
        OUTPUT PARAMETERS
            T0          -   new value of the internal counter
            T1          -   new value of the internal counter
            I           -   row index of non-zero element, 0<=I<M.
            J           -   column index of non-zero element, 0<=J<N
            V           -   value of the T-th element
            
        RESULT
            True in case of success (next non-zero element was retrieved)
            False in case all non-zero elements were enumerated

          -- ALGLIB PROJECT --
             Copyright 14.03.2012 by Bochkanov Sergey
        *************************************************************************/
        public static bool sparseenumerate(sparsematrix s,
            ref int t0,
            ref int t1,
            ref int i,
            ref int j,
            ref double v)
        {
            bool result = new bool();
            int counter = 0;
            int sz = 0;
            int i0 = 0;

            i = 0;
            j = 0;
            v = 0;

            if( t0<0 || (s.matrixtype==1 && t1<0) )
            {
                result = false;
                return result;
            }
            
            //
            // Hash-table matrix
            //
            if( s.matrixtype==0 )
            {
                sz = alglib.ap.len(s.vals);
                for(i0=t0; i0<=sz-1; i0++)
                {
                    if( s.idx[2*i0]==-1 || s.idx[2*i0]==-2 )
                    {
                        continue;
                    }
                    else
                    {
                        i = s.idx[2*i0];
                        j = s.idx[2*i0+1];
                        v = s.vals[i0];
                        t0 = i0+1;
                        result = true;
                        return result;
                    }
                }
                t0 = 0;
                result = false;
                return result;
            }
            
            //
            // CRS matrix
            //
            if( s.matrixtype==1 && t0<s.ninitialized )
            {
                alglib.ap.assert(s.ninitialized==s.ridx[s.m], "SparseEnumerate: some rows/elements of the CRS matrix were not initialized (you must initialize everything you promised to SparseCreateCRS)");
                while( t0>s.ridx[t1+1]-1 && t1<s.m )
                {
                    t1 = t1+1;
                }
                i = t1;
                j = s.idx[t0];
                v = s.vals[t0];
                t0 = t0+1;
                result = true;
                return result;
            }
            t0 = 0;
            t1 = 0;
            result = false;
            return result;
        }
コード例 #21
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function calculates matrix-vector product  S^T*x. Matrix S  must  be
            stored in CRS format (exception will be thrown otherwise).

            INPUT PARAMETERS
                S           -   sparse M*N matrix in CRS format (you MUST convert  it
                                to CRS before calling this function).
                X           -   array[M], input vector. For  performance  reasons  we 
                                make only quick checks - we check that array size  is
                                at least M, but we do not check for NAN's or INF's.
                Y           -   output buffer, possibly preallocated. In case  buffer
                                size is too small to store  result,  this  buffer  is
                                automatically resized.
            
            OUTPUT PARAMETERS
                Y           -   array[N], S^T*x
            
            NOTE: this function throws exception when called for non-CRS matrix.  You
            must convert your matrix  with  SparseConvertToCRS()  before  using  this
            function.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparsemtv(sparsematrix s,
                double[] x,
                ref double[] y)
            {
                int i = 0;
                int j = 0;
                int lt = 0;
                int rt = 0;
                int ct = 0;
                double v = 0;

                alglib.ap.assert(s.matrixtype == 1, "SparseMTV: incorrect matrix type (convert your matrix to CRS)");
                alglib.ap.assert(s.ninitialized == s.ridx[s.m], "SparseMTV: some rows/elements of the CRS matrix were not initialized (you must initialize everything you promised to SparseCreateCRS)");
                alglib.ap.assert(alglib.ap.len(x) >= s.m, "SparseMTV: Length(X)<M");
                apserv.rvectorsetlengthatleast(ref y, s.n);
                for (i = 0; i <= s.n - 1; i++)
                {
                    y[i] = 0;
                }
                for (i = 0; i <= s.m - 1; i++)
                {
                    lt = s.ridx[i];
                    rt = s.ridx[i + 1];
                    v = x[i];
                    for (j = lt; j <= rt - 1; j++)
                    {
                        ct = s.idx[j];
                        y[ct] = y[ct] + v * s.vals[j];
                    }
                }
            }
コード例 #22
0
        /*************************************************************************
        This function rewrites existing (non-zero) element. It  returns  True   if
        element  exists  or  False,  when  it  is  called for non-existing  (zero)
        element.

        The purpose of this function is to provide convenient thread-safe  way  to
        modify  sparse  matrix.  Such  modification  (already  existing element is
        rewritten) is guaranteed to be thread-safe without any synchronization, as
        long as different threads modify different elements.

        INPUT PARAMETERS
            S           -   sparse M*N matrix in Hash-Table or CRS representation.
            I           -   row index of non-zero element to modify, 0<=I<M
            J           -   column index of non-zero element to modify, 0<=J<N
            V           -   value to rewrite, must be finite number

        OUTPUT PARAMETERS
            S           -   modified matrix

          -- ALGLIB PROJECT --
             Copyright 14.03.2012 by Bochkanov Sergey
        *************************************************************************/
        public static bool sparserewriteexisting(sparsematrix s,
            int i,
            int j,
            double v)
        {
            bool result = new bool();
            int hashcode = 0;
            int k = 0;
            int k0 = 0;
            int k1 = 0;

            alglib.ap.assert(0<=i && i<s.m, "SparseRewriteExisting: invalid argument I(either I<0 or I>=S.M)");
            alglib.ap.assert(0<=j && j<s.n, "SparseRewriteExisting: invalid argument J(either J<0 or J>=S.N)");
            alglib.ap.assert(math.isfinite(v), "SparseRewriteExisting: invalid argument V(either V is infinite or V is NaN)");
            result = false;
            
            //
            // Hash-table matrix
            //
            if( s.matrixtype==0 )
            {
                k = alglib.ap.len(s.vals);
                hashcode = hash(i, j, k);
                while( true )
                {
                    if( s.idx[2*hashcode]==-1 )
                    {
                        return result;
                    }
                    if( s.idx[2*hashcode]==i && s.idx[2*hashcode+1]==j )
                    {
                        s.vals[hashcode] = v;
                        result = true;
                        return result;
                    }
                    hashcode = (hashcode+1)%k;
                }
            }
            
            //
            // CRS matrix
            //
            if( s.matrixtype==1 )
            {
                alglib.ap.assert(s.ninitialized==s.ridx[s.m], "SparseRewriteExisting: some rows/elements of the CRS matrix were not initialized (you must initialize everything you promised to SparseCreateCRS)");
                k0 = s.ridx[i];
                k1 = s.ridx[i+1]-1;
                for(k=k0; k<=k1; k++)
                {
                    if( s.idx[k]==j )
                    {
                        s.vals[k] = v;
                        result = true;
                        return result;
                    }
                }
                return result;
            }
            return result;
        }
コード例 #23
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function calculates matrix-vector product  S*x, when S is  symmetric
            matrix.  Matrix  S  must  be stored in  CRS  format  (exception  will  be
            thrown otherwise).

            INPUT PARAMETERS
                S           -   sparse M*M matrix in CRS format (you MUST convert  it
                                to CRS before calling this function).
                X           -   array[N], input vector. For  performance  reasons  we 
                                make only quick checks - we check that array size  is
                                at least N, but we do not check for NAN's or INF's.
                Y           -   output buffer, possibly preallocated. In case  buffer
                                size is too small to store  result,  this  buffer  is
                                automatically resized.
            
            OUTPUT PARAMETERS
                Y           -   array[M], S*x
            
            NOTE: this function throws exception when called for non-CRS matrix.  You
            must convert your matrix  with  SparseConvertToCRS()  before  using  this
            function.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparsesmv(sparsematrix s,
                bool isupper,
                double[] x,
                ref double[] y)
            {
                int i = 0;
                int j = 0;
                int id = 0;
                int lt = 0;
                int rt = 0;
                double v = 0;
                double vy = 0;
                double vx = 0;

                alglib.ap.assert(s.matrixtype == 1, "SparseSMV: incorrect matrix type (convert your matrix to CRS)");
                alglib.ap.assert(s.ninitialized == s.ridx[s.m], "SparseSMV: some rows/elements of the CRS matrix were not initialized (you must initialize everything you promised to SparseCreateCRS)");
                alglib.ap.assert(alglib.ap.len(x) >= s.n, "SparseSMV: length(X)<N");
                alglib.ap.assert(s.m == s.n, "SparseSMV: non-square matrix");
                apserv.rvectorsetlengthatleast(ref y, s.m);
                for (i = 0; i <= s.m - 1; i++)
                {
                    y[i] = 0;
                }
                for (i = 0; i <= s.m - 1; i++)
                {
                    if (s.didx[i] != s.uidx[i])
                    {
                        y[i] = y[i] + s.vals[s.didx[i]] * x[s.idx[s.didx[i]]];
                    }
                    if (isupper)
                    {
                        lt = s.uidx[i];
                        rt = s.ridx[i + 1];
                        vy = 0;
                        vx = x[i];
                        for (j = lt; j <= rt - 1; j++)
                        {
                            id = s.idx[j];
                            v = s.vals[j];
                            vy = vy + x[id] * v;
                            y[id] = y[id] + vx * v;
                        }
                        y[i] = y[i] + vy;
                    }
                    else
                    {
                        lt = s.ridx[i];
                        rt = s.didx[i];
                        vy = 0;
                        vx = x[i];
                        for (j = lt; j <= rt - 1; j++)
                        {
                            id = s.idx[j];
                            v = s.vals[j];
                            vy = vy + x[id] * v;
                            y[id] = y[id] + vx * v;
                        }
                        y[i] = y[i] + vy;
                    }
                }
            }
コード例 #24
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function creates sparse matrix in a Hash-Table format.

            This function creates Hast-Table matrix, which can be  converted  to  CRS
            format after its initialization is over. Typical  usage  scenario  for  a
            sparse matrix is:
            1. creation in a Hash-Table format
            2. insertion of the matrix elements
            3. conversion to the CRS representation
            4. matrix is passed to some linear algebra algorithm

            Some  information  about  different matrix formats can be found below, in
            the "NOTES" section.

            INPUT PARAMETERS
                M           -   number of rows in a matrix, M>=1
                N           -   number of columns in a matrix, N>=1
                K           -   K>=0, expected number of non-zero elements in a matrix.
                                K can be inexact approximation, can be less than actual
                                number  of  elements  (table will grow when needed) or 
                                even zero).
                                It is important to understand that although hash-table
                                may grow automatically, it is better to  provide  good
                                estimate of data size.

            OUTPUT PARAMETERS
                S           -   sparse M*N matrix in Hash-Table representation.
                                All elements of the matrix are zero.

            NOTE 1.

            Sparse matrices can be stored using either Hash-Table  representation  or
            Compressed  Row  Storage  representation. Hast-table is better suited for
            querying   and   dynamic   operations   (thus,  it  is  used  for  matrix
            initialization), but it is inefficient when you want to make some  linear 
            algebra operations.

            From the other side, CRS is better suited for linear algebra  operations,
            but initialization is less convenient - you have to tell row sizes at the
            initialization,  and  you  can  fill matrix only row by row, from left to 
            right. CRS is also very inefficient when you want to find matrix  element 
            by its index.

            Thus,  Hash-Table  representation   does   not   support  linear  algebra
            operations, while CRS format does not support modification of the  table.
            Tables below outline information about these two formats:

                OPERATIONS WITH MATRIX      HASH        CRS
                create                      +           +
                read element                +           +
                modify element              +           
                add value to element        +
                A*x  (dense vector)                     +
                A'*x (dense vector)                     +
                A*X  (dense matrix)                     +
                A'*X (dense matrix)                     +

            NOTE 2.

            Hash-tables use memory inefficiently, and they have to keep  some  amount
            of the "spare memory" in order to have good performance. Hash  table  for
            matrix with K non-zero elements will  need  C*K*(8+2*sizeof(int))  bytes,
            where C is a small constant, about 1.5-2 in magnitude.

            CRS storage, from the other side, is  more  memory-efficient,  and  needs
            just K*(8+sizeof(int))+M*sizeof(int) bytes, where M is a number  of  rows
            in a matrix.

            When you convert from the Hash-Table to CRS  representation, all unneeded
            memory will be freed.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparsecreate(int m,
                int n,
                int k,
                sparsematrix s)
            {
                int i = 0;
                int sz = 0;

                alglib.ap.assert(m > 0, "SparseCreate: M<=0");
                alglib.ap.assert(n > 0, "SparseCreate: N<=0");
                alglib.ap.assert(k >= 0, "SparseCreate: K<0");
                sz = (int)Math.Round(k / desiredloadfactor + additional);
                s.matrixtype = 0;
                s.m = m;
                s.n = n;
                s.nfree = sz;
                s.vals = new double[sz];
                s.idx = new int[2 * sz];
                for (i = 0; i <= sz - 1; i++)
                {
                    s.idx[2 * i] = -1;
                }
            }
コード例 #25
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function simultaneously calculates two matrix-matrix products:
                S*A and S^T*A.
            S must be square (non-rectangular) matrix stored in CRS format (exception  
            will be thrown otherwise).

            INPUT PARAMETERS
                S           -   sparse N*N matrix in CRS format (you MUST convert  it
                                to CRS before calling this function).
                A           -   array[N][K], input dense matrix. For performance reasons
                                we make only quick checks - we check that array size  is
                                at least N, but we do not check for NAN's or INF's.
                K           -   number of columns of matrix (A).                    
                B0          -   output buffer, possibly preallocated. In case  buffer
                                size is too small to store  result,  this  buffer  is
                                automatically resized.
                B1          -   output buffer, possibly preallocated. In case  buffer
                                size is too small to store  result,  this  buffer  is
                                automatically resized.
            
            OUTPUT PARAMETERS
                B0          -   array[N][K], S*A
                B1          -   array[N][K], S^T*A
            
            NOTE: this function throws exception when called for non-CRS matrix.  You
            must convert your matrix  with  SparseConvertToCRS()  before  using  this
            function. It also throws exception when S is non-square.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparsemm2(sparsematrix s,
                double[,] a,
                int k,
                ref double[,] b0,
                ref double[,] b1)
            {
                int i = 0;
                int j = 0;
                int k0 = 0;
                int lt = 0;
                int rt = 0;
                int ct = 0;
                double v = 0;
                double tval = 0;
                int i_ = 0;

                alglib.ap.assert(s.matrixtype == 1, "SparseMM2: incorrect matrix type (convert your matrix to CRS)");
                alglib.ap.assert(s.ninitialized == s.ridx[s.m], "SparseMM2: some rows/elements of the CRS matrix were not initialized (you must initialize everything you promised to SparseCreateCRS)");
                alglib.ap.assert(s.m == s.n, "SparseMM2: matrix is non-square");
                alglib.ap.assert(alglib.ap.rows(a) >= s.n, "SparseMM2: Rows(A)<N");
                alglib.ap.assert(k > 0, "SparseMM2: K<=0");
                apserv.rmatrixsetlengthatleast(ref b0, s.m, k);
                apserv.rmatrixsetlengthatleast(ref b1, s.n, k);
                for (i = 0; i <= s.n - 1; i++)
                {
                    for (j = 0; j <= k - 1; j++)
                    {
                        b1[i, j] = 0;
                    }
                }
                if (k < linalgswitch)
                {
                    for (i = 0; i <= s.m - 1; i++)
                    {
                        for (j = 0; j <= k - 1; j++)
                        {
                            tval = 0;
                            lt = s.ridx[i];
                            rt = s.ridx[i + 1];
                            v = a[i, j];
                            for (k0 = lt; k0 <= rt - 1; k0++)
                            {
                                ct = s.idx[k0];
                                b1[ct, j] = b1[ct, j] + s.vals[k0] * v;
                                tval = tval + s.vals[k0] * a[ct, j];
                            }
                            b0[i, j] = tval;
                        }
                    }
                }
                else
                {
                    for (i = 0; i <= s.m - 1; i++)
                    {
                        for (j = 0; j <= k - 1; j++)
                        {
                            b0[i, j] = 0;
                        }
                    }
                    for (i = 0; i <= s.m - 1; i++)
                    {
                        lt = s.ridx[i];
                        rt = s.ridx[i + 1];
                        for (j = lt; j <= rt - 1; j++)
                        {
                            v = s.vals[j];
                            ct = s.idx[j];
                            for (i_ = 0; i_ <= k - 1; i_++)
                            {
                                b0[i, i_] = b0[i, i_] + v * a[ct, i_];
                            }
                            for (i_ = 0; i_ <= k - 1; i_++)
                            {
                                b1[ct, i_] = b1[ct, i_] + v * a[i, i_];
                            }
                        }
                    }
                }
            }
コード例 #26
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function creates sparse matrix in a CRS format (expert function for
            situations when you are running out of memory).

            This function creates CRS matrix. Typical usage scenario for a CRS matrix 
            is:
            1. creation (you have to tell number of non-zero elements at each row  at 
               this moment)
            2. insertion of the matrix elements (row by row, from left to right) 
            3. matrix is passed to some linear algebra algorithm

            This function is a memory-efficient alternative to SparseCreate(), but it
            is more complex because it requires you to know in advance how large your
            matrix is. Some  information about  different matrix formats can be found 
            below, in the "NOTES" section.

            INPUT PARAMETERS
                M           -   number of rows in a matrix, M>=1
                N           -   number of columns in a matrix, N>=1
                NER         -   number of elements at each row, array[M], NER[i]>=0

            OUTPUT PARAMETERS
                S           -   sparse M*N matrix in CRS representation.
                                You have to fill ALL non-zero elements by calling
                                SparseSet() BEFORE you try to use this matrix.

            NOTE 1.

            Sparse matrices can be stored using either Hash-Table  representation  or
            Compressed  Row  Storage  representation. Hast-table is better suited for
            querying   and   dynamic   operations   (thus,  it  is  used  for  matrix
            initialization), but it is inefficient when you want to make some  linear 
            algebra operations.

            From the other side, CRS is better suited for linear algebra  operations,
            but initialization is less convenient - you have to tell row sizes at the
            initialization,  and  you  can  fill matrix only row by row, from left to 
            right. CRS is also very inefficient when you want to find matrix  element 
            by its index.

            Thus,  Hash-Table  representation   does   not   support  linear  algebra
            operations, while CRS format does not support modification of the  table.
            Tables below outline information about these two formats:

                OPERATIONS WITH MATRIX      HASH        CRS
                create                      +           +
                read element                +           +
                modify element              +           
                add value to element        +
                A*x  (dense vector)                     +
                A'*x (dense vector)                     +
                A*X  (dense matrix)                     +
                A'*X (dense matrix)                     +

            NOTE 2.

            Hash-tables use memory inefficiently, and they have to keep  some  amount
            of the "spare memory" in order to have good performance. Hash  table  for
            matrix with K non-zero elements will  need  C*K*(8+2*sizeof(int))  bytes,
            where C is a small constant, about 1.5-2 in magnitude.

            CRS storage, from the other side, is  more  memory-efficient,  and  needs
            just K*(8+sizeof(int))+M*sizeof(int) bytes, where M is a number  of  rows
            in a matrix.

            When you convert from the Hash-Table to CRS  representation, all unneeded
            memory will be freed.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparsecreatecrs(int m,
                int n,
                int[] ner,
                sparsematrix s)
            {
                int i = 0;
                int noe = 0;

                alglib.ap.assert(m > 0, "SparseCreateCRS: M<=0");
                alglib.ap.assert(n > 0, "SparseCreateCRS: N<=0");
                alglib.ap.assert(alglib.ap.len(ner) >= m, "SparseCreateCRS: Length(NER)<M");
                noe = 0;
                s.matrixtype = 1;
                s.ninitialized = 0;
                s.m = m;
                s.n = n;
                s.ridx = new int[s.m + 1];
                s.ridx[0] = 0;
                for (i = 0; i <= s.m - 1; i++)
                {
                    alglib.ap.assert(ner[i] >= 0, "SparseCreateCRS: NER[] contains negative elements");
                    noe = noe + ner[i];
                    s.ridx[i + 1] = s.ridx[i] + ner[i];
                }
                s.vals = new double[noe];
                s.idx = new int[noe];
                if (noe == 0)
                {
                    sparseinitduidx(s);
                }
            }
コード例 #27
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This procedure resizes Hash-Table matrix. It can be called when you  have
            deleted too many elements from the matrix, and you want to  free unneeded
            memory.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparseresizematrix(sparsematrix s)
            {
                int k = 0;
                int k1 = 0;
                int i = 0;
                double[] tvals = new double[0];
                int[] tidx = new int[0];

                alglib.ap.assert(s.matrixtype == 0, "SparseResizeMatrix: incorrect matrix type");

                //
                //initialization for length and number of non-null elementd
                //
                k = alglib.ap.len(s.vals);
                k1 = 0;

                //
                //calculating number of non-null elements
                //
                for (i = 0; i <= k - 1; i++)
                {
                    if (s.idx[2 * i] >= 0)
                    {
                        k1 = k1 + 1;
                    }
                }

                //
                //initialization value for free space
                //
                s.nfree = (int)Math.Round(k1 / desiredloadfactor * growfactor + additional) - k1;
                tvals = new double[s.nfree + k1];
                tidx = new int[2 * (s.nfree + k1)];
                alglib.ap.swap(ref s.vals, ref tvals);
                alglib.ap.swap(ref s.idx, ref tidx);
                for (i = 0; i <= s.nfree + k1 - 1; i++)
                {
                    s.idx[2 * i] = -1;
                }
                for (i = 0; i <= k - 1; i++)
                {
                    if (tidx[2 * i] >= 0)
                    {
                        sparseset(s, tidx[2 * i], tidx[2 * i + 1], tvals[i]);
                    }
                }
            }
コード例 #28
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            This function copies S0 to S1.

            NOTE:  this  function  does  not verify its arguments, it just copies all
            fields of the structure.

              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            public static void sparsecopy(sparsematrix s0,
                sparsematrix s1)
            {
                int l = 0;
                int i = 0;

                s1.matrixtype = s0.matrixtype;
                s1.m = s0.m;
                s1.n = s0.n;
                s1.nfree = s0.nfree;
                s1.ninitialized = s0.ninitialized;

                //
                //initialization for arrays
                //
                l = alglib.ap.len(s0.vals);
                s1.vals = new double[l];
                for (i = 0; i <= l - 1; i++)
                {
                    s1.vals[i] = s0.vals[i];
                }
                l = alglib.ap.len(s0.ridx);
                s1.ridx = new int[l];
                for (i = 0; i <= l - 1; i++)
                {
                    s1.ridx[i] = s0.ridx[i];
                }
                l = alglib.ap.len(s0.idx);
                s1.idx = new int[l];
                for (i = 0; i <= l - 1; i++)
                {
                    s1.idx[i] = s0.idx[i];
                }

                //
                //initalization for CRS-parameters
                //
                l = alglib.ap.len(s0.uidx);
                s1.uidx = new int[l];
                for (i = 0; i <= l - 1; i++)
                {
                    s1.uidx[i] = s0.uidx[i];
                }
                l = alglib.ap.len(s0.didx);
                s1.didx = new int[l];
                for (i = 0; i <= l - 1; i++)
                {
                    s1.didx[i] = s0.didx[i];
                }
            }
コード例 #29
0
ファイル: linalg.cs プロジェクト: tablee/TabBox
            /*************************************************************************
            Procedure for initialization 'S.DIdx' and 'S.UIdx'


              -- ALGLIB PROJECT --
                 Copyright 14.10.2011 by Bochkanov Sergey
            *************************************************************************/
            private static void sparseinitduidx(sparsematrix s)
            {
                int i = 0;
                int j = 0;
                int lt = 0;
                int rt = 0;

                s.didx = new int[s.m];
                s.uidx = new int[s.m];
                for (i = 0; i <= s.m - 1; i++)
                {
                    s.uidx[i] = -1;
                    s.didx[i] = -1;
                    lt = s.ridx[i];
                    rt = s.ridx[i + 1];
                    for (j = lt; j <= rt - 1; j++)
                    {
                        if (i < s.idx[j] && s.uidx[i] == -1)
                        {
                            s.uidx[i] = j;
                            break;
                        }
                        else
                        {
                            if (i == s.idx[j])
                            {
                                s.didx[i] = j;
                            }
                        }
                    }
                    if (s.uidx[i] == -1)
                    {
                        s.uidx[i] = s.ridx[i + 1];
                    }
                    if (s.didx[i] == -1)
                    {
                        s.didx[i] = s.uidx[i];
                    }
                }
            }
コード例 #30
0
ファイル: linalg.cs プロジェクト: Kerbas-ad-astra/MechJeb2
        /*************************************************************************
        This  function  performs  out-of-place  conversion  to  CRS format.  S0 is
        copied to S1 and converted on-the-fly. Memory allocated in S1 is reused to
        maximum extent possible.

        INPUT PARAMETERS
            S0          -   sparse matrix in any format.
            S1          -   matrix which may contain some pre-allocated memory, or
                            can be just uninitialized structure.

        OUTPUT PARAMETERS
            S1          -   sparse matrix in CRS format.
            
        NOTE: if S0 is stored as CRS, it is just copied without conversion.

          -- ALGLIB PROJECT --
             Copyright 20.07.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void sparsecopytocrsbuf(sparsematrix s0,
            sparsematrix s1)
        {
            int[] temp = new int[0];
            int nonne = 0;
            int i = 0;
            int j = 0;
            int k = 0;
            int offs0 = 0;
            int offs1 = 0;
            int m = 0;

            alglib.ap.assert((s0.matrixtype==0 || s0.matrixtype==1) || s0.matrixtype==2, "SparseCopyToCRSBuf: invalid matrix type");
            m = s0.m;
            if( s0.matrixtype==0 )
            {
                
                //
                // Convert from hash-table to CRS
                // Done like ConvertToCRS function
                //
                s1.matrixtype = 1;
                s1.m = s0.m;
                s1.n = s0.n;
                s1.nfree = s0.nfree;
                nonne = 0;
                k = s0.tablesize;
                apserv.ivectorsetlengthatleast(ref s1.ridx, s1.m+1);
                for(i=0; i<=s1.m; i++)
                {
                    s1.ridx[i] = 0;
                }
                temp = new int[s1.m];
                for(i=0; i<=s1.m-1; i++)
                {
                    temp[i] = 0;
                }
                
                //
                // Number of elements per row
                //
                for(i=0; i<=k-1; i++)
                {
                    if( s0.idx[2*i]>=0 )
                    {
                        s1.ridx[s0.idx[2*i]+1] = s1.ridx[s0.idx[2*i]+1]+1;
                        nonne = nonne+1;
                    }
                }
                
                //
                // Fill RIdx (offsets of rows)
                //
                for(i=0; i<=s1.m-1; i++)
                {
                    s1.ridx[i+1] = s1.ridx[i+1]+s1.ridx[i];
                }
                
                //
                // Allocate memory
                //
                apserv.rvectorsetlengthatleast(ref s1.vals, nonne);
                apserv.ivectorsetlengthatleast(ref s1.idx, nonne);
                for(i=0; i<=k-1; i++)
                {
                    if( s0.idx[2*i]>=0 )
                    {
                        s1.vals[s1.ridx[s0.idx[2*i]]+temp[s0.idx[2*i]]] = s0.vals[i];
                        s1.idx[s1.ridx[s0.idx[2*i]]+temp[s0.idx[2*i]]] = s0.idx[2*i+1];
                        temp[s0.idx[2*i]] = temp[s0.idx[2*i]]+1;
                    }
                }
                
                //
                // Set NInitialized
                //
                s1.ninitialized = s1.ridx[s1.m];
                
                //
                // Sorting of elements
                //
                for(i=0; i<=s1.m-1; i++)
                {
                    tsort.tagsortmiddleir(ref s1.idx, ref s1.vals, s1.ridx[i], s1.ridx[i+1]-s1.ridx[i]);
                }
                
                //
                // Initialization 'S.UIdx' and 'S.DIdx'
                //
                sparseinitduidx(s1);
                return;
            }
            if( s0.matrixtype==1 )
            {
                
                //
                // Already CRS, just copy
                //
                sparsecopybuf(s0, s1);
                return;
            }
            if( s0.matrixtype==2 )
            {
                alglib.ap.assert(s0.m==s0.n, "SparseCopyToCRS: non-square SKS matrices are not supported");
                
                //
                // From SKS to CRS.
                //
                s1.m = s0.m;
                s1.n = s0.n;
                s1.matrixtype = 1;
                
                //
                // Fill RIdx by number of elements per row:
                // RIdx[I+1] stores number of elements in I-th row.
                //
                // Convert RIdx from row sizes to row offsets.
                // Set NInitialized
                //
                apserv.ivectorsetlengthatleast(ref s1.ridx, m+1);
                s1.ridx[0] = 0;
                for(i=1; i<=m; i++)
                {
                    s1.ridx[i] = 1;
                }
                nonne = 0;
                for(i=0; i<=m-1; i++)
                {
                    s1.ridx[i+1] = s0.didx[i]+s1.ridx[i+1];
                    for(j=i-s0.uidx[i]; j<=i-1; j++)
                    {
                        s1.ridx[j+1] = s1.ridx[j+1]+1;
                    }
                    nonne = nonne+s0.didx[i]+1+s0.uidx[i];
                }
                for(i=0; i<=m-1; i++)
                {
                    s1.ridx[i+1] = s1.ridx[i+1]+s1.ridx[i];
                }
                s1.ninitialized = s1.ridx[m];
                
                //
                // Allocate memory and move elements to Vals/Idx.
                // Initially, elements are sorted by rows, and are sorted within row too.
                // No additional post-sorting is required.
                //
                temp = new int[m];
                for(i=0; i<=m-1; i++)
                {
                    temp[i] = 0;
                }
                apserv.rvectorsetlengthatleast(ref s1.vals, nonne);
                apserv.ivectorsetlengthatleast(ref s1.idx, nonne);
                for(i=0; i<=m-1; i++)
                {
                    
                    //
                    // copy subdiagonal and diagonal parts of I-th block
                    //
                    offs0 = s0.ridx[i];
                    offs1 = s1.ridx[i]+temp[i];
                    k = s0.didx[i]+1;
                    for(j=0; j<=k-1; j++)
                    {
                        s1.vals[offs1+j] = s0.vals[offs0+j];
                        s1.idx[offs1+j] = i-s0.didx[i]+j;
                    }
                    temp[i] = temp[i]+s0.didx[i]+1;
                    
                    //
                    // Copy superdiagonal part of I-th block
                    //
                    offs0 = s0.ridx[i]+s0.didx[i]+1;
                    k = s0.uidx[i];
                    for(j=0; j<=k-1; j++)
                    {
                        offs1 = s1.ridx[i-k+j]+temp[i-k+j];
                        s1.vals[offs1] = s0.vals[offs0+j];
                        s1.idx[offs1] = i;
                        temp[i-k+j] = temp[i-k+j]+1;
                    }
                }
                
                //
                // Initialization 'S.UIdx' and 'S.DIdx'
                //
                sparseinitduidx(s1);
                return;
            }
            alglib.ap.assert(false, "SparseCopyToCRSBuf: unexpected matrix type");
        }