2013-07-28 76 views
0

我創建一個新的類。該類聲明一個結構變量,cs,它用於該類的所有功能。該類中函數的一些返回變量類型爲cs *。在下面,是CSparse.h的內容。在課堂上使用的typedef自己的結構數據

#ifndef _CSPARSE_H 
#define _CSPARSE_H 

#include <stdlib.h> 
#include <limits.h> 
#include <math.h> 
#include <stdio.h> 
#include <stddef.h> 
#ifdef MATLAB_MEX_FILE 
#include "mex.h" 
#endif 
#define CS_VER 3     /* CSparse Version */ 
#define CS_SUBVER 1 
#define CS_SUBSUB 2 
#define CS_DATE "April 16, 2013" /* CSparse release date */ 
#define CS_COPYRIGHT "Copyright (c) Timothy A. Davis, 2006-2013" 

#ifdef MATLAB_MEX_FILE 
#undef csi 
#define csi mwSignedIndex 
#endif 
#ifndef csi 
#define csi ptrdiff_t 
#endif 

class CSparse 
{ 
public: 
    CSparse(void); 
    virtual ~CSparse(void); 

    /* --- primary CSparse routines and data structures ------------------------- */ 
    typedef struct csparse  /* matrix in compressed-column or triplet form */ 
    { 
     csi nzmax ;  /* maximum number of entries */ 
     csi m ;   /* number of rows */ 
     csi n ;   /* number of columns */ 
     csi *p ;  /* column pointers (size n+1) or col indices (size nzmax) */ 
     csi *i ;  /* row indices, size nzmax */ 
     double *x ;  /* numerical values, size nzmax */ 
     csi nz ;  /* # of entries in triplet matrix, -1 for compressed-col */ 
    } cs; 

    cs *cs_add (const cs *A, const cs *B, double alpha, double beta) ; 
    csi cs_cholsol (csi order, const cs *A, double *b) ; 
    cs *cs_compress (const cs *T) ; 
    csi cs_dupl (cs *A) ; 
    csi cs_entry (cs *T, csi i, csi j, double x) ; 
    csi cs_gaxpy (const cs *A, const double *x, double *y) ; 
    cs *cs_load (FILE *f) ; 
    csi cs_lusol (csi order, const cs *A, double *b, double tol) ; 
    cs *cs_multiply (const cs *A, const cs *B) ; 
    double cs_norm (const cs *A) ; 
    csi cs_print (const cs *A, csi brief) ; 
    csi cs_qrsol (csi order, const cs *A, double *b) ; 
    cs *cs_transpose (const cs *A, csi values) ; 

    /* utilities */ 
    void *cs_calloc (csi n, size_t size) ; 
    void *cs_free (void *p) ; 
    void *cs_realloc (void *p, csi n, size_t size, csi *ok) ; 
    cs *cs_spalloc (csi m, csi n, csi nzmax, csi values, csi triplet) ; 
    cs *cs_spfree (cs *A) ; 
    csi cs_sprealloc (cs *A, csi nzmax) ; 
    void *cs_malloc (csi n, size_t size) ; 

private: 
    /* --- secondary CSparse routines and data structures ----------------------- */ 
    typedef struct cs_symbolic /* symbolic Cholesky, LU, or QR analysis */ 
    { 
     csi *pinv ;  /* inverse row perm. for QR, fill red. perm for Chol */ 
     csi *q ;  /* fill-reducing column permutation for LU and QR */ 
     csi *parent ; /* elimination tree for Cholesky and QR */ 
     csi *cp ;  /* column pointers for Cholesky, row counts for QR */ 
     csi *leftmost ; /* leftmost[i] = min(find(A(i,:))), for QR */ 
     csi m2 ;  /* # of rows for QR, after adding fictitious rows */ 
     double lnz ; /* # entries in L for LU or Cholesky; in V for QR */ 
     double unz ; /* # entries in U for LU; in R for QR */ 
    } css; 

    typedef struct cs_numeric /* numeric Cholesky, LU, or QR factorization */ 
    { 
     cs *L ;   /* L for LU and Cholesky, V for QR */ 
     cs *U ;   /* U for LU, R for QR, not used for Cholesky */ 
     csi *pinv ;  /* partial pivoting for LU */ 
     double *B ;  /* beta [0..n-1] for QR */ 
    } csn; 

