third_party/inchi/INCHI_BASE/src/strutil.c
subgraf *subgraf_new( ORIG_ATOM_DATA *orig_inp_data,
                      int nnodes, 
                      int *nodes )
{
    int i, j, iat, nbr, jat, nj, degree, nat, err = 0;

    subgraf *sg = (subgraf *) inchi_calloc( 1, sizeof( subgraf ) );
    if (!sg)
    {
        return NULL;
    }

    nat = orig_inp_data->num_inp_atoms;

    /* orig2node is mapping of original at numbers --> subgraph node numbers */
    err = 1;
    if (!( sg->orig2node = (int *) inchi_calloc( nat + 1, sizeof( int ) ) ))
    {
        goto exit_function;
    }
    if (!( sg->nodes = (int *) inchi_calloc( nnodes, sizeof( int ) ) ))
    {
        goto exit_function;
    }
    if (!( sg->degrees = (int *) inchi_calloc( nnodes, sizeof( int ) ) ))
    {
        goto exit_function;
    }
    /* NB:    input list of 'nodes' is assumed to be in 'original_atom_numbering domain' which starts from 1.
    Now it is mapped to current atom numbers which starts from 0/connections using at[j].orig_at_number    */
    sg->nnodes = 0;
    for (i = 0; i < nnodes; i++)
    {
        sg->nodes[sg->nnodes++] = nodes[i];
    }

    for (i = 0; i <= nat; i++)
    {
        sg->orig2node[i] = -1;
    }
    for (i = 0; i < nnodes; i++)
    {
        sg->orig2node[sg->nodes[i]] = i;
    }

    /* Create and fill subgraph adjacency matrix based on nodes/orig atom numbers 
       and connections stored in orig_inp_data */
    sg->adj = (subgraf_edge **) inchi_calloc( nnodes, sizeof( subgraf_edge * ) );
    if (!sg->adj)
    {
        goto exit_function;
    }

    for (i = 0; i < sg->nnodes; i++)
    {
        iat = nodes[i] - 1;    /* current atom  number for this node */
        degree = orig_inp_data->at[iat].valence;
        nj = -1;
        sg->adj[i] = (subgraf_edge *) inchi_calloc( degree, sizeof( subgraf_edge ) );
        if (!sg->adj[i])
        {
            goto exit_function;
        }
        for (j = 0; j < degree; j++)
        {
            jat = orig_inp_data->at[iat].neighbor[j]; /* for curr num jat, a (jat+1) would be an orig num */
            nbr = sg->orig2node[jat + 1];
            if (nbr < 0)
                continue;
            nj++;
            sg->adj[i][nj].nbr = nbr;
            sg->adj[i][nj].etype = orig_inp_data->at[iat].bond_type[j];
        }
        sg->degrees[i] = nj + 1;
    }
    err = 0;

    /* subgraf_debug_trace( sg ); */

exit_function:
    if (err)
    {
        subgraf_free( sg );
    }

    return sg;
}
/****************************************************************************
 Establish light-weight subgraph representing (part of) orig_inp_data
 ****************************************************************************/
