0

I have created a class called CSparse. Its header file is as follows.

#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;

    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_results     /* 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;

    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) ;

    /* --- secondary CSparse routines and data structures ----------------------- */    
    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

Some parts of the content of CSparse.cpp is as follows.

#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' */
CSparse::cs *CSparse::cs_transpose (const cs *A, csi values)
{
    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 */
}

I can access the class data type using ::. How can I use the functions of the class by using :: rather than creating an instance of the class and access the functions by using .? Which one is better for calling the functions: :: or .?

afp_2008
  • 1,940
  • 1
  • 19
  • 46
  • 5
    Apart from this being a gigantic wall-of-code, I think you're misunderstanding the use of classes and/or OOP in general. What I think you're trying to achieve is use functions and variables collected inside a class without having a class instance. This is the way a C-Programmer would (have to) do this, because it's not OOP at all. – arne Jul 29 '13 at 10:06
  • 2
    make those function `static`if you can.... and after you can call class function without having an instance – alexbuisson Jul 29 '13 at 10:07
  • 2
    You also know the `namespace` keyword, don't you? – neuront Jul 29 '13 at 10:16
  • @arne: You are right. I am trying to use the functions and variables collected inside a class. What would you recommend? Is it a bad style that I have created a class for all these C functions and organize them in a class? May I have your thoughts on this? – afp_2008 Jul 31 '13 at 00:28
  • 1
    @Ahmad: I'd at least put them in a namespace instead of a class. Even better would be to think of a good object oriented class design. Browse http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list and pick (almost) any book from the list to read up on that. – arne Jul 31 '13 at 05:56

2 Answers2

3

Functions that are static in C++ classes are accessed with :: and accessing functions that are from instances of an object is done with .

Therefore if you declare: -

class SomeClass
{
    public:
      void Function1();
      static void Function2();
};

You can then call the following: -

SomeClass::Function2(); // called without an instantiated object

Or instantiate an object: -

SomeClass classObj; // create an object
classObj.Function1(); // call the function from an instance of the object

Note that if you use the static method, the member variables of the class need to be static in order for you to access them from within the function.

Neither :: or . can be classed as 'better'. It all depends on the design of your program and the class for which you will use.

TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
0

Just mark the function as class level function instead of instance level. In C++ just turget it as static. E.g.

static css *cs_sfree (css *S) ;

then 
void foo()
{
   css* a = 0;
   css* b = 0;
   a = CSparse::cs_sfree(b);
}

The difference is that you can invoke static function without an object but you cant modify object from it(cant use this pointer). Non static function is connected to one object(through this pointer)

Leaf
  • 553
  • 5
  • 13