Exemplo n.º 1
0
/** execute_actual_parameters	Execute the actual parameters of
 *				a declared subroutine call.
 *
 * @param p_function_id : ptr to the subroutine name's symtab node
 */
void cx_executor::execute_actual_parameters (cx_symtab_node *p_function_id) {
    cx_symtab_node *p_formal_id; // ptr to formal parm's symtab node

    // Loop to execute each actual parameter.
    for (p_formal_id = p_function_id->defn.routine.locals.p_parms_ids;
            p_formal_id;
            p_formal_id = p_formal_id->next__) {

        cx_type *p_formal_type = p_formal_id->p_type;
        get_token();

        /* Reference parameter: execute_variable will leave the actual
         * parameter's address on top of the stack. */
        if (p_formal_id->defn.how == dc_reference) {

            const int size = p_node->p_type->size;
            p_formal_type->form = p_node->p_type->form;
            execute_variable(p_node, true);

            if (p_formal_type->form == fc_array) {

                p_formal_type->size = size;
                p_formal_type->array.element_count = size;
                p_formal_type->array.max_index = size;

                p_formal_id->runstack_item = top();

            } else {
                p_formal_id->runstack_item = top();
            }

            get_token();
        }// value parameter
        else {
            cx_type *p_actual_type = execute_expression();

            if ((p_formal_type == p_float_type) &&
                    (p_actual_type->base_type() == p_integer_type)) {

                // real formal := integer actual:
                // convert integer value to real.
                float ff = top()->basic_types.int__;
                pop();

                push(ff);
                p_formal_id->runstack_item = top();
            } else if (!p_formal_type->is_scalar_type()) {

                /* Formal parameter is an array or a record:
                 * Make a copy of the actual parameter's value. */

                const int size = p_actual_type->size;
                void *p_target_address = nullptr;
                const int num_of_elements = size / p_actual_type->base_type()->size;

                p_target_address = realloc(p_target_address, size);
                //memset(p_target_address, 0, size);

                if (p_target_address == nullptr) {
                    perror("realloc");
                    exit(0);
                }

                void *p_source = top()->basic_types.addr__;
                memcpy(p_target_address, p_source, size);

                pop();
                push(p_target_address);

                p_formal_type->array.element_count = num_of_elements;
                p_formal_type->array.max_index = num_of_elements;
                p_formal_type->size = size;
                p_formal_type->form = fc_array;
                p_formal_id->runstack_item = top();
            } else {

                // Range check an integer or enumeration
                // formal parameter.
                range_check(p_formal_type, top()->basic_types.int__);
                p_formal_id->runstack_item = top();
            }
        }
    }

    if (token == tc_left_paren) get_token();
}
Exemplo n.º 2
0
static void do_sham(const char *fn, const char *ndx,
                    const char *xpmP, const char *xpm, const char *xpm2,
                    const char *xpm3, const char *pdb,
                    const char *logf,
                    int n, int neig, real **eig,
                    gmx_bool bGE, int nenerT, real **enerT,
                    real Tref,
                    real pmax, real gmax,
                    real *emin, real *emax, int nlevels, real pmin,
                    int *idim, int *ibox,
                    gmx_bool bXmin, real *xmin, gmx_bool bXmax, real *xmax)
{
    FILE        *fp;
    real        *min_eig, *max_eig;
    real        *axis_x, *axis_y, *axis_z, *axis = NULL;
    double      *P;
    real       **PP, *W, *E, **WW, **EE, *S, **SS, *M, *bE;
    rvec         xxx;
    char        *buf;
    double      *bfac, efac, bref, Pmax, Wmin, Wmax, Winf, Emin, Emax, Einf, Smin, Smax, Sinf;
    real        *delta;
    int          i, j, k, imin, len, index, *nbin, *bindex, bi;
    int         *nxyz, maxbox;
    t_blocka    *b;
    gmx_bool     bOutside;
    unsigned int flags;
    t_rgb        rlo  = { 0, 0, 0 };
    t_rgb        rhi  = { 1, 1, 1 };

    /* Determine extremes for the eigenvectors */
    snew(min_eig, neig);
    snew(max_eig, neig);
    snew(nxyz, neig);
    snew(bfac, neig);
    snew(delta, neig);

    for (i = 0; (i < neig); i++)
    {
        /* Check for input constraints */
        min_eig[i] = max_eig[i] = eig[i][0];
        for (j = 0; (j < n); j++)
        {
            min_eig[i] = std::min(min_eig[i], eig[i][j]);
            max_eig[i] = std::max(max_eig[i], eig[i][j]);
            delta[i]   = (max_eig[i]-min_eig[i])/(2.0*ibox[i]);
        }
        /* Add some extra space, half a bin on each side, unless the
         * user has set the limits.
         */
        if (bXmax)
        {
            if (max_eig[i] > xmax[i])
            {
                gmx_warning("Your xmax[%d] value %f is smaller than the largest data point %f", i, xmax[i], max_eig[i]);
            }
            max_eig[i] = xmax[i];
        }
        else
        {
            max_eig[i] += delta[i];
        }

        if (bXmin)
        {
            if (min_eig[i] < xmin[i])
            {
                gmx_warning("Your xmin[%d] value %f is larger than the smallest data point %f", i, xmin[i], min_eig[i]);
            }
            min_eig[i] = xmin[i];
        }
        else
        {
            min_eig[i] -= delta[i];
        }
        bfac[i]     = ibox[i]/(max_eig[i]-min_eig[i]);
    }
    /* Do the binning */
    bref = 1/(BOLTZ*Tref);
    snew(bE, n);
    if (bGE || nenerT == 2)
    {
        assert(enerT);
        Emin = 1e8;
        for (j = 0; (j < n); j++)
        {
            if (bGE)
            {
                bE[j] = bref*enerT[0][j];
            }
            else
            {
                bE[j] = (bref - 1/(BOLTZ*enerT[1][j]))*enerT[0][j];
            }
            Emin  = std::min(Emin, static_cast<double>(bE[j]));
        }
    }
    else
    {
        Emin = 0;
    }
    len = 1;
    for (i = 0; (i < neig); i++)
    {
        len = len*ibox[i];
    }
    printf("There are %d bins in the %d-dimensional histogram. Beta-Emin = %g\n",
           len, neig, Emin);
    snew(P, len);
    snew(W, len);
    snew(E, len);
    snew(S, len);
    snew(M, len);
    snew(nbin, len);
    snew(bindex, n);


    /* Loop over projections */
    for (j = 0; (j < n); j++)
    {
        /* Loop over dimensions */
        bOutside = FALSE;
        for (i = 0; (i < neig); i++)
        {
            nxyz[i] = static_cast<int>(bfac[i]*(eig[i][j]-min_eig[i]));
            if (nxyz[i] < 0 || nxyz[i] >= ibox[i])
            {
                bOutside = TRUE;
            }
        }
        if (!bOutside)
        {
            index = indexn(neig, ibox, nxyz);
            range_check(index, 0, len);
            /* Compute the exponential factor */
            if (enerT)
            {
                efac = std::exp(-bE[j]+Emin);
            }
            else
            {
                efac = 1;
            }
            /* Apply the bin volume correction for a multi-dimensional distance */
            for (i = 0; i < neig; i++)
            {
                if (idim[i] == 2)
                {
                    efac /= eig[i][j];
                }
                else if (idim[i] == 3)
                {
                    efac /= gmx::square(eig[i][j]);
                }
                else if (idim[i] == -1)
                {
                    efac /= std::sin(DEG2RAD*eig[i][j]);
                }
            }
            /* Update the probability */
            P[index] += efac;
            /* Update the energy */
            if (enerT)
            {
                E[index] += enerT[0][j];
            }
            /* Statistics: which "structure" in which bin */
            nbin[index]++;
            bindex[j] = index;
        }
    }
    /* Normalize probability */
    normalize_p_e(len, P, nbin, E, pmin);
    Pmax = 0;
    /* Compute boundaries for the Free energy */
    Wmin = 1e8;
    imin = -1;
    Wmax = -1e8;
    /* Recompute Emin: it may have changed due to averaging */
    Emin = 1e8;
    Emax = -1e8;
    for (i = 0; (i < len); i++)
    {
        if (P[i] != 0)
        {
            Pmax = std::max(P[i], Pmax);
            W[i] = -BOLTZ*Tref*std::log(P[i]);
            if (W[i] < Wmin)
            {
                Wmin = W[i];
                imin = i;
            }
            Emin = std::min(static_cast<double>(E[i]), Emin);
            Emax = std::max(static_cast<double>(E[i]), Emax);
            Wmax = std::max(static_cast<double>(W[i]), Wmax);
        }
    }
    if (pmax > 0)
    {
        Pmax = pmax;
    }
    if (gmax > 0)
    {
        Wmax = gmax;
    }
    else
    {
        Wmax -= Wmin;
    }
    Winf = Wmax+1;
    Einf = Emax+1;
    Smin = Emin-Wmax;
    Smax = Emax-Smin;
    Sinf = Smax+1;
    /* Write out the free energy as a function of bin index */
    fp = gmx_ffopen(fn, "w");
    for (i = 0; (i < len); i++)
    {
        if (P[i] != 0)
        {
            W[i] -= Wmin;
            S[i]  = E[i]-W[i]-Smin;
            fprintf(fp, "%5d  %10.5e  %10.5e  %10.5e\n", i, W[i], E[i], S[i]);
        }
        else
        {
            W[i] = Winf;
            E[i] = Einf;
            S[i] = Sinf;
        }
    }
    gmx_ffclose(fp);
    /* Organize the structures in the bins */
    snew(b, 1);
    snew(b->index, len+1);
    snew(b->a, n);
    b->index[0] = 0;
    for (i = 0; (i < len); i++)
    {
        b->index[i+1] = b->index[i]+nbin[i];
        nbin[i]       = 0;
    }
    for (i = 0; (i < n); i++)
    {
        bi = bindex[i];
        b->a[b->index[bi]+nbin[bi]] = i;
        nbin[bi]++;
    }
    /* Consistency check */
    /* This no longer applies when we allow the plot to be smaller
       than the sampled space.
       for(i=0; (i<len); i++) {
       if (nbin[i] != (b->index[i+1] - b->index[i]))
        gmx_fatal(FARGS,"nbin[%d] = %d, should be %d",i,nbin[i],
          b->index[i+1] - b->index[i]);
       }
     */
    /* Write the index file */
    fp = gmx_ffopen(ndx, "w");
    for (i = 0; (i < len); i++)
    {
        if (nbin[i] > 0)
        {
            fprintf(fp, "[ %d ]\n", i);
            for (j = b->index[i]; (j < b->index[i+1]); j++)
            {
                fprintf(fp, "%d\n", b->a[j]+1);
            }
        }
    }
    gmx_ffclose(fp);
    snew(axis_x, ibox[0]+1);
    snew(axis_y, ibox[1]+1);
    snew(axis_z, ibox[2]+1);
    maxbox = std::max(ibox[0], std::max(ibox[1], ibox[2]));
    snew(PP, maxbox*maxbox);
    snew(WW, maxbox*maxbox);
    snew(EE, maxbox*maxbox);
    snew(SS, maxbox*maxbox);
    for (i = 0; (i < std::min(neig, 3)); i++)
    {
        switch (i)
        {
            case 0: axis = axis_x; break;
            case 1: axis = axis_y; break;
            case 2: axis = axis_z; break;
            default: break;
        }
        for (j = 0; j <= ibox[i]; j++)
        {
            axis[j] = min_eig[i] + j/bfac[i];
        }
    }

    pick_minima(logf, ibox, neig, len, W);
    if (gmax <= 0)
    {
        gmax = Winf;
    }
    flags = MAT_SPATIAL_X | MAT_SPATIAL_Y;
    if (neig == 2)
    {
        /* Dump to XPM file */
        snew(PP, ibox[0]);
        for (i = 0; (i < ibox[0]); i++)
        {
            snew(PP[i], ibox[1]);
            for (j = 0; j < ibox[1]; j++)
            {
                PP[i][j] = P[i*ibox[1]+j];
            }
            WW[i] = &(W[i*ibox[1]]);
            EE[i] = &(E[i*ibox[1]]);
            SS[i] = &(S[i*ibox[1]]);
        }
        fp = gmx_ffopen(xpmP, "w");
        write_xpm(fp, flags, "Probability Distribution", "", "PC1", "PC2",
                  ibox[0], ibox[1], axis_x, axis_y, PP, 0, Pmax, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
        fp = gmx_ffopen(xpm, "w");
        write_xpm(fp, flags, "Gibbs Energy Landscape", "G (kJ/mol)", "PC1", "PC2",
                  ibox[0], ibox[1], axis_x, axis_y, WW, 0, gmax, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
        fp = gmx_ffopen(xpm2, "w");
        write_xpm(fp, flags, "Enthalpy Landscape", "H (kJ/mol)", "PC1", "PC2",
                  ibox[0], ibox[1], axis_x, axis_y, EE,
                  emin ? *emin : Emin, emax ? *emax : Einf, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
        fp = gmx_ffopen(xpm3, "w");
        write_xpm(fp, flags, "Entropy Landscape", "TDS (kJ/mol)", "PC1", "PC2",
                  ibox[0], ibox[1], axis_x, axis_y, SS, 0, Sinf, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
    }
    else if (neig == 3)
    {
        /* Dump to PDB file */
        fp = gmx_ffopen(pdb, "w");
        for (i = 0; (i < ibox[0]); i++)
        {
            xxx[XX] = 3*(i+0.5-ibox[0]/2);
            for (j = 0; (j < ibox[1]); j++)
            {
                xxx[YY] = 3*(j+0.5-ibox[1]/2);
                for (k = 0; (k < ibox[2]); k++)
                {
                    xxx[ZZ] = 3*(k+0.5-ibox[2]/2);
                    index   = index3(ibox, i, j, k);
                    if (P[index] > 0)
                    {
                        fprintf(fp, "%-6s%5d  %-4.4s%3.3s  %4d    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
                                "ATOM", (index+1) %10000, "H", "H", (index+1)%10000,
                                xxx[XX], xxx[YY], xxx[ZZ], 1.0, W[index]);
                    }
                }
            }
        }
        gmx_ffclose(fp);
        write_xplor("out.xplor", W, ibox, min_eig, max_eig);
        nxyz[XX] = imin/(ibox[1]*ibox[2]);
        nxyz[YY] = (imin-nxyz[XX]*ibox[1]*ibox[2])/ibox[2];
        nxyz[ZZ] = imin % ibox[2];
        for (i = 0; (i < ibox[0]); i++)
        {
            snew(WW[i], maxbox);
            for (j = 0; (j < ibox[1]); j++)
            {
                WW[i][j] = W[index3(ibox, i, j, nxyz[ZZ])];
            }
        }
        snew(buf, std::strlen(xpm)+4);
        sprintf(buf, "%s", xpm);
        sprintf(&buf[std::strlen(xpm)-4], "12.xpm");
        fp = gmx_ffopen(buf, "w");
        write_xpm(fp, flags, "Gibbs Energy Landscape", "W (kJ/mol)", "PC1", "PC2",
                  ibox[0], ibox[1], axis_x, axis_y, WW, 0, gmax, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
        for (i = 0; (i < ibox[0]); i++)
        {
            for (j = 0; (j < ibox[2]); j++)
            {
                WW[i][j] = W[index3(ibox, i, nxyz[YY], j)];
            }
        }
        sprintf(&buf[std::strlen(xpm)-4], "13.xpm");
        fp = gmx_ffopen(buf, "w");
        write_xpm(fp, flags, "SHAM Energy Landscape", "kJ/mol", "PC1", "PC3",
                  ibox[0], ibox[2], axis_x, axis_z, WW, 0, gmax, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
        for (i = 0; (i < ibox[1]); i++)
        {
            for (j = 0; (j < ibox[2]); j++)
            {
                WW[i][j] = W[index3(ibox, nxyz[XX], i, j)];
            }
        }
        sprintf(&buf[std::strlen(xpm)-4], "23.xpm");
        fp = gmx_ffopen(buf, "w");
        write_xpm(fp, flags, "SHAM Energy Landscape", "kJ/mol", "PC2", "PC3",
                  ibox[1], ibox[2], axis_y, axis_z, WW, 0, gmax, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
        sfree(buf);
    }
}