How can the make function take three parameters? - function

The function make is describe like this:
func make(Type, size IntegerType) Type
When we use make for slicing sometimes it shows like:
make([]int, 0, 10)
So my question is:
How can the make function take three parameters? The size IntegerType is not Vararg. I'm confused...

The make function is one of a bunch of built-in functions that are allowed to do things that you cannot achieve (at least not cleanly and easily) in your Go code.
It has a number of overloaded forms for creating maps, channels and slices (see
https://golang.org/ref/spec#Making_slices_maps_and_channels) :
Your confusion probably stems from https://golang.org/pkg/builtin/#make which shows make as having the signature func make(Type, size IntegerType) Type.
If you look closer in that section, you would also see an indication that make can have a third argument:
Slice: The size specifies the length. The capacity of the slice is
equal to its length. A second integer argument may be provided to
specify a different capacity; it must be no smaller than the length,
so make([]int, 0, 10) allocates a slice of length 0 and capacity 10.
You can also notice that make can also be used without its integer argument:
Map: An initial allocation is made according to the size but the
resulting map has length 0. The size may be omitted, in which case a
small starting size is allocated.
Channel: The channel's buffer is initialized with the specified buffer capacity. If zero, or the size is omitted, the channel is unbuffered.

The make() function is not a regular function, is a builtin function being part of the language specification. What you see in the builtin package (builtin.make()) is only for documentation purposes. That is not the actual signature of the function. The 3rd optional parameter is the capacity, which may only be provided when you're creating a slice.
It's described in the spec: Making slices, maps and channels:
make(T, n) slice slice of type T with length n and capacity n
make(T, n, m) slice slice of type T with length n and capacity m
And also mentioned at Slice types:
A new, initialized slice value for a given element type T is made using the built-in function make, which takes a slice type and parameters specifying the length and optionally the capacity. A slice created with make always allocates a new, hidden array to which the returned slice value refers. That is, executing
make([]T, length, capacity)
produces the same slice as allocating an array and slicing it, so these two expressions are equivalent:
make([]int, 50, 100)
new([100]int)[0:50]

The function make is a builtin function. The function has several features not available to other functions. One is that it takes a variable number arguments as you noted. Another is that the first argument is a type.
The function definition func make(Type, size IntegerType) Type is for documentation purposes only. It is not the actual definition of the function.

Related

imshow() dispalys nothing for int16 array in Octave

I am working on Octave with a brain MRI dataset.
The data is in the form of hundreds of .mat fils.
I load the data file using: x = load("filename.mat") and the images are stored in the form of an array from 0 to 256.
Then when I try to imshow(x.image) a window pops up with 512 x 512 graph but is completely black.
It also throws a warning saying: unsupported type for cdata (= int16 matrix). Valid types are uint8, uint16, double, single, and bool.
I have also tried casting the image array using: imshow(cast(x, "double")) and all the other data types mentioned above, but the result is almost the same.
Help me out here.
You can use the limits parameter of imshow. The image is appearing black because it only contains values in the range [0,256], while int16 contains values up to 32767.
You can set the limits manually:
imshow(x.image, [0, 256])
Or use
imshow(x.image, [])
For automatic limit detection.
Note: on Octave, this will only work with supported types. Since your image doesn't contain negative values, you can convert the image to uint16, which will fit your values. Or you can use double, for a more general approach:
imshow(uint16(x.image), [])
imshow(double(x.image), [])
In your case, if you don't mind the pixels with value 256 being saturated to 255, you can convert the image to uint8:
imshow(uint8(x.image))

TFPCustomHashTable constructor use 196613 constant. Why use this particular value?

Following code is part of contnrs unit of FreePascal
constructor TFPCustomHashTable.Create;
begin
CreateWith(196613,#RSHash);
end;
I am curious about 196613. I know it is hash table size. Is there any particular reason why this value is used?
In my test, constructor took about 3-4 ms to execute, which in my particular situation is not accepted. I suspect this is related to this constant value.
Update:
My question are:
Why 196613 is chosen? Why not other prime number?
Does it affect constructor call execution time?
196613 is one of the numbers being recommended for hash tables sizes (prime and far away from powers of two), for more info see e.g. https://planetmath.org/goodhashtableprimes.
It affects the constructor call execution time, yes. You can always construct TFPCustomHashTable using CreateWith and pass a size of your choice (any number is fine, as resizing algorithm checks for suitable sizes anyways) as well as your own hash function (or the pre-defined RSHash):
MyHashTable:=TFPCustomHashTable.CreateWith(193,#RSHash);
Keep in mind though, that resizing a hash table is an expensive operation as it requires to recalculate the hash function for all elements, so starting with a too small value is neither a good idea.

Constructor/Function overload signature lookup time complexity?

I was reading up on the std::string class in C++ and noticed there are quite a few different constructors available giving us a wide set of initialization features. This got me wondering how a compiler picks which constructor to choose when given parameters, or in the case of overloads, how a compiler matches a function signature with a given set of parameters.
If we have the following functions declared in pseudo-code:
function f1(int numberHere) {
//....do something
}
function f1(int numberHere, string stringHere) {
//....do something
}
And I decide to call f1(4), there are obviously two options to choose from, but what if there are 10000 options/signatures? Would it take proportionally longer? If so, what takes longer? Does the compiler have some sneaky O(n) way to index overloads such that it can call the right one in O(1) time once the program is running or would it compile in O(1) no matter how many overloads exist but take longer to run the finished result because of on-the-fly signature matching?
Can this question even be answered effectively?
Thanks!
Matching function signatures is actually not different from any other search or lookup problem. There are three basic ways to do it depending on the data structure you are storing the available function signatures in:
Use an unsorted list or array and get O(n) time complexity.
Use a sorted array or a tree-like structure and get O(log(n)). (You can sort by type of 1st argument, then 2nd and so on, assuming that each type has an integer id assigned to it.)
Use a hash map and get O(1).
But I doubt that time complxity has any practical relevance in this case. It describes the asymptotic behaviour of algorithms for large values of n. Even for n=100, an unsorted array search might be faster than hash map lookup because it has less overhead.
And from a usability point of view it is a very bad idea to design an API having functions with 10 or even 100 overloads.

ANY , NONE and Unit in Nim

i couldn't find any specific information in the manual.
can anyone clarify how does ANY , NONE and type unit are reflected in Nim?
short definitions -
a unit type is a type that allows only one value (and thus can hold no information). The carrier (underlying set) associated with a unit type can be any singleton set. There is an isomorphism between any two such sets, so it is customary to talk about the unit type and ignore the details of its value. One may also regard the unit type as the type of 0-tuples, i.e. the product of no types.
ANY -
type ANY also known as ALL or Top , is the universal set. (all possible values).
NONE- the "empty set"
thank you!
Your question seems to be about sets. Let's have a look:
let emptySet: set[int8] = {}
This is an empty set of type int8. The {} literal for the empty set is implicitly casted to any actual set type.
let singletonSet = {1'i8}
This is a set containing exactly one value (a unit type if I understand it correctly). The type of the set can now be automatically deduced from the type of the single value in it.
let completeSet = {low(int8) .. high(int8)}
This set holds all possible int8 values.
The builtin set type is implemented as bitvector and thus can only be used for value types which can hold only a small set of possible values (for int8, the bitvector is already 256 bits long). Besides int8, it is usually used for char and enumeration types.
Then there is HashSet from the module sets which can hold larger types. However, if you construct a HashSet containing all possible values, memory consumption will probably be enormous.
Nim is not a functional language, and never claims to be one. There is no equivalent of these types, and the solution is more like the road that c++ takes.
There is void, wich is closest to what Unit is. The Any type does not exist, but there is the untyped pointer. But that type does not hold any type information in it, so you need to know what you can cast it to. And for NONE, or Nothing how I know it from scala, you have to use void, too. But here you can add the noReturn pragma.

Octave force deepcopy

The question
What are the ways of coercing octave to create a real copy of whatever object? Structures are the main interest.
My underlying problem
In my problem I'm obtaining a rather large structure from another function in a loop but for the current task only a few pieces of it are needed. For example:
for i=1:many
res=solver(params);
store1{i}=res.string1;
store2{i}=res.arr(:,1);
end
res is a sizable chunk of data and due to lazy-copy those store-s are references to tiny portions of bytes in that chunk. After I store those tiny portions, I don't need res itself, however, since middle of that chunk is referenced by store, the memory area is unfit for res obtained on the next iteration (they are of the same size) and thus another sizable piece of memory is allocated, which is then again crossed by few tiny links an so on.
Without storing parts of res, the program successfully keeps the memory consumption same after first couple of iterations.
So how do I make a complete copy of structure field?
I've tried using struct-related functions like rmfield but those keep references instead of their own objects.
I've tried to wrap the assignment of in its own function:
new_struct=copy( rmfield(old_struct,"bigdata"));
function c=copy(a);
c=a;
end;
This by the way doesn't work even for arrays.
I'm interested in method applicable to any generic variable.
Minimal working example of the problem
a=cell(3,1);
for i=1:length(a);
r=rand(100000,1000);
a{i}=r(1:100,end);
whos; fflush(stdout);
pause(2);
end;
The above code will cause memory usage to gradually grow by far more than 8.08 kb reported by whos due to references stored by a{i} blocking bigger memory block than they actually need. If you force the proper copy, the problem is not present.
Numerical arrays
For numeric types addition of zero is enough to warrant a new array.
c=a+0;
Strings
For string which is 1 x n char array, something along the following lines will work:
c=[a "a"](1:end-1);
Multidimensional char arrays will require concatenation with a column:
c=[a true(size(a,1),1)](:,1:end-1);
Here true is used to generate dummy array of size compatible with char. (There seems to be no procedural method of generating char array of arbitrary size) char(zeros(size(a,1),1)) and char(true(size(a,1),1)) caused excess memory usage during their creation on some calls.
Note that empty concatenation c=[a ""]; will not result in a copying. Also it is possible to do c=[a+0 ""]; which will result in a copying due to +0 but that one infers type conversions to and from double which is 8 times larger in size. (char(zeros( doesn't seem to cause that)
Other types
In general you can use casting for the types allowed by it in order to not tailor the expressions manually as I had to do above:
typelist={"double","single","char"}; %full list of supported types is available in the link
class_of_a = typelist{ isa(a,typelist) };
c=typecast( [typecast(a,'single'); single(1)] (1:end-1), class_of_a);
Single is seemingly smallest datatype available in octave.
Note that logical is not supported by this method.
Copying structures
Apparently you'd have to write your own function to go around struct fields, copy them with above methods and recursively go to substructs.
(As it doesn't involve complexities relevant here, I'd rather leave that to be done by those who actually needs that, my own problem being solved by +0's.)