    typedef struct cs_dmperm  /* cs_dmperm or cs_scc output */ 
    { 
     csi *p ;  /* size m, row permutation */ 
     csi *q ;  /* size n, column permutation */ 
     csi *r ;  /* size nb+1, block k is rows r[k] to r[k+1]-1 in A(p,q) */ 
     csi *s ;  /* size nb+1, block k is cols s[k] to s[k+1]-1 in A(p,q) */ 
     csi nb ;  /* # of blocks in fine dmperm decomposition */ 
     csi rr [5] ; /* coarse row decomposition */ 
     csi cc [5] ; /* coarse column decomposition */ 
    } csd; 

    csi *cs_amd (csi order, const cs *A) ; 
    csn *cs_chol (const cs *A, const css *S) ; 
    csd *cs_dmperm (const cs *A, csi seed) ; 
    csi cs_droptol (cs *A, double tol) ; 
    csi cs_dropzeros (cs *A) ; 
    csi cs_happly (const cs *V, csi i, double beta, double *x) ; 
    csi cs_ipvec (const csi *p, const double *b, double *x, csi n) ; 
    csi cs_lsolve (const cs *L, double *x) ; 
    csi cs_ltsolve (const cs *L, double *x) ; 
    csn *cs_lu (const cs *A, const css *S, double tol) ; 
    cs *cs_permute (const cs *A, const csi *pinv, const csi *q, csi values) ; 
    csi *cs_pinv (const csi *p, csi n) ; 
    csi cs_pvec (const csi *p, const double *b, double *x, csi n) ; 
    csn *cs_qr (const cs *A, const css *S) ; 
    css *cs_schol (csi order, const cs *A) ; 
    css *cs_sqr (csi order, const cs *A, csi qr) ; 
    cs *cs_symperm (const cs *A, const csi *pinv, csi values) ; 
    csi cs_updown (cs *L, csi sigma, const cs *C, const csi *parent) ; 
    csi cs_usolve (const cs *U, double *x) ; 
    csi cs_utsolve (const cs *U, double *x) ; 
    /* utilities */ 
    css *cs_sfree (css *S) ; 
    csn *cs_nfree (csn *N) ; 
    csd *cs_dfree (csd *D) ; 

    /* --- tertiary CSparse routines -------------------------------------------- */ 
    csi *cs_counts (const cs *A, const csi *parent, const csi *post, csi ata) ; 
    double cs_cumsum (csi *p, csi *c, csi n) ; 
    csi cs_dfs (csi j, cs *G, csi top, csi *xi, csi *pstack, const csi *pinv) ; 
    csi cs_ereach (const cs *A, csi k, const csi *parent, csi *s, csi *w) ; 
    csi *cs_etree (const cs *A, csi ata) ; 
    csi cs_fkeep (cs *A, csi (*fkeep) (csi, csi, double, void *), void *other) ; 
    double cs_house (double *x, double *beta, csi n) ; 
    csi cs_leaf (csi i, csi j, const csi *first, csi *maxfirst, csi *prevleaf, 
        csi *ancestor, csi *jleaf) ; 
    csi *cs_maxtrans (const cs *A, csi seed) ; 
    csi *cs_post (const csi *parent, csi n) ; 
    csi *cs_randperm (csi n, csi seed) ; 
    csi cs_reach (cs *G, const cs *B, csi k, csi *xi, const csi *pinv) ; 
    csi cs_scatter (const cs *A, csi j, double beta, csi *w, double *x, csi mark, 
         cs *C, csi nz) ; 
    csd *cs_scc (cs *A) ; 
    csi cs_spsolve (cs *G, const cs *B, csi k, csi *xi, double *x, 
     const csi *pinv, csi lo) ; 
    csi cs_tdfs (csi j, csi k, csi *head, const csi *next, csi *post, 
        csi *stack) ; 
    /* utilities */ 
    csd *cs_dalloc (csi m, csi n) ; 
    csd *cs_ddone (csd *D, cs *C, void *w, csi ok) ; 
    cs *cs_done (cs *C, void *w, void *x, csi ok) ; 
    csi *cs_idone (csi *p, cs *C, void *w, csi ok) ; 
    csn *cs_ndone (csn *N, cs *C, void *w, void *x, csi ok) ; 