Establish light-weight subgraph representing (part of) orig_inp_data
Establish light - weight subgraph representing ( part of ) orig_inp_data
subgraf *subgraf_new( ORIG_ATOM_DATA *orig_inp_data,
                      int nnodes, 
                      int *nodes )
{
    int i, j, iat, nbr, jat, nj, degree, nat, err = 0;
    subgraf *sg = (subgraf *) inchi_calloc( 1, sizeof( subgraf ) );
    if (!sg)
    {
        return NULL;
    }
    nat = orig_inp_data->num_inp_atoms;
    err = 1;
    if (!( sg->orig2node = (int *) inchi_calloc( nat + 1, sizeof( int ) ) ))
    {
        goto exit_function;
    }
    if (!( sg->nodes = (int *) inchi_calloc( nnodes, sizeof( int ) ) ))
    {
        goto exit_function;
    }
    if (!( sg->degrees = (int *) inchi_calloc( nnodes, sizeof( int ) ) ))
    {
        goto exit_function;
    }
    sg->nnodes = 0;
    for (i = 0; i < nnodes; i++)
    {
        sg->nodes[sg->nnodes++] = nodes[i];
    }
    for (i = 0; i <= nat; i++)
    {
        sg->orig2node[i] = -1;
    }
    for (i = 0; i < nnodes; i++)
    {
        sg->orig2node[sg->nodes[i]] = i;
    }
    sg->adj = (subgraf_edge **) inchi_calloc( nnodes, sizeof( subgraf_edge * ) );
    if (!sg->adj)
    {
        goto exit_function;
    }
    for (i = 0; i < sg->nnodes; i++)
    {
        iat = nodes[i] - 1;    
        degree = orig_inp_data->at[iat].valence;
        nj = -1;
        sg->adj[i] = (subgraf_edge *) inchi_calloc( degree, sizeof( subgraf_edge ) );
        if (!sg->adj[i])
        {
            goto exit_function;
        }
        for (j = 0; j < degree; j++)
        {
            jat = orig_inp_data->at[iat].neighbor[j]; 
            nbr = sg->orig2node[jat + 1];
            if (nbr < 0)
                continue;
            nj++;
            sg->adj[i][nj].nbr = nbr;
            sg->adj[i][nj].etype = orig_inp_data->at[iat].bond_type[j];
        }
        sg->degrees[i] = nj + 1;
    }
    err = 0;
exit_function:
    if (err)
    {
        subgraf_free( sg );
    }
    return sg;
}
subgraf * subgraf_new ( ORIG_ATOM_DATA * orig_inp_data , int nnodes , int * nodes ) { int i , j , iat , nbr , jat , nj , degree , nat , err = 0 ; subgraf * sg = ( subgraf * ) inchi_calloc ( 1 , sizeof ( subgraf ) ) ; if ( ! sg ) { return NULL ; } nat = orig_inp_data -> num_inp_atoms ; err = 1 ; if ( ! ( sg -> orig2node = ( int * ) inchi_calloc ( nat + 1 , sizeof ( int ) ) ) ) { goto exit_function ; } if ( ! ( sg -> nodes = ( int * ) inchi_calloc ( nnodes , sizeof ( int ) ) ) ) { goto exit_function ; } if ( ! ( sg -> degrees = ( int * ) inchi_calloc ( nnodes , sizeof ( int ) ) ) ) { goto exit_function ; } sg -> nnodes = 0 ; for ( i = 0 ; i < nnodes ; i ++ ) { sg -> nodes [ sg -> nnodes ++ ] = nodes [ i ] ; } for ( i = 0 ; i <= nat ; i ++ ) { sg -> orig2node [ i ] = -1 ; } for ( i = 0 ; i < nnodes ; i ++ ) { sg -> orig2node [ sg -> nodes [ i ] ] = i ; } sg -> adj = ( subgraf_edge * * ) inchi_calloc ( nnodes , sizeof ( subgraf_edge * ) ) ; if ( ! sg -> adj ) { goto exit_function ; } for ( i = 0 ; i < sg -> nnodes ; i ++ ) { iat = nodes [ i ] - 1 ; degree = orig_inp_data -> at [ iat ] . valence ; nj = -1 ; sg -> adj [ i ] = ( subgraf_edge * ) inchi_calloc ( degree , sizeof ( subgraf_edge ) ) ; if ( ! sg -> adj [ i ] ) { goto exit_function ; } for ( j = 0 ; j < degree ; j ++ ) { jat = orig_inp_data -> at [ iat ] . neighbor [ j ] ; nbr = sg -> orig2node [ jat + 1 ] ; if ( nbr < 0 ) continue ; nj ++ ; sg -> adj [ i ] [ nj ] . nbr = nbr ; sg -> adj [ i ] [ nj ] . etype = orig_inp_data -> at [ iat ] . bond_type [ j ] ; } sg -> degrees [ i ] = nj + 1 ; } err = 0 ; exit_function : if ( err ) { subgraf_free ( sg ) ; } return sg ; }
Establish light-weight subgraph representing (part of) orig_inp_data
Establish light - weight subgraph representing ( part of ) orig_inp_data
/* orig2node is mapping of original at numbers --> subgraph node numbers */ /* NB:    input list of 'nodes' is assumed to be in 'original_atom_numbering domain' which starts from 1.
    Now it is mapped to current atom numbers which starts from 0/connections using at[j].orig_at_number    */ /* Create and fill subgraph adjacency matrix based on nodes/orig atom numbers 
       and connections stored in orig_inp_data */ /* current atom  number for this node */ /* for curr num jat, a (jat+1) would be an orig num */ /* subgraf_debug_trace( sg ); */