Heterogeneous sets in OCaml - set

suppose I have a type defined as
type value =
None
| Int of int
| Float of float
| Complex of Complex.t
| String of string
| Char of char
| Bool of bool
and I want to be able to work with Sets of these values. From what I understood I have to use the functor to concretize the Set module with a concrete type and its associated ordering.
How should I do it in this example? Since value cannot be used directly inside the Set.Make functor?
Then of course I need to be able to give a full ordering of these values so I should invent something like giving a predefined order to different types, and then ordering them by their effective value.. am I right?
So for example I can decide to have Int of int < Float of int and Int x < Int y if x < y. Is it a practical approach to what I'm trying to achieve?

Set.Make functor takes the module with signature Set.OrderedType :
module type OrderedType = sig type t val compare : t -> t -> int end
For comparison you can use Pervasives.compare if you don't have any requirements on the order and results returned by min_elt/max_elt. So the parameter to the functor can be as simple as :
module T = struct type t = value let compare = compare end

Related

Why there are two different answer in same compare template function

When I try to implement a template to compare two variables' value.
When I try passing string as parameters then the program couldn't compare the value right.
However when I add two same variables this code get me a right result.
Just as the picture shows.
You passed it a const char * pointer to compare and that will compare the pointer addresses, not the contents with '>'. As these are from different objects/strings, you have no way to know which will be first or last in memory, and it may vary from compile to compile, or even potentially run to run.
As you had the std::string local variable, I assume you intended to pass that, which does have comparison operators to compare the contents. If you want to pass a string literal as an std::string to such a template function, you must do it explicitly, such as:
Max<std::string>("a", "b"); // K is std::string, so both parameters will use the implicit constructor
Max(std::string("a"), std::string("b")); // Explicitly construct strings
If you do want Max to work with char pointers, you might overload or specialise it to use say strcmp, which does compare the contents.
template<class T> T Max(T x, T y)
{
return x > y ? x : y;
}
template<> const char* Max(const char *x, const char *y)
{
return strcmp(x, y) > 0 ? x : y;
}
template<> char* Max(char *x, char *y)
{
return strcmp(x, y) > 0 ? x : y;
}

Define uint8_t variable in Protocol Buffers message file

I want to define a Point message in Protocol Buffers which represents an RGB Colored Point in 3-dimensional space.
message Point {
float x = 1;
float y = 2;
float z = 3;
uint8_t r = 4;
uint8_t g = 5;
uint8_t b = 6;
}
Here, x, y, z variables defines the position of Point and r, g, b defines the color in RGB space.
Since uint8_t is not defined in Protocol Buffers, I am looking for a workaround to define it. At present, I am using uint32 in place of uint8_t.
There isn't anything in protobuf that represents a single byte - it simply isn't a thing that the wire-format worries about. The options are:
varint (up to 64 bits input, up to 10 bytes on the wire depending on the highest set bit)
fixed 32 bit
fixed 64 bit
length-prefixed (strings, sub-objects, packed arrays)
(group tokens; a rare implementation detail)
A single byte isn't a good fit for any of those. Frankly, I'd use a single fixed32 for all 3, and combine/decompose the 3 bytes manually (via shifting etc). The advantage here is that it would only have one field header for the 3 bytes, and wouldn't be artificially stretched via having high bits (I'm not sure that a composed RGB value is a good candidate for varint). You'd also have a spare byte if you want to add something else at a later date (alpha, maybe).
So:
message Point {
float x = 1;
float y = 2;
float z = 3;
fixed32 rgb = 4;
}
IMHO this is the correct approach. You should use the nearest data type capable of holding all values to be sent between the system. The source & destination systems should validate the data if it is in the correct range. For uint8_t this is int32 indeed.
Some protocol buffers implementations actually allow this. In particular, nanopb allows to either have .options file alongside the .proto file or use its extension directly in .proto file to fine tune interpretation of individual fields.
Specifying int_size = IS_8 will convert uint32 from message to uint8_t in generated structure.
import "nanopb.proto";
message Point {
float x = 1;
float y = 2;
float z = 3;
uint32 r = 4 [(nanopb).int_size = IS_8];
uint32 g = 5 [(nanopb).int_size = IS_8];
uint32 b = 6 [(nanopb).int_size = IS_8];
}

How to send a variable of type struct in MPI_Send()?