    #define CS_MAX(a,b) (((a) > (b)) ? (a) : (b)) 
    #define CS_MIN(a,b) (((a) < (b)) ? (a) : (b)) 
    #define CS_FLIP(i) (-(i)-2) 
    #define CS_UNFLIP(i) (((i) < 0) ? CS_FLIP(i) : (i)) 
    #define CS_MARKED(w,j) (w [j] < 0) 
    #define CS_MARK(w,j) { w [j] = CS_FLIP (w [j]) ; } 
    #define CS_CSC(A) (A && (A->nz == -1)) 
    #define CS_TRIPLET(A) (A && (A->nz >= 0)) 
}; 
#endif 

這裏是CSparse.cpp

#include "CSparse.h" 

CSparse::CSparse(void) 
{ 
} 

CSparse::~CSparse(void) 
{ 
} 

/* remove duplicate entries from A */ 
csi CSparse::cs_dupl (cs *A) 
{ 
    csi i, j, p, q, nz = 0, n, m, *Ap, *Ai, *w ; 
    double *Ax ; 
    if (!CS_CSC (A)) return (0) ;    /* check inputs */ 
    m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; 
    w = (csi*) cs_malloc (m, sizeof (csi)) ;   /* get workspace */ 
    if (!w) return (0) ;      /* out of memory */ 
    for (i = 0 ; i < m ; i++) w [i] = -1 ;  /* row i not yet seen */ 
    for (j = 0 ; j < n ; j++) 
    { 
     q = nz ;        /* column j will start at q */ 
     for (p = Ap [j] ; p < Ap [j+1] ; p++) 
     { 
      i = Ai [p] ;      /* A(i,j) is nonzero */ 
      if (w [i] >= q) 
      { 
       Ax [w [i]] += Ax [p] ;   /* A(i,j) is a duplicate */ 
      } 
      else 
      { 
       w [i] = nz ;     /* record where row i occurs */ 
       Ai [nz] = i ;     /* keep A(i,j) */ 
       Ax [nz++] = Ax [p] ; 
      } 
     } 
     Ap [j] = q ;       /* record start of column j */ 
    } 
    Ap [n] = nz ;        /* finalize A */ 
    cs_free (w) ;        /* free workspace */ 
    return (cs_sprealloc (A, 0)) ;    /* remove extra space from A */ 
} 

/* C = A' */ 
cs* CSparse::cs_transpose (const cs *A, csi values) // THIS IS THE LINE WHERE THE FIRST ERROR APPREARS. 
{ 
    csi p, q, j, *Cp, *Ci, n, m, *Ap, *Ai, *w ; 
    double *Cx, *Ax ; 
    cs *C ; 
    if (!CS_CSC (A)) return (NULL) ; /* check inputs */ 
    m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; 
    C = cs_spalloc (n, m, Ap [n], values && Ax, 0) ;  /* allocate result */ 
    w = (csi *) cs_calloc (m, sizeof (csi)) ;      /* get workspace */ 
    if (!C || !w) return (cs_done (C, w, NULL, 0)) ;  /* out of memory */ 
    Cp = C->p ; Ci = C->i ; Cx = C->x ; 
    for (p = 0 ; p < Ap [n] ; p++) w [Ai [p]]++ ;   /* row counts */ 
    cs_cumsum (Cp, w, m) ;         /* row pointers */ 
    for (j = 0 ; j < n ; j++) 
    { 
     for (p = Ap [j] ; p < Ap [j+1] ; p++) 
     { 
      Ci [q = w [Ai [p]]++] = j ; /* place A(i,j) as entry C(j,i) */ 
      if (Cx) Cx [q] = Ax [p] ; 
     } 
    } 
    return (cs_done (C, w, NULL, 1)) ; /* success; free w and return C */ 
} 

