Exemple #1
0
/*--------------------------------------------------------------------------*/
SciErr getVarDimension(void *_pvCtx, int *_piAddress, int *_piRows, int *_piCols)
{
    SciErr sciErr;
    sciErr.iErr = 0;
    sciErr.iMsgCount = 0;

    if (_piAddress != NULL && isVarMatrixType(_pvCtx, _piAddress))
    {
        *_piRows = _piAddress[1];
        *_piCols = _piAddress[2];
    }
    else
    {
        *_piRows = 0;
        *_piCols = 0;
        if (_piAddress == NULL)
        {
            addErrorMessage(&sciErr, API_ERROR_INVALID_POINTER, _("%s: Invalid argument address"), "getVarDimension");
        }
        else
        {
            addErrorMessage(&sciErr, API_ERROR_NOT_MATRIX_TYPE, _("%s: matrix argument excepted"), "getVarDimension");
        }
    }
    return sciErr;
}
Exemple #2
0
/*--------------------------------------------------------------------------*/
int isColumnVector(void *_pvCtx, int *_piAddress)
{
    SciErr sciErr;
    sciErr.iErr = 0;
    sciErr.iMsgCount = 0;
    int iRows = 0;
    int iCols = 0;

    if (_piAddress == NULL)
    {
        return 0;
    }

    if (isVarMatrixType(_pvCtx, _piAddress) == 0)
    {
        return 0;
    }

    sciErr = getVarDimension(_pvCtx, _piAddress, &iRows, &iCols);
    if (sciErr.iErr)
    {
        addErrorMessage(&sciErr, API_ERROR_IS_COLUMN_VECTOR, _("%s: Unable to get argument dimension"), "isColumnVector");
        printError(&sciErr, 0);
        return 0;
    }

    if (iCols == 1 && iRows > 1)
    {
        return 1;
    }

    return 0;
}
Exemple #3
0
/*--------------------------------------------------------------------------*/
int checkVarDimension(void *_pvCtx, int *_piAddress, int _iRows, int _iCols)
{
    SciErr sciErr;
    sciErr.iErr = 0;
    sciErr.iMsgCount = 0;
    int iRows = 0;
    int iCols = 0;

    if (_piAddress == NULL)
    {
        return 0;
    }

    if (isVarMatrixType(_pvCtx, _piAddress) == 0)
    {
        return 0;
    }

    sciErr = getVarDimension(_pvCtx, _piAddress, &iRows, &iCols);
    if (sciErr.iErr)
    {
        addErrorMessage(&sciErr, API_ERROR_CHECK_VAR_DIMENSION, _("%s: Unable to get argument dimension"), "checkVarDimension");
        printError(&sciErr, 0);
        return 0;
    }

    if ((_iRows == iRows || _iRows == -1) && (_iCols == iCols || _iCols == -1))
    {
        return 1;
    }

    return 0;
}
Exemple #4
0
/*--------------------------------------------------------------------------*/
int isSquareMatrix(void *_pvCtx, int *_piAddress)
{
    SciErr sciErr;
    sciErr.iErr = 0;
    sciErr.iMsgCount = 0;
    int iRows = 0;
    int iCols = 0;

    if (_piAddress == NULL)
    {
        return 0;
    }

    if (isVarMatrixType(_pvCtx, _piAddress) == 0)
    {
        return 0;
    }

    sciErr = getVarDimension(_pvCtx, _piAddress, &iRows, &iCols);
    if (sciErr.iErr)
    {
        addErrorMessage(&sciErr, API_ERROR_IS_SQUARE, _("%s: Unable to get argument dimension"), "isSquareMatrix");
        printError(&sciErr, 0);
        return 0;
    }

    if (iRows > 1 && iCols == iRows)
    {
        return 1;
    }

    return 0;
}
Exemple #5
0
/*--------------------------------------------------------------------------*/
int isScalar(void *_pvCtx, int *_piAddress)
{
    int iRows = 0;
    int iCols = 0;

    if (_piAddress == NULL)
    {
        return 0;
    }

    if (isVarMatrixType(_pvCtx, _piAddress) == 0)
    {
        return 0;
    }

    SciErr sciErr = getVarDimension(_pvCtx, _piAddress, &iRows, &iCols);
    if (sciErr.iErr)
    {
        addErrorMessage(&sciErr, API_ERROR_IS_SCALAR, _("%s: Unable to get argument dimension"), "isScalar");
        printError(&sciErr, 0);
        return 0;
    }

    if (iCols == 1 && iRows == 1)
    {
        return 1;
    }

    return 0;
}
Exemple #6
0
/*--------------------------------------------------------------------------*/
int isNamedVarMatrixType(void *_pvCtx, const char *_pstName)
{
    int *piAddr = NULL;

    SciErr sciErr = getVarAddressFromName(_pvCtx, _pstName, &piAddr);
    if (sciErr.iErr)
    {
        return 0;
    }
    return isVarMatrixType(_pvCtx, piAddr);
}
Exemple #7
0
int sci_fft_4args(void* _pvCtx, char *fname, int ndimsA, int *dimsA, double *Ar,  double *Ai, int isn, int iopt)
{
    /* API variables */
    SciErr sciErr;
    int *piAddr = NULL;

    /* Input  array variables */
    int *Dim1 = NULL;
    int ndims = 0;
    int *Incr = NULL;
    int nincr = 0;

    /*FFTW specific library variable */
    guru_dim_struct gdim = {0, NULL, 0, NULL};
    /* input/output address for transform variables */

    /* local variable */
    int *Dim = NULL, *Sel = NULL;
    int pd = 1;
    int pds = 1;
    int nd = 0;
    int rank = 0;
    int i = 0, j = 0, k = 0, lA = 1;

    for (i = 0; i < ndimsA; i++)
    {
        lA *= dimsA[i];
    }

    /* void or scalar input gives void output or scalar*/
    if (lA <= 1 )
    {
        AssignOutputVariable(_pvCtx, 1) =  1;
        ReturnArguments(_pvCtx);
        return 0;
    }

    /******************** get and check third argument (dim) ****************************************/
    getVarAddressFromPosition(pvApiCtx, 3, &piAddr);
    if (isVarMatrixType(pvApiCtx, piAddr) == 0)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d.\n"), fname, 3);
        FREE(Dim1);
        FREE(Incr);
        FREE(Dim);
        FREE(Sel);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }
    sciErr = getVectorIntArg(pvApiCtx, 3, fname, &ndims, &Dim1);
    if (sciErr.iErr)
    {
        Scierror(sciErr.iErr, getErrorMessage(sciErr));
        FREE(Dim1);
        FREE(Incr);
        FREE(Dim);
        FREE(Sel);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }
    /* check values of Dim1[i] */
    pd = 1;
    for (i = 0; i < ndims; i++)
    {
        if (Dim1[i] <= 1)
        {
            Scierror(999, _("%s: Wrong values for input argument #%d: Elements must be greater than %d.\n"), fname, 3, 1);
            FREE(Dim1);
            FREE(Incr);
            FREE(Dim);
            FREE(Sel);
            FREE(gdim.dims);
            FREE(gdim.howmany_dims);
            return 0;
        }
        pd *= Dim1[i];
    }
    if ( pd > lA)
    {
        Scierror(999, _("%s: Wrong values for input argument #%d: Must be less than %d.\n"), fname, 3, lA);
        FREE(Dim1);
        FREE(Incr);
        FREE(Dim);
        FREE(Sel);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }
    if (lA % pd)
    {
        Scierror(999, _("%s: Wrong values for input argument #%d: Must be a divisor of %d.\n"), fname, 3, lA);
        FREE(Dim1);
        FREE(Incr);
        FREE(Dim);
        FREE(Sel);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }
    /******************** get and check fourth argument (incr) ****************************************/
    sciErr = getVectorIntArg(pvApiCtx, 4, fname, &nincr, &Incr);
    if (sciErr.iErr)
    {
        Scierror(sciErr.iErr, getErrorMessage(sciErr));
        FREE(Dim1);
        FREE(Incr);
        FREE(Dim);
        FREE(Sel);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }
    if (nincr != ndims)
    {
        Scierror(999, _("%s: Incompatible input arguments #%d and #%d: Same sizes expected.\n"), fname, 3, 4);
        FREE(Dim1);
        FREE(Incr);
        FREE(Dim);
        FREE(Sel);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }

    /* check values of Incr[i] */
    if (Incr[0] <= 0)
    {
        Scierror(999, _("%s: Wrong values for input argument #%d: Positive integers expected.\n"), fname, 4);
        FREE(Dim1);
        FREE(Incr);
        FREE(Dim);
        FREE(Sel);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }
    for (i = 0; i < ndims; i++)
    {
        if (lA % Incr[i])
        {
            Scierror(999, _("%s: Wrong values for input argument #%d: Elements must be divisors of %d.\n"), fname, 3, lA);
            FREE(Dim1);
            FREE(Incr);
            FREE(Dim);
            FREE(Sel);
            FREE(gdim.dims);
            FREE(gdim.howmany_dims);
            return 0;
        }
        if (i > 0 && (Incr[i] <= Incr[i - 1]))
        {
            Scierror(999, _("%s: Wrong values for input argument #%d: Elements must be in increasing ""order.\n"), fname, 4);
            FREE(Dim1);
            FREE(Incr);
            FREE(Dim);
            FREE(Sel);
            FREE(gdim.dims);
            FREE(gdim.howmany_dims);
            return 0;
        }
    }
    if ((Dim = (int *)MALLOC((2 * ndims + 1) * sizeof(int))) == NULL)
    {
        Scierror(999, _("%s: Cannot allocate more memory.\n"), fname);
        FREE(Dim1);
        FREE(Incr);
        FREE(Dim);
        FREE(Sel);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }
    if ((Sel = (int *)MALLOC((ndims) * sizeof(int))) == NULL)
    {
        Scierror(999, _("%s: Cannot allocate more memory.\n"), fname);
        FREE(Dim1);
        FREE(Incr);
        FREE(Dim);
        FREE(Sel);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }


    /*Transform  Dim1 and Incr into Dim and Sel and check validity*/

    nd = 0;
    pd = 1;
    if (Incr[0] != 1)
    {
        Dim[nd++] = Incr[0];
        pd *= Incr[0];
    }
    Dim[nd++] = Dim1[0];
    pd *= Dim1[0];
    Sel[0] = nd;

    for (k = 1; k < ndims; k++)
    {
        if (Incr[k] % pd != 0)
        {
            Scierror(999, _("%s: Incompatible input arguments #%d and #%d.\n"), fname, 3, 4);
            FREE(Dim1);
            FREE(Incr);
            FREE(Dim);
            FREE(Sel);
            FREE(gdim.dims);
            FREE(gdim.howmany_dims);
            return 0;
        }
        if (Incr[k] != pd)
        {
            Dim[nd++] = (int)(Incr[k] / pd);
            pd = Incr[k];
        }
        Dim[nd++] = Dim1[k];
        pd *= Dim1[k];
        Sel[k] = nd;
    }
    if (pd < lA)
    {
        if (lA % pd != 0)
        {
            Scierror(999, _("%s: Incompatible input arguments #%d and #%d.\n"), fname, 3, 4);
            FREE(Dim1);
            FREE(Incr);
            FREE(Dim);
            FREE(Sel);
            FREE(gdim.dims);
            FREE(gdim.howmany_dims);
            return 0;
        }
        Dim[nd++] = (int)(lA / pd);
    }

    rank = ndims;
    ndims = nd;

    /* now one  same algorithm than sci_fft_3args applies */
    /* Create  gdim struct */
    gdim.rank = rank;
    if ((gdim.dims = (fftw_iodim *)MALLOC(sizeof(fftw_iodim) * gdim.rank)) == NULL)
    {
        Scierror(999, _("%s: Cannot allocate more memory.\n"), fname);
        FREE(Dim1);
        FREE(Incr);
        FREE(Dim);
        FREE(Sel);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }

    pd = 1; /* used to store prod(Dims(1:sel(k-1)))*/
    pds = 1; /* used to store prod(Dims(sel(k-1):sel(k)))*/
    j = 0;
    for (i = 0; i < ndims; i++)
    {
        if (j >= gdim.rank) break;
        if (Sel[j] == i + 1)
        {
            gdim.dims[j].n = Dim[i];
            gdim.dims[j].is = pd;
            gdim.dims[j].os = pd;
            j++;
        }
        pd *= Dim[i];
    }
    /* Compute howmany_rank based on jumps in the Sel sequence */
    gdim.howmany_rank = 0;
    if ((Sel[0] != 1) && (Sel[0] != ndims)) gdim.howmany_rank++;

    for (i = 1; i <= rank - 1; i++)
    {
        if (Sel[i] != Sel[i - 1] + 1) gdim.howmany_rank++;
    }
    if ((Sel[rank - 1] != ndims) || (rank == 1)) gdim.howmany_rank++;
    /* Fill the howmany_dims struct */
    if (gdim.howmany_rank > 0)
    {
        /* it must be the case */
        int ih = 0;

        if ((gdim.howmany_dims = (fftw_iodim *)MALLOC(gdim.howmany_rank * sizeof(fftw_iodim))) == NULL)
        {
            Scierror(999, _("%s: Cannot allocate more memory.\n"), fname);
            FREE(Dim1);
            FREE(Incr);
            FREE(Dim);
            FREE(Sel);
            FREE(gdim.dims);
            FREE(gdim.howmany_dims);
            return 0;
        }
        pd = 1;
        for (j = 1; j <= (Sel[0] - 1); j++) pd *= Dim[j - 1]; /*prod(Dims(1:(sel(1)-1)))*/
        ih = 0;
        if ((Sel[0] != 1) && (Sel[0] != ndims))
        {
            /* First seleted dimension */
            gdim.howmany_dims[ih].is = 1;
            gdim.howmany_dims[ih].os = 1;
            gdim.howmany_dims[ih].n = pd;
            ih++;
        }
        pd *= Dim[Sel[0] - 1]; /*prod(Dims(1:sel(1)))*/
        for (i = 2; i <= rank; i++)
        {
            /* intermediate selected dimensions */
            if (Sel[i - 1] != Sel[i - 2] + 1)
            {
                pds = 1;
                for (j = (Sel[i - 2] + 1); j <= (Sel[i - 1] - 1); j++) pds *= Dim[j - 1]; /*prod(Dims(sel(i-1)+1:(sel(i)-1)))*/
                gdim.howmany_dims[ih].is = pd;
                gdim.howmany_dims[ih].os = pd;
                gdim.howmany_dims[ih].n = pds;
                ih++;
            }
            pd *= pds * Dim[Sel[i - 1] - 1]; /*prod(Dims(1:sel(i)))*/
        }

        if (Sel[rank - 1] != ndims)
        {
            /* last selected dimension*/
            pds = 1;
            for (j = (Sel[rank - 1] + 1); j <= ndims; j++) pds *= Dim[j - 1]; /*prod(Dims(sel(i-1)+1:(sel(i)-1)))*/
            gdim.howmany_dims[ih].is = pd;
            gdim.howmany_dims[ih].os = pd;
            gdim.howmany_dims[ih].n = pds;
            ih++;
        }
        else if (rank == 1) /* the only selected dimension is the last one */
        {
            gdim.howmany_dims[ih].is = 1;
            gdim.howmany_dims[ih].os = 1;
            gdim.howmany_dims[ih].n = pd / Dim[Sel[0] - 1];
            ih++;
        }
    }
    if (!sci_fft_gen(_pvCtx, fname, ndimsA, dimsA, Ar,  Ai, isn, iopt, gdim))
    {
        FREE(Dim1);
        FREE(Incr);
        FREE(Dim);
        FREE(Sel);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }

    /***********************************
    * Return results in lhs argument *
    ***********************************/

    FREE(Dim1);
    FREE(Incr);
    FREE(Dim);
    FREE(Sel);
    FREE(gdim.dims);
    FREE(gdim.howmany_dims);

    ReturnArguments(_pvCtx);

    return 0;
}
Exemple #8
0
int  sci_fft_3args(void* _pvCtx, char *fname, int ndimsA, int *dimsA, double *Ar,  double *Ai, int isn, int iopt)
{
    /* API variables */
    SciErr sciErr;
    int *piAddr = NULL;

    int *Sel = NULL;
    int rank = 0;

    /*FFTW specific library variable */
    guru_dim_struct gdim = {0, NULL, 0, NULL};
    /* local variable */
    int ndims = 0;
    int first_nonsingleton = -1;
    int ih = 0;
    int pd = 1; /* used to store prod(Dims(1:sel(k-1)))*/
    int pds = 1; /* used to store prod(Dims(sel(k-1):sel(k)))*/
    int i = 0, j = 0;

    /* ignore singleton dimensions */
    first_nonsingleton = -1;
    ndims = 0;
    for (i = 0; i < ndimsA; i++)
    {
        if (dimsA[i] > 1)
        {
            ndims++;
            if (first_nonsingleton < 0) first_nonsingleton = i;
        }
    }

    /* void or scalar input gives void output or scalar*/
    if (ndims == 0 )
    {
        AssignOutputVariable(_pvCtx, 1) =  1;
        ReturnArguments(_pvCtx);
        return 0;
    }


    /******************** get and check third argument (sel) ****************************************/
    getVarAddressFromPosition(pvApiCtx, 3, &piAddr);
    if (isVarMatrixType(pvApiCtx, piAddr) == 0)
    {
        Scierror(999, _("%s: Wrong type for input argument #%d.\n"), fname, 3);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }
    sciErr = getVectorIntArg(pvApiCtx, 3, fname, &rank, &Sel);
    if (sciErr.iErr)
    {
        Scierror(sciErr.iErr, getErrorMessage(sciErr));
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }
    /* size of Sel must be less than ndimsA */
    if (rank <= 0 || rank >= ndimsA)
    {
        Scierror(999, _("%s: Wrong size for input argument #%d: Must be between %d and %d.\n"), fname, 3, 1, ndimsA - 1);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }
    /* check values of Sel[i] */
    for (i = 0; i < rank; i++)
    {
        if (Sel[i] <= 0)
        {
            Scierror(999, _("%s: Wrong values for input argument #%d: Positive integers expected.\n"), fname, 3);
            FREE(gdim.dims);
            FREE(gdim.howmany_dims);
            return 0;
        }
        if (Sel[i] > ndimsA)
        {
            Scierror(999, _("%s: Wrong values for input argument #%d: Elements must be less than %d.\n"), fname, 3, ndimsA);
            FREE(gdim.dims);
            FREE(gdim.howmany_dims);
            return 0;
        }
        if (i > 0 && Sel[i] <= Sel[i - 1])
        {
            Scierror(999, _("%s: Wrong values for input argument #%d: Elements must be in increasing order.\n"), fname, 3);
            FREE(gdim.dims);
            FREE(gdim.howmany_dims);
            return 0;
        }
    }

    /* Create  gdim struct */
    gdim.rank = rank;
    if ((gdim.dims = (fftw_iodim *)MALLOC(sizeof(fftw_iodim) * gdim.rank)) == NULL)
    {
        Scierror(999, _("%s: Cannot allocate more memory.\n"), fname);
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }

    pd = 1; /* used to store prod(Dims(1:sel(k-1)))*/
    pds = 1; /* used to store prod(Dims(sel(k-1):sel(k)))*/
    j = 0;
    for (i = 0; i < ndimsA; i++)
    {
        if (j >= gdim.rank) break;
        if (Sel[j] == i + 1)
        {
            gdim.dims[j].n = dimsA[i];
            gdim.dims[j].is = pd;
            gdim.dims[j].os = pd;
            j++;
        }
        pd *= dimsA[i];
    }
    /* Compute howmany_rank based on jumps in the Sel sequence */
    gdim.howmany_rank = 0;
    if ((Sel[0] != 1) && (Sel[0] != ndimsA)) gdim.howmany_rank++;

    for (i = 1; i <= rank - 1; i++)
      {
        if (Sel[i] != Sel[i-1] + 1)
          {
            /*check if all dimensions between Sel[i-1]+1 and Sel[i]-1 are
              equal to one, in this case they can be ignored and there is
              no jump*/
            for (j = Sel[i - 1] + 1; j <= Sel[i] - 1; j++)
              {
                if (dimsA[j - 1] != 1)
                  {
                    gdim.howmany_rank++;
                    break;
                  }
              }
          }
      }

    if ((Sel[rank - 1] != ndimsA) || (rank == 1)) gdim.howmany_rank++;

    /* Fill the howmany_dims struct */
    if (gdim.howmany_rank > 0)
    {
        /* it must be the case */
        if ((gdim.howmany_dims = (fftw_iodim *)MALLOC(gdim.howmany_rank * sizeof(fftw_iodim))) == NULL)
        {
            Scierror(999, _("%s: Cannot allocate more memory.\n"), fname);
            FREE(gdim.dims);
            FREE(gdim.howmany_dims);
            return 0;
        }
        pd = 1;
        for (j = 1; j <= (Sel[0] - 1); j++) pd *= dimsA[j - 1]; /*prod(Dims(1:(sel(1)-1)))*/
        ih = 0;
        if ((Sel[0] != 1) && (Sel[0] != ndimsA))
        {
            /* First seleted dimension */
            gdim.howmany_dims[ih].is = 1;
            gdim.howmany_dims[ih].os = 1;
            gdim.howmany_dims[ih].n = pd;
            ih++;
        }
        pd *= dimsA[Sel[0] - 1]; /*prod(Dims(1:sel(1)))*/
        for (i = 1; i <= rank -1; i++)
          {
            /* intermediate selected dimensions */
            if (Sel[i] != Sel[i - 1] + 1)
              {
                pds = 1;
                for (j = (Sel[i - 1] + 1); j <= (Sel[i] - 1); j++) pds *= dimsA[j - 1]; /*prod(Dims(sel(i-1)+1:(sel(i)-1)))*/
                /*check again if all dimensions between Sel[i-1]+1 and
                  Sel[i]-1 are equal to one, in this case they can be
                  ignored and there is no jump*/
                for (j = (Sel[i - 1] + 1); j <= (Sel[i] - 1); j++)
                  {
                    if (dimsA[j - 1] != 1)
                      {
                        gdim.howmany_dims[ih].is = pd;
                        gdim.howmany_dims[ih].os = pd;
                        gdim.howmany_dims[ih].n = pds;
                        ih++;
                        break;
                      }
                  }
              }
            pd *= pds * dimsA[Sel[i] - 1]; /*prod(Dims(1:sel(i)))*/
          }

        if (Sel[rank - 1] != ndimsA)
        {
            /* last selected dimension*/
            pds = 1;
            for (j = (Sel[rank - 1] + 1); j <= ndimsA; j++) pds *= dimsA[j - 1]; /*prod(Dims(sel(i-1)+1:(sel(i)-1)))*/
            gdim.howmany_dims[ih].is = pd;
            gdim.howmany_dims[ih].os = pd;
            gdim.howmany_dims[ih].n = pds;
            ih++;
        }
        else if (rank == 1)
        {
            /* the only selected dimension is the last one */
            gdim.howmany_dims[ih].is = 1;
            gdim.howmany_dims[ih].os = 1;
            gdim.howmany_dims[ih].n = pd / dimsA[Sel[0] - 1];
            ih++;
        }
    }

    if (!sci_fft_gen(_pvCtx, fname, ndimsA, dimsA, Ar,  Ai, isn, iopt, gdim))
    {
        FREE(gdim.dims);
        FREE(gdim.howmany_dims);
        return 0;
    }

    /***********************************
    * Return results in lhs argument *
    ***********************************/

    ReturnArguments(_pvCtx);

    FREE(gdim.dims);
    FREE(gdim.howmany_dims);
    return 0;
}
/*--------------------------------------------------------------------------*/
int sci_figure(char * fname, void* pvApiCtx)
{
    SciErr sciErr;
    int* piAddr = NULL;
    int iFig = 0;
    int iRhs = nbInputArgument(pvApiCtx);
    int iId = 0;
    int iPos = 0;
    int i = 0;
    int iAxes = 0;
    int iPropertyOffset = 0;
    BOOL bDoCreation = TRUE;
    BOOL bVisible = TRUE; // Create a visible figure by default
    BOOL bDockable = TRUE; // Create a dockable figure by default
    BOOL bDefaultAxes = TRUE; // Create an Axes by default
    double* figureSize = NULL;
    double* axesSize = NULL;
    double* position = NULL;
    double val[4];
    BOOL bMenuBar = TRUE;
    BOOL bToolBar = TRUE;
    BOOL bInfoBar = TRUE;
    BOOL bResize = TRUE;
    int iMenubarType = 1; // Create a 'figure' menubar by default
    int iToolbarType = 1; // Create a 'figure' toolbar by default
    double dblId = 0;
    BOOL status = FALSE;

    //figure(num) -> scf(num)
    //figure() -> scf()

    //figure(x, "...", ...)

    // figure()
    if (iRhs == 0) // Auto ID
    {
        iId = getValidDefaultFigureId();
        iFig = createNewFigureWithAxes();
        setGraphicObjectProperty(iFig, __GO_ID__, &iId, jni_int,  1);
        iAxes = setDefaultProperties(iFig, TRUE);
        initBar(iFig, bMenuBar, bToolBar, bInfoBar);
        createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
        AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
        ReturnArguments(pvApiCtx);
        return 0;
    }

    if (iRhs == 1)
    {
        //figure(x);
        sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
        if (sciErr.iErr)
        {
            printError(&sciErr, 0);
            Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
            return 0;
        }

        if (isVarMatrixType(pvApiCtx, piAddr) == 0)
        {
            Scierror(999, _("%s: Wrong type for input argument #%d: An integer value expected.\n"), fname, 1);
            return 0;
        }

        if (getScalarDouble(pvApiCtx, piAddr, &dblId))
        {
            Scierror(999, _("%s: No more memory.\n"), fname);
            return 0;
        }

        iId = (int)(dblId + 0.5); //avoid 1.999 -> 1

        //get current fig from id
        iFig = getFigureFromIndex(iId);
        if (iFig == 0) // Figure does not exists, create a new one
        {
            iFig = createNewFigureWithAxes();
            setGraphicObjectProperty(iFig, __GO_ID__, &iId, jni_int,  1);
            iAxes = setDefaultProperties(iFig, TRUE);
        }

        initBar(iFig, bMenuBar, bToolBar, bInfoBar);
        createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
        AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
        ReturnArguments(pvApiCtx);
        return 0;
    }

    // Prepare property analysis
    if (iRhs % 2 == 0)
    {
        //get highest value of winsid to create the new windows @ + 1
        iId = getValidDefaultFigureId();
        iPos = 0;
    }
    else
    {
        iPos = 1;
        //figure(x, ...);
        sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
        if (sciErr.iErr)
        {
            printError(&sciErr, 0);
            Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
            return 0;
        }

        if (isVarMatrixType(pvApiCtx, piAddr) == 0)
        {
            Scierror(999, _("%s: Wrong type for input argument #%d: An integer value expected.\n"), fname, 1);
            return 0;
        }

        if (getScalarDouble(pvApiCtx, piAddr, &dblId))
        {
            Scierror(999, _("%s: No more memory.\n"), fname);
            return 0;
        }

        iId = (int)(dblId + 0.5); //avoid 1.999 -> 1
        //get current fig from id
        iFig = getFigureFromIndex(iId);
        if (iFig != 0) // Figure already exists
        {
            bDoCreation = FALSE;
        }
    }

    if (bDoCreation)
    {
        int* piAddrProp = NULL;
        char* pstProName = NULL;
        int* piAddrData = NULL;
        for (i = iPos + 1 ; i <= iRhs ; i += 2)
        {
            //get property name
            sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddrProp);
            if (sciErr.iErr)
            {
                Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i);
                return 1;
            }

            if (getAllocatedSingleString(pvApiCtx, piAddrProp, &pstProName))
            {
                Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
                return 1;
            }

            if (stricmp(pstProName, "dockable") != 0 &&
                    stricmp(pstProName, "toolbar") != 0 &&
                    stricmp(pstProName, "menubar") != 0 &&
                    stricmp(pstProName, "default_axes") != 0 &&
                    stricmp(pstProName, "visible") != 0 &&
                    stricmp(pstProName, "figure_size") != 0 &&
                    stricmp(pstProName, "axes_size") != 0 &&
                    stricmp(pstProName, "position") != 0 &&
                    stricmp(pstProName, "menubar_visible") != 0 &&
                    stricmp(pstProName, "toolbar_visible") != 0 &&
                    stricmp(pstProName, "resize") != 0 &&
                    stricmp(pstProName, "infobar_visible") != 0)
            {
                freeAllocatedSingleString(pstProName);
                continue;
            }

            //get address of value on stack
            sciErr = getVarAddressFromPosition(pvApiCtx, i + 1, &piAddrData);
            if (sciErr.iErr)
            {
                Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i + 1);
                freeAllocatedSingleString(pstProName);
                return 1;
            }

            //check property value to compatibility
            if (stricmp(pstProName, "dockable") == 0)
            {
                bDockable = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
                if (bDockable == -1)
                {
                    Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "dockable", "on", "off");
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }
            }
            else if (stricmp(pstProName, "toolbar") == 0)
            {
                char* pstVal = NULL;
                if (isStringType(pvApiCtx, piAddrData) == FALSE || isScalar(pvApiCtx, piAddrData) == FALSE)
                {
                    Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
                    freeAllocatedSingleString(pstProName);
                }

                if (getAllocatedSingleString(pvApiCtx, piAddrData, &pstVal))
                {
                    Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i + 1);
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }

                if (stricmp(pstVal, "none") == 0)
                {
                    iToolbarType = 0;
                }
                else if (stricmp(pstVal, "figure") == 0)
                {
                    iToolbarType = 1;
                }
                else
                {
                    Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "toolbar", "none", "figure");
                    freeAllocatedSingleString(pstProName);
                    freeAllocatedSingleString(pstVal);
                    return 1;
                }

                freeAllocatedSingleString(pstVal);
            }
            else if (stricmp(pstProName, "menubar") == 0)
            {
                char* pstVal = NULL;
                if (isStringType(pvApiCtx, piAddrData) == FALSE || isScalar(pvApiCtx, piAddrData) == FALSE)
                {
                    Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i + 1);
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }

                if (getAllocatedSingleString(pvApiCtx, piAddrData, &pstVal))
                {
                    Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i + 1);
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }

                if (stricmp(pstVal, "none") == 0)
                {
                    iMenubarType = 0;
                }
                else if (stricmp(pstVal, "figure") == 0)
                {
                    iMenubarType = 1;
                }
                else
                {
                    Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "menubar", "none", "figure");
                    freeAllocatedSingleString(pstProName);
                    freeAllocatedSingleString(pstVal);
                    return 1;
                }

                freeAllocatedSingleString(pstVal);
            }
            else if (stricmp(pstProName, "default_axes") == 0)
            {
                bDefaultAxes = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
                if (bDefaultAxes == -1)
                {
                    Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "default_axes", "on", "off");
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }
            }
            else if (stricmp(pstProName, "visible") == 0)
            {
                bVisible = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
                if (bVisible == -1)
                {
                    Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "visible", "on", "off");
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }
            }
            else if (stricmp(pstProName, "figure_size") == 0)
            {
                int iRows = 0;
                int iCols = 0;
                if (isDoubleType(pvApiCtx, piAddrData) == FALSE)
                {
                    Scierror(999, _("%s: Wrong type for input argument #%d: A double vector expected.\n"), fname, i + 1);
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }

                getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, &figureSize);
                if (iRows * iCols != 2)
                {
                    Scierror(999, _("Wrong size for '%s' property: %d elements expected.\n"), "figure_size", 2);
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }
            }
            else if (stricmp(pstProName, "axes_size") == 0)
            {
                int iRows = 0;
                int iCols = 0;
                if (isDoubleType(pvApiCtx, piAddrData) == FALSE)
                {
                    Scierror(999, _("%s: Wrong type for input argument #%d: A double vector expected.\n"), fname, i + 1);
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }

                getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, &axesSize);
                if (iRows * iCols != 2)
                {
                    Scierror(999, _("Wrong size for '%s' property: %d elements expected.\n"), "axes_size", 2);
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }
            }
            else if (stricmp(pstProName, "position") == 0)
            {
                int iRows = 0;
                int iCols = 0;
                double* pdbl = NULL;
                if (isDoubleType(pvApiCtx, piAddrData))
                {
                    getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, &pdbl);
                    if (iRows * iCols != 4)
                    {
                        Scierror(999, _("Wrong size for '%s' property: %d elements expected.\n"), "position", 4);
                        freeAllocatedSingleString(pstProName);
                        return 1;
                    }

                    position = pdbl;
                    axesSize = (pdbl + 2);
                }
                else if (isStringType(pvApiCtx, piAddrData) && isScalar(pvApiCtx, piAddrData))
                {
                    char* pstVal = NULL;
                    int iVal = 0;

                    if (getAllocatedSingleString(pvApiCtx, piAddrData, &pstVal))
                    {
                        Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i + 1);
                        freeAllocatedSingleString(pstProName);
                        return 1;
                    }

                    iVal = sscanf(pstVal, "%lf|%lf|%lf|%lf", &val[0], &val[1], &val[2], &val[3]);
                    freeAllocatedSingleString(pstVal);
                    if (iVal != 4)
                    {
                        Scierror(999, _("Wrong value for '%s' property: string or 1 x %d real row vector expected.\n"), "position", 4);
                        freeAllocatedSingleString(pstProName);
                        return 1;
                    }

                    position = val;
                    axesSize = (val + 2);
                }
                else
                {
                    Scierror(999, _("Wrong value for '%s' property: string or 1 x %d real row vector expected.\n"), "position", 4);
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }
            }
            else if (stricmp(pstProName, "resize") == 0)
            {
                bResize = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
                if (bResize == -1)
                {
                    Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "resize", "on", "off");
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }
            }
            else if (stricmp(pstProName, "menubar_visible") == 0)
            {
                bMenuBar = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
                if (bMenuBar == -1)
                {
                    Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "menubar_visible", "on", "off");
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }
            }
            else if (stricmp(pstProName, "toolbar_visible") == 0)
            {
                bToolBar = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
                if (bToolBar == -1)
                {
                    Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "toolbar_visible", "on", "off");
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }
            }
            else if (stricmp(pstProName, "infobar_visible") == 0)
            {
                bInfoBar = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
                if (bInfoBar == -1)
                {
                    Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "infobar_visible", "on", "off");
                    freeAllocatedSingleString(pstProName);
                    return 1;
                }
            }
            freeAllocatedSingleString(pstProName);
        }

        iFig = createFigure(bDockable, iMenubarType, iToolbarType, bDefaultAxes, bVisible);
        setGraphicObjectProperty(iFig, __GO_ID__, &iId, jni_int, 1);
        iAxes = setDefaultProperties(iFig, bDefaultAxes);
    }

    //set(iFig, iPos, iPos + 1)
    for (i = iPos + 1 ; i <= iRhs ; i += 2)
    {
        int isMatrixOfString = 0;
        int* piAddrProp = NULL;
        char* pstProName = NULL;
        int* piAddrData = NULL;
        int iRows = 0;
        int iCols = 0;
        void* _pvData = NULL;
        int iType = 0;

        //get property name
        sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddrProp);
        if (sciErr.iErr)
        {
            Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i);
            return 1;
        }

        if (getAllocatedSingleString(pvApiCtx, piAddrProp, &pstProName))
        {
            Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
            return 1;
        }

        if (bDoCreation && (
                    stricmp(pstProName, "dockable") == 0 ||
                    stricmp(pstProName, "toolbar") == 0 ||
                    stricmp(pstProName, "menubar") == 0 ||
                    stricmp(pstProName, "default_axes") == 0 ||
                    stricmp(pstProName, "visible") == 0 ||
                    stricmp(pstProName, "figure_size") == 0 ||
                    stricmp(pstProName, "axes_size") == 0 ||
                    stricmp(pstProName, "position") == 0 ||
                    stricmp(pstProName, "resize") == 0 ||
                    stricmp(pstProName, "menubar_visible") == 0 ||
                    stricmp(pstProName, "toolbar_visible") == 0 ||
                    stricmp(pstProName, "infobar_visible") == 0))
        {
            // Already set creating new figure
            // but let the set_ function fail if figure already exists
            freeAllocatedSingleString(pstProName);
            continue;
        }

        //get address of value on stack
        sciErr = getVarAddressFromPosition(pvApiCtx, i + 1, &piAddrData);
        if (sciErr.iErr)
        {
            Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i + 1);
            freeAllocatedSingleString(pstProName);
            return 1;
        }

        getVarType(pvApiCtx, piAddrData, &iType);

        if ((strcmp(pstProName, "user_data") == 0) || (stricmp(pstProName, "userdata") == 0))
        {
            /* in this case set_user_data_property
             * directly uses the  third position in the stack
             * to get the variable which is to be set in
             * the user_data property (any data type is allowed) S. Steer */
            _pvData = (void*)piAddrData;         /*position in the stack */
            iRows = -1;   /*unused */
            iCols = -1;   /*unused */
            iType = -1;
        }
        else
        {
            switch (iType)
            {
                case sci_matrix :
                    getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, (double**)&_pvData);
                    break;
                case sci_boolean :
                    getMatrixOfBoolean(pvApiCtx, piAddrData, &iRows, &iCols, (int**)&_pvData);
                    break;
                case sci_handles :
                    getMatrixOfHandle(pvApiCtx, piAddrData, &iRows, &iCols, (long long**)&_pvData);
                    break;
                case sci_strings :
                    if (   strcmp(pstProName, "tics_labels") != 0 && strcmp(pstProName, "auto_ticks") != 0 &&
                            strcmp(pstProName, "axes_visible") != 0 && strcmp(pstProName, "axes_reverse") != 0 &&
                            strcmp(pstProName, "text") != 0 && stricmp(pstProName, "string") != 0 &&
                            stricmp(pstProName, "tooltipstring") != 0) /* Added for uicontrols */
                    {
                        if (getAllocatedSingleString(pvApiCtx, piAddrData, (char**)&_pvData))
                        {
                            Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 3);
                            freeAllocatedSingleString(pstProName);
                            return 1;
                        }
                        iRows = (int)strlen((char*)_pvData);
                        iCols = 1;
                    }
                    else
                    {
                        isMatrixOfString = 1;
                        if (getAllocatedMatrixOfString(pvApiCtx, piAddrData, &iRows, &iCols, (char***)&_pvData))
                        {
                            Scierror(999, _("%s: Wrong type for argument #%d: string expected.\n"), fname, 3);
                            freeAllocatedSingleString(pstProName);
                            return 1;
                        }
                    }
                    break;
                case sci_list :
                    iCols = 1;
                    getListItemNumber(pvApiCtx, piAddrData, &iRows);
                    _pvData = (void*)piAddrData;         /* In this case l3 is the list position in stack */
                    break;
                default :
                    _pvData = (void*)piAddrData;         /* In this case l3 is the list position in stack */
                    break;
            }
        }

        callSetProperty(pvApiCtx, iFig, _pvData, iType, iRows, iCols, pstProName);

        // If backgroundcolor is set :
        // * add it to colormap => performed by callSetProperty
        // * set background to index => performed by callSetProperty
        // * copy value into axes background property
        if (stricmp(pstProName, "backgroundcolor") == 0 && iAxes > 0)
        {
            int iBackground = 0;
            int *piBackground = &iBackground;

            getGraphicObjectProperty(iFig, __GO_BACKGROUND__, jni_int, (void **)&piBackground);
            setGraphicObjectProperty(iAxes, __GO_BACKGROUND__, piBackground, jni_int, 1);
        }

        freeAllocatedSingleString(pstProName);
        if (iType == sci_strings)
        {
            //free allacted data
            if (isMatrixOfString == 1)
            {
                freeAllocatedMatrixOfString(iRows, iCols, (char**)_pvData);
            }
            else
            {
                freeAllocatedSingleString((char*)_pvData);
            }
        }
    }

    if (position)
    {
        int pos[2];
        pos[0] = (int)position[0];
        pos[1] = (int)position[1];
        setGraphicObjectProperty(iFig, __GO_POSITION__, pos, jni_int_vector, 2);
    }

    //axes_size
    if (axesSize)
    {
        int axes[2];
        axes[0] = (int)axesSize[0];
        axes[1] = (int)axesSize[1];
        setGraphicObjectProperty(iFig, __GO_AXES_SIZE__, axes, jni_int_vector, 2);
    }
    else //no size, use default axes_size
    {
        int* piAxesSize = NULL;
        getGraphicObjectProperty(getFigureModel(), __GO_AXES_SIZE__, jni_int_vector, (void **)&piAxesSize);
        setGraphicObjectProperty(iFig, __GO_AXES_SIZE__, piAxesSize, jni_int_vector, 2);
        releaseGraphicObjectProperty(__GO_AXES_SIZE__, piAxesSize, jni_int_vector, 2);
    }

    initBar(iFig, bMenuBar, bToolBar, bInfoBar);

    if (axesSize == NULL && figureSize) //figure_size
    {
        int figure[2];
        figure[0] = (int)figureSize[0];
        figure[1] = (int)figureSize[1];
        setGraphicObjectProperty(iFig, __GO_SIZE__, figure, jni_int_vector, 2);
    }


    setGraphicObjectProperty(iFig, __GO_RESIZE__, (void*)&bResize, jni_bool, 1);

    //return new created fig
    createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
    AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
    ReturnArguments(pvApiCtx);
    return 0;
}