Is it possible to do something like this?
trace( for(a in array) a );
I've seen it used when populating an array:
var numbers = [ for (i in 0...100) i ];
But doesn't seem to work as an overall expression?
for can be used "as a value" in array comprehension (as you mentioned) as well as map comprehension. The same is true for while and do...while.
In other places, loops cannot be used like this. Everything is an expression explains this well, using pretty much the same trace example you gave:
Some expressions, such as loops or var declarations don't make any sense as values, so they will be typed as Void and thus won't be able to be used where value is expected. For example the following won't compile:
trace(for (i in 0...10) i); // ERROR: Cannot use Void as value
Related
I have some code that runs fine and does what I want, although there may be a simpler more elegant solution, this works :
round(Int16, floor(rand(TruncatedNormal(150,20,50,250))))
However when I try to execute it multiple times, using map, it throws an error saying it doesn't like the Int16 specification, so this:
map(round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))), 1:2)
throws this error
ERROR: MethodError: objects of type Int16 are not callable
I just want to run it twice (in this case) and sum the results. Why is it unhappy? Thx. J
The first argument to map is a function. So, with your code, Julia is trying to make a function call:
round(Int16, floor(rand(TruncatedNormal(150,20,50,250))))()
But the output of round(Int16, ...) isn't a function, it's a number, so you cannot call it. That's why the error says "objects of type Int16 are not callable." You could fix this by using an anonymous function:
map(() -> round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))), 1:2)
But the "Julian" way to do this is to use a comprehension:
[round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))) for _ in 1:2]
EDIT:
If you are going to sum the results, then you can use something that looks like a comprehension but is called a generator expression. This is basically everything above with the [ ] around the expression. A generator expression can be used directly in functions like sum or mean, etc.
sum(round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))) for _ in 1:2)
The advantage to generator expressions is that they don't allocate the memory for the full array. So, if you did this 100 times and used the sum approach above, you wouldn't need to allocate space for 100 numbers.
This goes beyond the original question, but OP wanted to use the sum expression where the 2 in 1:2 is a 1-element vector. Of course, if the input is always a 1-element vector, then I recommend first(x) like the comments. But this is a nice opportunity to show the importance of breaking things down into functions frequently in Julia. For example, you could take the entire sum expression and define a function
generatenumbers(n::Integer) = sum(... for _ in 1:n)
where n is a scalar. Then if you have some odd array expression for n (1-element vector, many such ns in a multi-dim array, etc.), you can just do:
generatenumbers.(ns)
# will apply to each element and return same shape as ns
If the de-sugaring logic is more complex than applying element-wise, you can even define:
generatenumbers(ns::AbstractArray) = # ... something more complex
The point is to define an "atomic" function that expresses the statement or task you want clearly, then use dispatch to apply it to more complicated data-structures that appear in practical code. This is a common design pattern in Julia (not the only option, but an effective one).
Adding on the answer from #darsnack.
If you want to run it multiple times in order to keep the results (it wasn't clear from the question). Then you could also ask rand to produce a vector by doing the following (and also making the type conversion through the floor call).
Moving from:
map(round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))), 1:2)
to:
floor.(Int16, rand(TruncatedNormal(150,20,50,250), 2))
The documentation is here.
Is there a simpler way to do apply a function in Julia to nested array than defining a new function? - e.g. for this simple example:
a = collect(1:10)
b = [ a*i for i in 100:100:400]
arraylog(x) = log.(x) ## Need to define an extra function to do the inner array?
arraylog.(b)
I would use a comprehension just like you used it to define b: [log.(x) for x in b].
The benefit of this approach is that such code should be easy to read later.
EDIT
Referring to the answer by Tasos actually a comprehension implicitly defines an anonymous function that is passed to Base.Generator. In this use case a comprehension and map should be largely equivalent.
I assumed that MR_MPI-BGC wanted to avoid defining an anonymous function.
If it were allowed one could also use a double broadcast like this:
(x->log.(x)).(b)
which is even shorer but I thought that it would not be very readable in comparison to a comprehension.
You could define it as a lambda instead.
Obviously the distinction may be moot, depending on how you're using this later in your code, but if all you want is to not waste a line in your code for the sake of conciseness, you could easily dump this inside a map statement, for instance:
map( x->log.(x), b )
or, if you prefer do syntax:
map(b) do x
log.(x)
end
PS. I'm not familiar with a syntax which allows the broadcasted version of a function to be plugged directly into map, but if one exists it would be even cleaner than a lambda here ... but alas 'map( log., b )' is not valid syntax.
I'm looking for an equivalent in Matlab to do the same as Apply in Mathematica. There it works like this
fct=#1+#2^2+#3^3+#4^4&;
Apply[fct,{a,b,c,d}]=f[a,b,c,d]
In Matlab, it's easy with a cell like this
fct=#(x1,x2,x3,x4) x1+x2^2+x3^3+x4^4;
mycell={a,b,c,d};
fct(mycell{:})
because mycell{:}=a,b,c,d is a valid comma-separated list of arguments for fct (see here).
Now, I would like to do the same with an array, e.g. like this:
myarrray=[a,b,c,d];
fct(myarray(:))
but this doesn't work. Sadly, things like fct(num2cell(myarray){:}) don't work either.
The problem here is that I would like to use the function as a one-liner (the array already exists, it can be called by its name). The reason for this is that the function should be an element of a struct.
Of course, in reality, my function looks differently. Note that I'm not looking for arrayfun which maps a function over an array.
(side note: In Mathematica, I can even write Apply[#1+#2^2+#3^3+#4^4&,{a,,b,c,d}] and there is even an infix notation for Apply making it more concise.)
I'm relatively new to C++, and I'm trying to take an array within a class, and set it equal to a passed in array.
public ref class Example {
array<float> ^ myarray1 = gcnew array<float>(3);
public:
Example(float^ myarray2) {
int i = 0;
while (i<3) {
myarray[i] = myarray2[i];
i += 1;
}
}
In the main function, the constructor is called as follows:
float myarray2[] = {1,2,3};
Example ^example1 = gcnew Example(*myarray2)
The errors I get is are as follows:
System::Single' has no default indexed property (class indexer)
expression must have pointer-to-object or handle-to-C++/CLI-array
type
Both of these errors are identified as happening where I am saying myarray[i] = myarray2[i].
I would greatly appreciate any help with solving this problem. I can't see where or how System::Single is getting pulled in as an error message. And, before it is suggested, I know I can get to work with setting myarray2 as a array float like myarray1, but I want it to work passing in myarray2 as float^ myarray2.
Since you say you're new to C++, let me point out that you're not writing classic C++ there. You're writing C++/CLI, which is a set of language extensions to C++ designed to interoperate with the CLI (.NET Framework). Because of this, the type float in your code is an alias for the type System::Single of the framework.
Regarding the indexer issue, the error messages pretty much spell out the cases in which you would be allowed to use an indexer:
System::Single' has no default indexed property (class indexer)
You could use an indexer if the type had a defined indexed property. System::Single, also known as float, doesn't happen to have one.
expression must have pointer-to-object type
You could use the indexer if the type was a non-void pointer type. You'd have to declare it like this:
Example(float* myarray2) {
In this case, myarray2[i] is equivalent to the expression *(myarray2 + i).
or handle-to-C++/CLI-array type
You could use the indexer if the type was a handle (^) to a C++/CLI array type. As you already know, you'd have to declare it like this:
Example(array<float> ^ myarray2) {
The bottom line is that, although you can treat a float* (pointer to float) like a C-style array of float (as a result of the rules of C and C++ about arrays and pointer arithmetic), these things simply do not apply to the float^ (handle to float) type (which is C++/CLI-specific).
Example(float^ myarray2)
That does not mean what you think it does. You are used to C language behavior, a float[] can automatically decay to a float* to the first element of the array. Somewhat unfortunately also carried forward into C++.
But not into C++/CLI, it is fundamentally unverifiable code. And responsible for a very large number of bugs and security problems. One core problem is that your constructor has no idea how many elements are stored in the array. You hard-coded "3" but if the caller passes an array that's smaller then Very Bad Things happen.
What it actually means is "reference to a boxed copy of a System::Single". The compiler tries to make sense of that, inevitably it starts to get very confused what you try to do next. Like using the [] operator, that requires the type to have an indexer. A float doesn't have one.
You need either:
Example(array<float>^ myarray2)
Which is safe and verifiable, you can't index the array out of bounds. And you don't have to hard-code "3" anymore, you can simply use myarray2->Length instead. And you don't (usually) have the copy the array anymore, simply assign myarray1. You'd call the constructor by passing gcnew array<float> { 1, 2, 3 }.
Or:
Example(float* myarray2)
Which works just like the way it does in C and C++. And required if you want to call the constructor with that float[]. Not verifiable, you need that magic "3". Do consider adding an extra argument to pass the array length.
i mean is it possible to have a method that gets as its parameters an array of objects and another parameter which indicates which field of the objects we are using to sort the array ?
for example if the objects are contacts if we call sort(contacts , name) it would sort them with respect to name. if we call sort(contacts , number) it sorts them according to their numbers.
maybe by sending an String of the field we want !! something like :
class sorting {
public static bubble_sort(Object[] array , String field){
for(int i =0; i<array.length ; i++){
if(array[i].field > array[i+1].field)
swap(array ,i ,i+1);
}
}
(preferably in java) (and please include examples of the solutions you give !)
Assuming this is Java: yes, it is possible. You can use reflection to get the field type and value and then compare them. It would not be a good idea. Much better to use Comparator with the existing sort method.
A method that would work in pretty much any language is to pass in some kind of function object.
class sorting {
public static bubble_sort(Object[] array, FunctionObject ordering) {
for(int i =0; i<array.length ; i++){
if(ordering(array[i+1], array[i]))
swap(array ,i ,i+1);
}
};
different languages are going to have different syntaxes for such a function object -- what its type is, etc -- but pretty much every language is going to have some way to do it.
Generally the best signature for it is one that takes two different objects, and returns true if the left one is less than the right one.
Similarly, different languages are going to have different ways of invoking a function object. Some may require ordering.Invoke( array[i+1], array[i] ).
In that function object, compare the field in question. If the language/objects have reflection, you can sometimes do this via field name directly.
As this pattern is very useful, languages tend to make it easier as they mature. So the most recent version of your language may have a syntax to create such objects with far less syntax, and invoke them with less syntax as well.