/* C = compressed-column form of a triplet matrix T */ 
cs *CSparse::cs_compress (const cs *T) 
{ 
    csi m, n, nz, p, k, *Cp, *Ci, *w, *Ti, *Tj ; 
    double *Cx, *Tx ; 
    cs *C ; 
    if (!CS_TRIPLET (T)) return (NULL) ;    /* check inputs */ 
    m = T->m ; n = T->n ; Ti = T->i ; Tj = T->p ; Tx = T->x ; nz = T->nz ; 
    C = cs_spalloc (m, n, nz, Tx != NULL, 0) ;   /* allocate result */ 
    w = (csi *) cs_calloc (n, sizeof (csi)) ;     /* get workspace */ 
    if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ 
    Cp = C->p ; Ci = C->i ; Cx = C->x ; 
    for (k = 0 ; k < nz ; k++) w [Tj [k]]++ ;   /* column counts */ 
    cs_cumsum (Cp, w, n) ;        /* column pointers */ 
    for (k = 0 ; k < nz ; k++) 
    { 
     Ci [p = w [Tj [k]]++] = Ti [k] ; /* A(i,j) is the pth entry in C */ 
     if (Cx) Cx [p] = Tx [k] ; 
    } 
    return (cs_done (C, w, NULL, 1)) ;  /* success; free w and return C */ 
} 


/* allocate a sparse matrix (triplet form or compressed-column form) */ 
cs *CSparse::cs_spalloc (csi m, csi n, csi nzmax, csi values, csi triplet) 
{ 
    cs *A = (cs *) cs_calloc (1, sizeof (cs)) ; /* allocate the cs struct */ 
    if (!A) return (NULL) ;     /* out of memory */ 
    A->m = m ;        /* define dimensions and nzmax */ 
    A->n = n ; 
    A->nzmax = nzmax = CS_MAX (nzmax, 1) ; 
    A->nz = triplet ? 0 : -1 ;    /* allocate triplet or comp.col */ 
    A->p = (csi *) cs_malloc (triplet ? nzmax : n+1, sizeof (csi)) ; 
    A->i = (csi *) cs_malloc (nzmax, sizeof (csi)) ; 
    A->x = values ? (double *) cs_malloc (nzmax, sizeof (double)) : NULL ; 
    return ((!A->p || !A->i || (values && !A->x)) ? cs_spfree (A) : A) ; 
} 

/* change the max # of entries sparse matrix */ 
csi CSparse::cs_sprealloc (cs *A, csi nzmax) 
{ 
    csi ok, oki, okj = 1, okx = 1 ; 
    if (!A) return (0) ; 
    if (nzmax <= 0) nzmax = (CS_CSC (A)) ? (A->p [A->n]) : A->nz ; 
    A->i = (csi *) cs_realloc (A->i, nzmax, sizeof (csi), &oki) ; 
    if (CS_TRIPLET (A)) A->p = (csi *) cs_realloc (A->p, nzmax, sizeof (csi), &okj) ; 
    if (A->x) A->x = (double *) cs_realloc (A->x, nzmax, sizeof (double), &okx) ; 
    ok = (oki && okj && okx) ; 
    if (ok) A->nzmax = nzmax ; 
    return (ok) ; 
} 

/* free a sparse matrix */ 
cs *CSparse::cs_spfree (cs *A) 
{ 
    if (!A) return (NULL) ;  /* do nothing if A already NULL */ 
    cs_free (A->p) ; 
    cs_free (A->i) ; 
    cs_free (A->x) ; 
    return ((cs *) cs_free (A)) ; /* free the cs struct and return NULL */ 
} 

/* free a numeric factorization */ 
csn *CSparse::cs_nfree (csn *N) 
{ 
    if (!N) return (NULL) ;  /* do nothing if N already NULL */ 
    cs_spfree (N->L) ; 
    cs_spfree (N->U) ; 
    cs_free (N->pinv) ; 
    cs_free (N->B) ; 
    return ((csn *) cs_free (N)) ; /* free the csn struct and return NULL */ 
} 

/* free a symbolic factorization */ 
css *CSparse::cs_sfree (css *S) 
{ 
    if (!S) return (NULL) ;  /* do nothing if S already NULL */ 
    cs_free (S->pinv) ; 
    cs_free (S->q) ; 
    cs_free (S->parent) ; 
    cs_free (S->cp) ; 
    cs_free (S->leftmost) ; 
    return ((css *) cs_free (S)) ; /* free the css struct and return NULL */ 
} 