I have coded a program in C using MPI wherein the struct variable is to be sent in a ring fashion to the processes and, based on the value received from that variable, the work for that particular process is assigned.
The problem is I need to know how to to send a struct variable in the MPI_Send() function as it is giving INVALID DATATYPE at the runtime , Consider the following example
struct info{
int ne, n, u, v, process, min, strip, mincost, b;
} stat;
MPI_Send(&stat,sizeof(stat),sizeof(struct info),1,2,MPI_COMM_WORLD);
You have to do some operation before send a struct.
I wrote the code for your example but to understand better you should read some documentation.
Anyway, here some tips:
If you have a struct made of just one kind of elements, like in your example that all the vars are int, it's better to send a vector taking care the position of each variable.
If you had other kinds, you have to set count to 2 or more and change all the other arrays (e.g: array_of_types, array_of_blocklengths et cetera).
You can calculate the values of array_of_displaysments on your own in that case take care of the Data structure alignment.
If for example you have the struct that follows, x will start from 0 but y from 8, because a padding of 4 bytes will be add to align the elements. struct point{ int x; double y; };
If you don't want to calculate the array_of_displaysments always use MPI_Get_Address and do not rely on the & operator.
Here the code:
struct info{
int ne, n, u, v, process,min,strip,mincost,b;
}stat;
int main(...){
/*MPI INIT*/
struct info _info,
int count; //Says how many kinds of data your structure has
count = 1; //1, 'cause you just have int
// Says the type of every block
MPI_Datatype array_of_types[count];
// You just have int
array_of_types[0] = MPI_INT;
// Says how many elements for block
int array_of_blocklengths[count];
// You have 8 int
array_of_blocklengths[0] = {8};
/* Says where every block starts in memory, counting from the beginning of the struct. */
MPI_Aint array_of_displaysments[coun];
MPI_Aint address1, address2;
MPI_Get_address(&_info,&address1);
MPI_Get_address(&_info.ne,&address2);
array_of_displaysments[0] = address2 - address1;
/*Create MPI Datatype and commit*/
MPI_Datatype stat_type;
MPI_Type_create_struct(count, array_of_blocklengths, array_of_displaysments, array_of_types, &stat_type);
MPI_Type_commit(&stat_type);
// Now we are ready to send
MPI_Send(&_info, 1, stat_type, dest, tag, comm),
/* . . . */
// Free datatype
MPI_Type_free(&stat_type);
// MPI finalization
MPI_Finalize();
}
try this
MPI_Send(&stat,sizeof(struct info),MPI_CHAR,1,2,MPI_COMM_WORLD);
MPI_Recv(&data,sizeof(struct info), MPI_CHAR, 0, DEFAULT_TAG, MPI_COMM_WORLD, &status);
stat = (struct info *) data;

In GNU GCC 4.5.3 type casting int to short

I would like to know, when two integers are multiplied and result is typecast to short and assigned to short, what will the compiler resolves it to? Below is the code snippet
int a=1,b=2,c;
short x=3,y=4,z;
int p;
short q;
int main()
{
c = a*b; /* Mul two ints and assign to int
[compiler resolves this to __mulsi3()] */
z = x*y; /* Mul two short and assign to short
[compiler resolves this to __mulhi3()] */
p = (x*y); /* Mul two short and assign to int
[compiler resolves this to __mulsi3()] */
q =(short)(a*b); /* Mul two ints typecast to short and assign to short
[compiler resolves this to __mulhi3()] */
return 0;
}
Here in the case for q =(short)(a*b);, first two ints multiplication should be performed (using __mulsi3()) and then assign it to short. But it's not the case here, compiler type casts both a and b to short and then calls __mulhi3().
I would like to know how can I change in gcc source code [which file], so that i can achieve my above requirements.
The compiler can analyse the code and see that as you covert the result immediately to a short the mutiplication can be done as short multiplication without affecting the result. This is exactly the same as case two of your example.
As the result is the same you don't need to worry about which multiplication function is used.

How to compare int values?

I would like to know how to compare int values.
I would like to know that once I compare both 2 int values, I would like to know how far apart these 2 values are and if it is possible to put this in a 'if' statement.
The only problem I have is that (lets say int HELLO), HELLO's value always changes at random, so I would like to know how do I always compare HELLO's value and a different int's value on the go, so that at any moment if the result of both values are only 50 numbers off (negative or positive), it would trigger let's say timer2->Stop();.
Thank you.
If you have two int values, then you can subtract them to find out the difference between the two. Then in your if-test you just check if they are within 50 of each other and then execute the code...
Here's some pseudocode for you to work off of:
int valueOne = 100;
int valueTwo = 50;
int differenceBetweenValues = valueOne - valueTwo;
if ( (differenceBetweenValues >= 50) || (differenceBetweenValues >= -50) ) {
timer2->Stop();
}
You could then make that as a function and pass your values in (as you've stated they're different each time).
The distance between two int numbers is calculated as an absolute value of their difference:
int dist = abs(value1 - value2);
You can put it in an if statement or do anything you wish with the result:
if (abs(value1 - value2) > 50) ...

Resources