Ejemplo n.º 1
0
        /// <summary>
        ///  This method obtains the data from the GAMS file using the low level API
        /// </summary>
        /// <param name="_source"></param>
        /// <param name="file"></param>
        /// <param name="table"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public static IEnumerable <QvxDataRow> GetGamsDataLowLevel(string _source, string file, QvxTable table, List <string> selectedFields, List <QueryExtractor.WhereCondition> where)
        {
            const int GMS_VAL_LEVEL    = 0;
            const int GMS_VAL_MARGINAL = 1;
            const int GMS_VAL_LOWER    = 2;
            const int GMS_VAL_UPPER    = 3;
            const int GMS_VAL_SCALE    = 4;
            //const int GMS_VAL_MAX = 5;

            string msg = string.Empty, VarName = string.Empty, sText = string.Empty, UelName = string.Empty;
            int    ErrNr = 0, SymNr = 0, SymTyp = 0, ADim = 0, ACount = 0, AUser = 0, NRec = 0, FDim = 0, j = 0, i = 0, IDum = 0;

            using (gdxcs gdx = new gdxcs(ref msg))
            {
                gdx.gdxOpenRead(_source + "\\" + file, ref ErrNr);
                gdx.gdxFindSymbol(table.TableName, ref SymNr);
                gdx.gdxSymbolInfo(SymNr, ref VarName, ref ADim, ref SymTyp);
                gdx.gdxSymbolInfoX(SymNr, ref ACount, ref AUser, ref sText);
                gdx.gdxDataReadRawStart(SymNr, ref NRec);

                Dictionary <int, string>[] dimensionCache = new Dictionary <int, string> [ADim];

                if (where.Count == 0)
                {
                    // No WHERE clause
                    double[] Vals = new double[gamsglobals.val_max];
                    int[]    Keys = new int[gamsglobals.maxdim];
                    while (gdx.gdxDataReadRaw(ref Keys, ref Vals, ref FDim) != 0)
                    {
                        QvxDataRow row = mapRow(Keys, Vals);
                        if (row != null)
                        {
                            yield return(row);
                        }
                    }
                }
                else
                {
                    // WHERE clause
                    string[] strFilter    = Enumerable.Repeat("", table.Fields.Count()).ToArray();
                    var      emptyFilters = new List <QvxField>();
                    foreach (var whereCondition in where)
                    {
                        int m = Array.FindIndex(table.Fields, element => element.FieldName == whereCondition.Field);
                        if (m >= 0)
                        {
                            if (m > (ADim - 1))
                            {
                                // Only dimensions can be filtered
                                throw new QvxPleaseSendReplyException(QvxResult.QVX_UNSUPPORTED_COMMAND, String.Format("Field \"{0}\" is not a dimension and can't be filtered", whereCondition.Field));
                            }
                            else if ("".Equals(whereCondition.Value))
                            {
                                // GAMS API doesn't allow empty filters, so we have to filter them ourselves
                                emptyFilters.Add(table.Fields[m]);
                            }
                            else
                            {
                                strFilter[m] = whereCondition.Value;
                            }
                        }
                        else
                        {
                            throw new QvxPleaseSendReplyException(QvxResult.QVX_FIELD_NOT_FOUND, String.Format("The field \"{0}\" is not valid", whereCondition.Field));
                        }
                    }

                    using (BlockingCollection <QvxDataRow> buffer = new BlockingCollection <QvxDataRow>())
                    {
                        // Start reading thread
                        Exception exception = null;
                        var       readTask  = Task.Run(() =>
                        {
                            try
                            {
                                gdx.gdxDataReadRawFastFilt(SymNr, strFilter, FilterProc);
                            }
                            catch (Exception e)
                            {
                                exception = e;
                            }
                            finally
                            {
                                // Signal the end of the data
                                buffer.CompleteAdding();
                            }
                        });

                        int FilterProc(IntPtr IndxPtr, IntPtr ValsPtr, IntPtr Uptr)
                        {
                            double[] managedArrayVals = new double[gamsglobals.val_max];
                            Marshal.Copy(ValsPtr, managedArrayVals, 0, gamsglobals.val_max);

                            int[] managedArrayIndx = new int[gamsglobals.maxdim];
                            Marshal.Copy(IndxPtr, managedArrayIndx, 0, gamsglobals.maxdim);

                            QvxDataRow row = mapRow(managedArrayIndx, managedArrayVals, emptyFilters);

                            if (row != null)
                            {
                                buffer.Add(row);
                            }
                            return(1);
                        }

                        // Writing process
                        foreach (QvxDataRow row in buffer.GetConsumingEnumerable())
                        {
                            yield return(row);
                        }
                        if (exception != null)
                        {
                            throw exception;
                        }
                    }
                }

                QvxDataRow mapRow(int[] Keys, double[] Vals, List <QvxField> emptyFilters = null)
                {
                    i = 0;
                    var row = new QvxDataRow();

                    // Read the dimensions
                    for (j = 0; j < ADim; j++)
                    {
                        if (dimensionCache[j] == null)
                        {
                            dimensionCache[j] = new Dictionary <int, string>();
                        }

                        UelName = null;
                        if (dimensionCache[j].ContainsKey(Keys[j]))
                        {
                            UelName = dimensionCache[j][Keys[j]];
                        }
                        else
                        {
                            gdx.gdxUMUelGet(Keys[j], ref UelName, ref IDum);
                            dimensionCache[j][Keys[j]] = UelName;
                        }

                        if (UelName != null)
                        {
                            QvxField field = table.Fields[i++];
                            if (selectedFields.Contains(field.FieldName))
                            {
                                row[field] = UelName;
                            }

                            // we check the empty filters, as GAMS API doesn't do it
                            if (emptyFilters != null && emptyFilters.Contains(field) && !string.IsNullOrEmpty(UelName))
                            {
                                return(null);
                            }
                        }
                    }

                    switch (SymTyp)
                    {
                    // SET
                    case gamsglobals.dt_set:
                        if (gdx.gdxGetElemText((int)Vals[GMS_VAL_LEVEL], ref msg, ref IDum) != 0)
                        {
                            QvxField field2 = table.Fields[i++];
                            if (selectedFields.Contains(field2.FieldName))
                            {
                                row[field2] = msg;
                            }
                        }
                        else
                        {
                            QvxField field2 = table.Fields[i++];
                            if (selectedFields.Contains(field2.FieldName))
                            {
                                row[field2] = Y_STRING;
                            }
                        }
                        break;

                    // PARAMETER
                    case gamsglobals.dt_par:
                        // Value
                        readValueField(row, table.Fields[i++], table.Fields[i++], Vals[GMS_VAL_LEVEL]);

                        if (!string.IsNullOrEmpty(sText) && ADim == 0)
                        {
                            QvxField field = table.Fields[i++];
                            if (selectedFields.Contains(field.FieldName))
                            {
                                row[field] = sText;
                            }
                        }
                        break;

                    // EQUATION and VARIABLE
                    case gamsglobals.dt_equ:
                    case gamsglobals.dt_var:
                        int[] gms_values = { GMS_VAL_LEVEL, GMS_VAL_MARGINAL, GMS_VAL_LOWER, GMS_VAL_UPPER, GMS_VAL_SCALE };
                        foreach (int gms_value in gms_values)
                        {
                            // Value
                            readValueField(row, table.Fields[i++], table.Fields[i++], Vals[gms_value]);
                        }
                        break;
                    }
                    return(row);
                }

                /// <summary>This method reads a value separated in two fields, the first with the numeric value and the second with the special value description.</summary>
                void readValueField(QvxDataRow pRow, QvxField numberField, QvxField specialField, double pVal)
                {
                    Boolean isSpecialValue = false;

                    // Value
                    if (selectedFields.Contains(numberField.FieldName))
                    {
                        pRow[numberField] = val2str(pVal, msg, out isSpecialValue, true, false);
                    }
                    // Value (Special)
                    if (selectedFields.Contains(specialField.FieldName))
                    {
                        pRow[specialField] = val2str(pVal, msg, out isSpecialValue, false, true);
                    }
                    else if (isSpecialValue)
                    {
                        // If the value is special, but the "Special value" column is not selected, we throw an error
                        throw new QvxPleaseSendReplyException(QvxResult.QVX_FIELD_NOT_FOUND, String.Format("The field \"{0}\" contains special values, so the field \"{1}\" has to be selected", numberField.FieldName, specialField.FieldName));
                    }
                }

                /// <summary>This method generates the final value of a field, that can be a normal number, an acronym, infinite, ...</summary>
                /// <param name="returnNumber">If true, the value of a number will be returned as a double</param>
                /// <param name="returnSpecial">If true, the value of a special value (infinite, epsilon, acronym, ...) will be returned as a string</param>
                dynamic val2str(double val, string s, out Boolean isSpecial, Boolean returnNumber = true, Boolean returnSpecial = true)
                {
                    string[] gmsSVText = { "UNdef", "NA", "+Inf", "-Inf", "Eps", "0", "AcroN" };
                    int      sv        = 0;

                    if (gdx.gdxAcronymName(val, ref s) != 0)
                    {
                        isSpecial = true;
                        return(returnSpecial ? s : null);
                    }
                    else
                    {
                        gdx.gdxMapValue(val, ref sv);
                        if (gamsglobals.sv_normal != sv)
                        {
                            isSpecial = true;
                            return(returnSpecial ? gmsSVText[sv] : null);
                        }
                        else
                        {
                            isSpecial = false;
                            if (returnNumber)
                            {
                                return(val);
                            }
                            else
                            {
                                return(null);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Obtains the preview data using the high level API
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="NumberOfRows"></param>
        /// <returns></returns>
        public string[,] GetPreviewData(QvxTable table, int NumberOfRows = int.MaxValue)
        {
            string[,] returnTable;
            GAMSSymbol symbol = Db.GetSymbol(table.TableName);

            switch (symbol)
            {
            case GAMSSet gset:
                GetPreviewColumnsData(out returnTable, gset, NumberOfRows);
                break;

            case GAMSParameter gparam:
                GetPreviewColumnsData(out returnTable, gparam, NumberOfRows);
                break;

            case GAMSEquation geq:
                GetPreviewColumnsData(out returnTable, geq, NumberOfRows);
                break;

            case GAMSVariable gvar:
                GetPreviewColumnsData(out returnTable, gvar, NumberOfRows);
                break;

            default:
                returnTable = new string[0, 0];
                break;
            }

            int FinalNumberOfRows = returnTable.GetLength(0);
            int NumberOfColumns   = returnTable.GetLength(1);

            //Using advanced api for retrieve acronyms if existing
            string msg = "";
            int    ErrNr = 0, SymNr = 0;

            using (gdxcs gdx = new gdxcs(ref msg))
            {
                gdx.gdxOpenRead(GDXFileLocation, ref ErrNr);
                gdx.gdxFindSymbol(table.TableName, ref SymNr);

                int dimensions = symbol.Dim;
                for (int i = 0; i < FinalNumberOfRows; i++)
                {
                    for (int j = dimensions; j < NumberOfColumns; j++)
                    {
                        if (double.TryParse(returnTable[i, j], out double doubleForParse))
                        {
                            string value = val2str(doubleForParse, msg, out Boolean isSpecial);
                            if (isSpecial)
                            {
                                // Values use two columns, and special values appear in the second one. So we increase the counter
                                returnTable[i, j++] = "";
                            }
                            returnTable[i, j] = value;
                        }
                    }
                }

                string val2str(double val, string s, out Boolean isSpecial)
                {
                    string[] gmsSVText = { "UNdef", "NA", "+Inf", "-Inf", "Eps", "0", "AcroN" };
                    isSpecial = false;
                    int sv = 0;

                    if (gdx.gdxAcronymName(val, ref s) != 0)
                    {
                        isSpecial = true;
                        return(s);
                    }
                    else
                    {
                        gdx.gdxMapValue(val, ref sv);
                        if (gamsglobals.sv_normal != sv)
                        {
                            isSpecial = true;
                            return(gmsSVText[sv]);
                        }
                        else
                        {
                            return(val.ToString("N", new CultureInfo("en-US", false).NumberFormat));
                        }
                    }
                }
            }

            return(returnTable);
        }
Ejemplo n.º 3
0
        static bool ReadSolutionData(string fnGDXFile)
        {
            int    VarNr = 0, NrRecs = 0, FDim = 0, dim = 0, vartype = 0;
            int    status = 0;
            string VarName;
            string msg = string.Empty;

            string[] Indx   = new string[gamsglobals.maxdim];
            double[] Values = new double[gamsglobals.val_max];

            gdx.gdxOpenRead(fnGDXFile, ref status);
            if (status != 0)
            {
                return(GDXError(status, "gdxOpenRead"));
            }

            VarName = "result";
            if (0 == gdx.gdxFindSymbol(VarName, ref VarNr))
            {
                Console.WriteLine("Could not find variable >" + VarName + "<");
                return(false);
            }

            gdx.gdxSymbolInfo(VarNr, ref VarName, ref dim, ref vartype);
            if (2 != dim || gamsglobals.dt_var != vartype)
            {
                Console.WriteLine(VarName + " is not a two dimensional variable");
                return(false);
            }

            if (0 == gdx.gdxDataReadStrStart(VarNr, ref NrRecs))
            {
                return(GDXError(gdx.gdxGetLastError(), "gdxDataReadStrStart"));
            }

            while (gdx.gdxDataReadStr(ref Indx, ref Values, ref FDim) != 0)
            {
                int i;
                if (0.0 == Values[gamsglobals.val_level])
                {
                    continue;                                       /* skip level = 0.0 is default */
                }
                for (i = 0; i < dim; i++)
                {
                    Console.Write(Indx[i]);
                    if (i < dim - 1)
                    {
                        Console.Write(".");
                    }
                }
                Console.WriteLine(" = " + Values[gamsglobals.val_level]);
            }
            Console.WriteLine("All solution values shown");

            gdx.gdxDataReadDone();

            status = gdx.gdxGetLastError();
            if (status != 0)
            {
                return(GDXError(status, "GDX"));
            }

            if (gdx.gdxClose() != 0)
            {
                return(GDXError(gdx.gdxGetLastError(), "gdxClose"));
            }

            return(true);
        }
Ejemplo n.º 4
0
        static int Main(string[] args)
        {
            string Msg = string.Empty;
            string Sysdir;
            string Producer = string.Empty;
            int ErrNr = 0;
            int rc;
            string[] Indx = new string[gamsglobals.maxdim];
            double[] Values = new double[gamsglobals.val_max];
            int VarNr = 0;
            int NrRecs = 0;
            int N = 0;
            int Dimen = 0;
            string VarName = string.Empty;
            int VarTyp = 0;
            int D;

            if (Environment.GetCommandLineArgs().Length != 2 && Environment.GetCommandLineArgs().Length != 3)
            {
                Console.WriteLine("**** XP_Example1: incorrect number of parameters");
                return 1;
            }

            String[] arguments = Environment.GetCommandLineArgs();
            Sysdir = arguments[1];
            Console.WriteLine("XP_Example1 using GAMS system directory: " + Sysdir);

            gdx = new gdxcs(Sysdir, ref Msg);
            if (Msg != string.Empty)
            {
                Console.WriteLine("**** Could not load GDX library");
                Console.WriteLine("**** " + Msg);
                return 1;
            }

            gdx.gdxGetDLLVersion(ref Msg);
            Console.WriteLine("Using GDX DLL version: " + Msg);

            if (Environment.GetCommandLineArgs().Length == 2)
            {
                //write demand data
                gdx.gdxOpenWrite("demanddata.gdx", "xp_example1", ref ErrNr);
                if (ErrNr != 0) xp_example1.ReportIOError(ErrNr);
                if (gdx.gdxDataWriteStrStart("Demand", "Demand data", 1, gamsglobals.dt_par, 0) == 0) ReportGDXError();
                WriteData("New-York", 324.0);
                WriteData("Chicago", 299.0);
                WriteData("Topeka", 274.0);
                if (gdx.gdxDataWriteDone() == 0) ReportGDXError();
                Console.WriteLine("Demand data written by xp_example1");
            }
            else
            {
                rc = gdx.gdxOpenRead(arguments[2], ref ErrNr);
                if (ErrNr != 0) ReportIOError(ErrNr);

                //read x variable back (non-default level values only)
                gdx.gdxFileVersion(ref Msg, ref Producer);
                Console.WriteLine("GDX file written using version: " + Msg);
                Console.WriteLine("GDX file written by: " + Producer);

                if (gdx.gdxFindSymbol("x", ref VarNr) == 0)
                {
                    Console.WriteLine("**** Could not find variable X");
                    return 1;
                }

                gdx.gdxSymbolInfo(VarNr, ref VarName, ref Dimen, ref VarTyp);
                if (Dimen != 2 || VarTyp != gamsglobals.dt_var)
                {
                    Console.WriteLine("**** X is not a two dimensional variable");
                    return 1;
                }

                if (gdx.gdxDataReadStrStart(VarNr, ref NrRecs) == 0) ReportGDXError();

                Console.WriteLine("Variable X has " + NrRecs + " records");
                while (gdx.gdxDataReadStr(ref Indx, ref Values, ref N) != 0)
                {
                    if(Values[gamsglobals.val_level] == 0.0) //skip level = 0.0 is default
                        continue;
                    for (D=0; D<Dimen; D++)
                    {
                        Console.Write(Indx[D]);
                        if (D < Dimen-1) Console.Write(".");
                    }
                    Console.WriteLine(" = " + Values[gamsglobals.val_level]);
                }
                Console.WriteLine("All solution values shown");
                gdx.gdxDataReadDone();
            }
            ErrNr = gdx.gdxClose();
            if (ErrNr != 0) ReportIOError(ErrNr);
            return 0;
        }
Ejemplo n.º 5
0
        static int Main(string[] args)
        {
            string Msg = string.Empty;
            string Sysdir;
            string Producer = string.Empty;
            int    ErrNr    = 0;
            int    rc;

            string[] Indx    = new string[gamsglobals.maxdim];
            double[] Values  = new double[gamsglobals.val_max];
            int      VarNr   = 0;
            int      NrRecs  = 0;
            int      N       = 0;
            int      Dimen   = 0;
            string   VarName = string.Empty;
            int      VarTyp  = 0;
            int      D;

            if (Environment.GetCommandLineArgs().Length != 2 && Environment.GetCommandLineArgs().Length != 3)
            {
                Console.WriteLine("**** XP_Example1: incorrect number of parameters");
                return(1);
            }

            String[] arguments = Environment.GetCommandLineArgs();
            Sysdir = arguments[1];
            Console.WriteLine("XP_Example1 using GAMS system directory: " + Sysdir);

            gdx = new gdxcs(Sysdir, ref Msg);
            if (Msg != string.Empty)
            {
                Console.WriteLine("**** Could not load GDX library");
                Console.WriteLine("**** " + Msg);
                return(1);
            }

            gdx.gdxGetDLLVersion(ref Msg);
            Console.WriteLine("Using GDX DLL version: " + Msg);

            if (Environment.GetCommandLineArgs().Length == 2)
            {
                //write demand data
                gdx.gdxOpenWrite("demanddata.gdx", "xp_example1", ref ErrNr);
                if (ErrNr != 0)
                {
                    xp_example1.ReportIOError(ErrNr);
                }
                if (gdx.gdxDataWriteStrStart("Demand", "Demand data", 1, gamsglobals.dt_par, 0) == 0)
                {
                    ReportGDXError();
                }
                WriteData("New-York", 324.0);
                WriteData("Chicago", 299.0);
                WriteData("Topeka", 274.0);
                if (gdx.gdxDataWriteDone() == 0)
                {
                    ReportGDXError();
                }
                Console.WriteLine("Demand data written by xp_example1");
            }
            else
            {
                rc = gdx.gdxOpenRead(arguments[2], ref ErrNr);
                if (ErrNr != 0)
                {
                    ReportIOError(ErrNr);
                }

                //read x variable back (non-default level values only)
                gdx.gdxFileVersion(ref Msg, ref Producer);
                Console.WriteLine("GDX file written using version: " + Msg);
                Console.WriteLine("GDX file written by: " + Producer);

                if (gdx.gdxFindSymbol("x", ref VarNr) == 0)
                {
                    Console.WriteLine("**** Could not find variable X");
                    return(1);
                }

                gdx.gdxSymbolInfo(VarNr, ref VarName, ref Dimen, ref VarTyp);
                if (Dimen != 2 || VarTyp != gamsglobals.dt_var)
                {
                    Console.WriteLine("**** X is not a two dimensional variable");
                    return(1);
                }

                if (gdx.gdxDataReadStrStart(VarNr, ref NrRecs) == 0)
                {
                    ReportGDXError();
                }

                Console.WriteLine("Variable X has " + NrRecs + " records");
                while (gdx.gdxDataReadStr(ref Indx, ref Values, ref N) != 0)
                {
                    if (Values[gamsglobals.val_level] == 0.0) //skip level = 0.0 is default
                    {
                        continue;
                    }
                    for (D = 0; D < Dimen; D++)
                    {
                        Console.Write(Indx[D]);
                        if (D < Dimen - 1)
                        {
                            Console.Write(".");
                        }
                    }
                    Console.WriteLine(" = " + Values[gamsglobals.val_level]);
                }
                Console.WriteLine("All solution values shown");
                gdx.gdxDataReadDone();
            }
            ErrNr = gdx.gdxClose();
            if (ErrNr != 0)
            {
                ReportIOError(ErrNr);
            }
            return(0);
        }