/* allocate a cs_dmperm or cs_scc result */ 
csd *CSparse::cs_dalloc (csi m, csi n) 
{ 
    csd *D ; 
    D = (csd *) cs_calloc (1, sizeof (csd)) ; 
    if (!D) return (NULL) ; 
    D->p = (csi *) cs_malloc (m, sizeof (csi)) ; 
    D->r = (csi *) cs_malloc (m+6, sizeof (csi)) ; 
    D->q = (csi *) cs_malloc (n, sizeof (csi)) ; 
    D->s = (csi *) cs_malloc (n+6, sizeof (csi)) ; 
    return ((!D->p || !D->r || !D->q || !D->s) ? cs_dfree (D) : D) ; 
} 

/* free a cs_dmperm or cs_scc result */ 
csd *CSparse::cs_dfree (csd *D) 
{ 
    if (!D) return (NULL) ;  /* do nothing if D already NULL */ 
    cs_free (D->p) ; 
    cs_free (D->q) ; 
    cs_free (D->r) ; 
    cs_free (D->s) ; 
    return ((csd *) cs_free (D)) ; /* free the csd struct and return NULL */ 
} 

/* free workspace and return a sparse matrix result */ 
cs *CSparse::cs_done (cs *C, void *w, void *x, csi ok) 
{ 
    cs_free (w) ;      /* free workspace */ 
    cs_free (x) ; 
    return (ok ? C : cs_spfree (C)) ; /* return result if OK, else free it */ 
} 

/* free workspace and return csi array result */ 
csi *CSparse::cs_idone (csi *p, cs *C, void *w, csi ok) 
{ 
    cs_spfree (C) ;      /* free temporary matrix */ 
    cs_free (w) ;      /* free workspace */ 
    return (ok ? p : (csi *) cs_free (p)) ; /* return result, or free it */ 
} 

/* free workspace and return a numeric factorization (Cholesky, LU, or QR) */ 
csn *CSparse::cs_ndone (csn *N, cs *C, void *w, void *x, csi ok) 
{ 
    cs_spfree (C) ;      /* free temporary matrix */ 
    cs_free (w) ;      /* free workspace */ 
    cs_free (x) ; 
    return (ok ? N : cs_nfree (N)) ; /* return result if OK, else free it */ 
} 

/* free workspace and return a csd result */ 
csd *CSparse::cs_ddone (csd *D, cs *C, void *w, csi ok) 
{ 
    cs_spfree (C) ;      /* free temporary matrix */ 
    cs_free (w) ;      /* free workspace */ 
    return (ok ? D : cs_dfree (D)) ; /* return result if OK, else free it */ 
} 

/* wrapper for malloc */ 
void *CSparse::cs_malloc (csi n, size_t size) 
{ 
    return (malloc (CS_MAX (n,1) * size)) ; 
} 

/* wrapper for calloc */ 
void *CSparse::cs_calloc (csi n, size_t size) 
{ 
    return (calloc (CS_MAX (n,1), size)) ; 
} 

/* wrapper for free */ 
void *CSparse::cs_free (void *p) 
{ 
    if (p) free (p) ;  /* free p if it is not already NULL */ 
    return (NULL) ;   /* return NULL to simplify the use of cs_free */ 
} 

/* wrapper for realloc */ 
void *CSparse::cs_realloc (void *p, csi n, size_t size, csi *ok) 
{ 
    void *pnew ; 
    pnew = realloc (p, CS_MAX (n,1) * size) ; /* realloc the block */ 
    *ok = (pnew != NULL) ;     /* realloc fails if pnew is NULL */ 
    return ((*ok) ? pnew : p) ;    /* return original p if failure */ 
} 

