0

I am creating a new class. The class declares a struct variable, cs, which is used in all functions of the class. Some of the return variable of the functions in the class are of type cs *. In below, is the content of CSparse.h.

#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

Here is the content of 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 */
}

The first error I get is the following.

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

I have marked the error location in the source code above. It happens in the definition of cs* CSparse::cs_transpose (const cs *A, csi values).

After searching online, I found out that this is the problem with the scope of the typedef. Therefore, I had to adjust the returned type of the functions in CSparse.cpp. For example, I changed

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

to

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

and it worked fine. Is there a better way of doing this? Why this problem is for the returned variable of the function and function arguments do not cause any problem. For example, in the function cs_transpose, A as well as function return variable is of type cs but only the function return causes the compiler to complain. Also, for some reasons, I could not use using namespace.

Could someone help me find the right solution for this problem?

1 Answer 1

1

It seems to me that you just forgot a ; at the end of your class myClass.

Beside, you don't need to typedef your struct, it could be:

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

ms *myfunction(void);
Sign up to request clarification or add additional context in comments.

5 Comments

Antonio: I did so. However, at the line where I define ms *myfunction(void) in myClass.cpp, I get an error sayig error C2143: syntax error : missing ';' before '*'
@Ahmad This is a wild guess... Maybe ms is a reserved word in your compiler? Can you try to give to your struct a different name? Are you sure you put all semicolons ; after the closing brace at end of all your structs and classes?
Antonio: I checked the semicolons. Is there any other thing that I can double check?
@Ahmad Try to post again your current code (edit your question, but leave your original text and append at the end your new code. You can also try your code at this link here coliru.stacked-crooked.com and post a link here/in your updated question. BTW, I am now going to bed...
@Ahmad The solution you found is correct. And, as long as I am aware, you cannot use namespaces for access a class namespace.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.