CPLEX OPL - How to read a set of variable length from Excel - excel

I want to read a tuple from my Excel file for my OPL model in CPLEX, which has the following format:
tuple A {
string a;
int b;
{string} c;
}
The set {string} c of each tuple element is of variable length.
How can I read this via SheetConnection or is this not possible?
I've tried to read it via named fields in Excel, but that didn't work.
I have also read on the CPLEX documentation, that it is only possible to read tuples of fixed width, but my data is not of fixed width.

if you know the number of tuples, you could read 2 arrays with SheetRead
One for
string a;
int b;
The second for
{string} c;
For that array you could use the max number of strings.
And then in the .mod you turn those 2 arrays into a tuple set.

Related

System Verilog function that takes any number of strings as an argument?

I want to have a SystemVerilog function that can accept any number of string arguments, this function is essentially a wrapper around the in-built $display as such I want users to be able to call the function in the same way, passing any number of strings into myfunc() as follows:
myfunc(stringVar1, "literalString", stringVar2, stringVarN, intVarToConvertToString);
My current implementation is to just have a single string arg and use the SystemVerilog concatenation operator to concatenate all the strings I wish to pass; e.g.
myfunc({stringVar1, "literalString", stringVar2, stringVarN, intVarToConvertToString});
however when I try to pass in a numeric type like int as a concatenated string, it isn't being converted into a string representation of its value correctly, and the � character is printed in its place. I have also tried to perform an explicit string cast on the non-string types being concatenated but to no avail.
I know that if I got all of the arguments to my function separately I can then just pass them directly to $display which does correctly convert the number types to their string representation to display them. Does anyone know how I would do this in System Verilog?
If you want to convert an integer's value into a string representation, or more specifically, a "string" of ASCII digits, you need to use a formatting function, like $sformatf("%d",intVarToConvertToString) to convert a value to a decimal representation, or you can combine the concatenation and formatting into a single expression.
myfunc($sformat("%s%s%s%d",{stringVar1, "literalString"}, stringVar2, stringVarN, intVarToConvertToString);
The concat operator {} converts its contents in a stream of bits.
There are no variable arguments in verilog/system verilog functions.
There is no way to wrap variable args in a $display.
So your best bet is using dynamic or associative arrays of strings or queues.
The following is an example of a possible use of an associative array:
package pkg;
function void multstr(string args[int]);
for(int i = 0; i < args.num; i++) begin
$display("arg%0d: %s", i, args[i]);
end
endfunction
endpackage
module testme();
string strings[int];
initial begin
strings[0] = "hello ";
strings[1] = "world";
pkg::multstr(strings);
end
endmodule
Create a function with a dynamic array port like this:
module tb ();
// function arg is a dynamic array of strings
function void printStrings(string mystrings[]);
foreach(mystrings[i])
$display("",mystrings[i]);
endfunction
// dynamic array of string
string names [];
initial
begin
names = new[2];
names = '{"bob","joe"};
printStrings(names);
$display("-----");
// make the d-array 1 bigger
names = new[names.size() + 1](names);
names = '{"bob","joe","bill"};
printStrings(names);
end
endmodule
Which produces
bob
joe
-----
bob
joe
bill
The same thing could be done using a queue as a function port rather than a d-array.

Python3 Struct unpack format string

I am using the python3 struct module to unpack byte data I extracted from a serial com. (With help) I've figured out how to unpack most the data into human readable form. I am having difficult with the format string on a group header struct group_hdr (please see attached screenshot document). I have a byte data (b). I know the character string for "word" is "H" but it's unclear to me from the document what phd_status is. It hasn't been defined anywhere else in the Data structure document. Any ideas?. Thank you in advance.
struct group_hdr
{
union phdb_status status
word label
}
subrecord = struct.unpack_from('<??H', b)
As is explained under Status, it is a simple bitfield with a width of 32 bits. The union is probably defined elsewhere in C (or a similar language) as
union phdb_status {
unsigned int bit_0:1;
unsigned int bit_1:1;
};
The following Python code will store your values:
status, label = struct.unpack_from('<IH', b)
and you can test the individual bits of status with status & 1 and status & 2.

CAPL associative array with string types

Following this paper, I'm trying to create an associative array like this:
variables
{
char[30] translate[ char[] ];
}
It is exactly the same example in the paper. Problem comes when I try to put values to this associative array. For example:
on preStart
{
translate["hello"] = "hola";
}
That gives me a compilation error: "Error 1112 at (89,23): operand types are incompatible"
What I'm doing wrong?
VERSIONS: I'm using Vector CAPL Browser included with CANalyzer version 11.0 SP2
With associative fields (so-called maps) you can perform a 1:1 assignment of values to other values without using excessive memory. The elements of an associative field are key value pairs, whereby there is fast access to a value via a key.
An associative field is declared in a similar way to a normal field but the data type of the key is written in square brackets:
int m[float]; // maps floats to ints
float x[int64]; // maps int64s to floats
char[30] s[ char[] ] // maps strings (of unspecified length) to strings of length < 30
If the key type char[] is specified, all the character fields (of any size) can be used as key values. In the iteration the loop variable must then also be declared as char[]. Key comparisons, e.g. in order to determine iteration sequence, are then performed as character string comparisons, whereby no country-specific algorithms are used.
char[] is the only field type that can be used as a key type. Please bear in mind that you can not declare variables or parameters of the char[] type, with the exception of loop variables in the iteration.
Association between strings:
char[30] namen[char []];
strncpy(namen["Max"], "Mustermann", 30);
strncpy(namen["Vector"], "Informatik", 30);
for (char[] mykey : namen)
{
write("%s is mapped to %s", mykey, namen[mykey]);
}

dealing with array of characters . how can i define an array without declaring its size?

I have an assignment to write a c++ program that:
declares an array named gamma of type char.
declares an array named vowels of type char.
prompts the user to input n characters in the array gamma.
defines a function named save vowels that determines and return the number of vowels letters in the gamma array and save them in the vowels array.
I already tried to write this but I got many errors especially with gamma array.
#include<iostream>
using namespace std;
void main()
{
char gamma[];
int i;
cout<<"insert characterst//insert -1 when you finish "<<endl;
while(i!=-1)
{
cin>>i;
gamma[]='i';
}
char vowels[]={'a','e','i','o','u'};}
You look to be well on your way.
declares an array named gamma of type char.
char gamma[];
This part is almost correct although the array has a size of 0. If you wanted to give it a size of 10, you would change it to
char gamma[10];
declares an array named vowels of type char.
This part is fine as is.
char vowels[]={'a','e','i','o','u'};
The list automatically gives vowels a size of 5 and assigns the values.
prompts the user to input n characters in the array gamma.
You look to have this down perfectly with the cout/cin lines. One small nitpick is that you should prefer using "\n" at the end of a cout instead of endl as it is much faster.
cout << "insert characterst//insert -1 when you finish\n";
You also need to change how you write to your array. You have to specify the index in which you want to write.
gamma[0] = 3; // Set the first element of gamma to 3
gamma[2] = 11;// Set the third element of gamma to 11
You'll need to add a counter to your while loop to know which position of gamma you are writing to
int counter = 0;
while(...) {
cin >> i;
gamma[counter] = i;
counter++;
}
You also need to add a check to your while loop that makes sure you don't write past the end of your gamma array. This is likely the cause of your errors.
For example, if we gamma is defined with a size of 10 it can only hold 10 characters. Trying to write 11 characters to gamma will likely cause the program to crash. Try adding a check like:
while( i != -1 && counter < 10) // where 10 is capacity of gamma
defines a function named save vowels that determines and return the number of vowels letters in the gamma array and save them in the vowels array.
You didn't give anything in your question on this point so I can't really help you out here.

Converting an array of one type to another - system verilog

I am looking to convert an array of one type to another.
As an example, let's say we have an array of type byte and would like a new array of type logic [5:0].
I am having difficulty doing this while not trying to lose data.
Thanks,
George
If you want to convert an array of one type to another, you can easily do that with a bit-stream cast if they have the exact same number of total bits. Dynamically sized arrays would need to be sized to have the exact number of bits.
An array of 60 bytes can be cast to an array of 80 6-bits because they both contain 480 bits.
typedef logic [7:0] array_8_60_t[60];
typedef logic [5:0] array_6_80_t[60];
array_8_60_t a1;
array_6_80_t a2;
...
a2 = array_6_80_t'(a1);
If the target array(a2) has more bits than required, or you have some special formatting, you will need to look at the streaming operators, or revert to a foreach loop;
A data type could be converted by using a cast (') operation.
For your example, you could do the following:
typedef byte byte_arr_t[];
byte_arr_t byte_arr;
typedef logic logic_arr_t[5:0];
logic_arr_t logic_arr;
logic_arr = logic_arr_t'(byte_arr);
remembering that you must also be aware of the size of the arrays and its elements, or data could be lost.

Resources