/* p [0..n] = cumulative sum of c [0..n-1], and then copy p [0..n-1] into c */ 
double CSparse::cs_cumsum (csi *p, csi *c, csi n) 
{ 
    csi i, nz = 0 ; 
    double nz2 = 0 ; 
    if (!p || !c) return (-1) ;  /* check inputs */ 
    for (i = 0 ; i < n ; i++) 
    { 
     p [i] = nz ; 
     nz += c [i] ; 
     nz2 += c [i] ;    /* also in double to avoid csi overflow */ 
     c [i] = p [i] ;    /* also copy p[0..n-1] back into c[0..n-1]*/ 
    } 
    p [n] = nz ; 
    return (nz2) ;     /* return sum (c [0..n-1]) */ 
} 

/* C = alpha*A + beta*B */ 
cs *CSparse::cs_add (const cs *A, const cs *B, double alpha, double beta) 
{ 
    csi p, j, nz = 0, anz, *Cp, *Ci, *Bp, m, n, bnz, *w, values ; 
    double *x, *Bx, *Cx ; 
    cs *C ; 
    if (!CS_CSC (A) || !CS_CSC (B)) return (NULL) ;   /* check inputs */ 
    if (A->m != B->m || A->n != B->n) return (NULL) ; 
    m = A->m ; anz = A->p [A->n] ; 
    n = B->n ; Bp = B->p ; Bx = B->x ; bnz = Bp [n] ; 
    w = (csi *) cs_calloc (m, sizeof (csi)) ;      /* get workspace */ 
    values = (A->x != NULL) && (Bx != NULL) ; 
    x = values ? (double *) cs_malloc (m, sizeof (double)) : NULL ; /* get workspace */ 
    C = cs_spalloc (m, n, anz + bnz, values, 0) ;   /* allocate result*/ 
    if (!C || !w || (values && !x)) return (cs_done (C, w, x, 0)) ; 
    Cp = C->p ; Ci = C->i ; Cx = C->x ; 
    for (j = 0 ; j < n ; j++) 
    { 
     Cp [j] = nz ;     /* column j of C starts here */ 
     nz = cs_scatter (A, j, alpha, w, x, j+1, C, nz) ; /* alpha*A(:,j)*/ 
     nz = cs_scatter (B, j, beta, w, x, j+1, C, nz) ; /* beta*B(:,j) */ 
     if (values) for (p = Cp [j] ; p < nz ; p++) Cx [p] = x [Ci [p]] ; 
    } 
    Cp [n] = nz ;      /* finalize the last column of C */ 
    cs_sprealloc (C, 0) ;    /* remove extra space from C */ 
    return (cs_done (C, w, x, 1)) ;  /* success; free workspace, return C */ 
} 

內容的第一個錯誤,我得到如下。

1>.\CSparse.cpp(46) : error C2143: syntax error : missing ';' before '*' 

我已經在上面的源代碼中標記了錯誤位置。它發生在cs* CSparse::cs_transpose (const cs *A, csi values)的定義中。

網上搜索後,我發現,這是與typedef的範圍問題。因此,我不得不調整CSparse.cpp中函數的返回類型。例如,我改變

cs* CSparse::cs_transpose (const cs *A, csi values) 

CSparse::cs* CSparse::cs_transpose (const cs *A, csi values) 

它工作得很好。有沒有更好的方法來做到這一點?爲什麼這個問題是針對函數和函數參數的返回變量不會導致任何問題的。例如,在功能cs_transposeA以及函數返回變量是cs類型的,但只有函數的返回導致編譯器抱怨。另外,由於某些原因,我無法使用using namespace

有人能幫助我找到這個問題的正確解決方案嗎?

回答

1

在我看來,你只是忘了;你的MyClass類的結尾。

旁邊,你並不需要的typedef你的結構,則可能是:

struct ms { 
    double d; 
    double* pd; 
}; 

ms *myfunction(void); 
+0

安東尼奧:我這樣做了。然而,在'myClass.cpp'中定義'ms * myfunction(void)'的行中,出現錯誤sayig'錯誤C2143:syntax error:missing';'之前'*'' – AFP

+0

@Ahmad這是一個瘋狂的猜測...也許'ms'是你的編譯器中的保留字?你可以嘗試給你的結構一個不同的名字?你確定在所有的結構和類的結尾處的大括號後面加上所有分號嗎? – Antonio

+0

Antonio:我檢查了分號。還有什麼我可以仔細檢查的嗎? – AFP