Array.set is not a function and cannot be applied - arrays

I need to make a function which turns a random pixel in a picture to black.
A picture is represented as an array of colors represented as Black or White.
Here is my code :
type color = Black | White
;;
type picture = color array array
;;
let rec color_rand_point (img : picture) : picture =
let randx = ref (Random.int (Array.length img))
and randy = ref (Random.int (Array.length img)) in
if (img.(!randx).(!randy) = White)then
begin
Array.set img.(!randx) (!randy) Black;
end
img
else
color_rand_point(img)
;;
Here is the result I have when I try compiling :
Lines 5-7, characters 4-7:
5 | ....begin
6 | Array.set img.(!randx) (!randy) Black;
7 | end
Error: This expression has type unit
This is not a function; it cannot be applied.
#
I'm pretty sure the answer would be obvious to anyone knowledgeable about ocaml and that it's bad style, but I'm working on this as a student and have close to no idea about what i'm doing with ocaml. We didn't learn the basics in depth so I would like a simple answer if possible.
I have no idea of why Array.set isn't considered as a function applicable in an imperative bloc.

The error message doesn't point to Array.set, but to the begin ... end block, which evaluates to unit because Array.set, the only expression inside the block, returns unit.
The problem is that img is outside the block, and not separated by a semicolon, so you're effectively telling the compiler to pass img as an argument to whatever the begin ... end block evaluates to. Which is unit, not a function, as the error message says.
The error can be fixed just by moving img inside the block.

Related

Matlab dot index error in array filled with objects from a class

Hi everyone i'm experiencing some trouble with my code. The goal is to add multiple objects to a class, i've created the following code for that:
array = cell(1,10);
A = matrix %specified somewhere else
for ind = 1:10
[r c] = find(A<3);
random = randi([1, size(r,1)]);
array{ind} = classname(1, r(random), c(random));
end
This block of code does everything I want it to, however, later on I add this array as property to another class and have to work with that specific array to make changes to it. And that is where is goes wrong.
function growing(thisElement)
for i = 1:length(otherClass.array)
range = range((otherClass.array(i).locationX - 2), (otherClass.array(i).locationX +2));
if otherClass.array(i).pos<20
......
end
end
end
Whereby both locationX and pos are properties of classname. I get the error Dot indexing is not supported for variables of this type. For both the range as the last if part. The error is apparently very commen error, however, I don't find any answers relating my case. Has anyone an idea to bypass the error?

Idiomatic exceptions for exiting loops in OCaml

In OCaml, imperative-style loops can be exited early by raising exceptions.
While the use of imperative loops is not idiomatic per se in OCaml, I'd like to know what are the most idiomatic ways to emulate imperative loops with early exits (taking into account aspects such as performance, if possible).
For instance, an old OCaml FAQ mentions exception Exit:
Exit: used to jump out of loops or functions.
Is it still current? The standard library simply mentions it as a general-purpose exception:
The Exit exception is not raised by any library function. It is provided for use in your programs.
Relatedly, this answer to another question mentions using a precomputed let exit = Exit exception to avoid allocations inside the loop. Is it still required?
Also, sometimes one wants to exit from the loop with a specific value, such as raise (Leave 42). Is there an idiomatic exception or naming convention to do this? Should I use references in this case (e.g. let res = ref -1 in ... <loop body> ... res := 42; raise Exit)?
Finally, the use of Exit in nested loops prevents some cases where one would like to exit several loops, like break <label> in Java. This would require defining exceptions with different names, or at least using an integer to indicate how many scopes should be exited (e.g. Leave 2 to indicate that 2 levels should be exited). Again, is there an approach/exception naming that is idiomatic here?
As originally posted in comments, the idiomatic way to do early exit in OCaml is using continuations. At the point where you want the early return to go to, you create a continuation, and pass it to the code that might return early. This is more general than labels for loops, since you can exit from just about anything that has access to the continuation.
Also, as posted in comments, note the usage of raise_notrace for exceptions whose trace you never want the runtime to generate.
A "naive" first attempt:
module Continuation :
sig
(* This is the flaw with this approach: there is no good choice for
the result type. *)
type 'a cont = 'a -> unit
(* with_early_exit f passes a function "k" to f. If f calls k,
execution resumes as if with_early_exit completed
immediately. *)
val with_early_exit : ('a cont -> 'a) -> 'a
end =
struct
type 'a cont = 'a -> unit
(* Early return is implemented by throwing an exception. The ref
cell is used to store the value with which the continuation is
called - this is a way to avoid having to generate an exception
type that can store 'a for each 'a this module is used with. The
integer is supposed to be a unique identifier for distinguishing
returns to different nested contexts. *)
type 'a context = 'a option ref * int64
exception Unwind of int64
let make_cont ((cell, id) : 'a context) =
fun result -> cell := Some result; raise_notrace (Unwind id)
let generate_id =
let last_id = ref 0L in
fun () -> last_id := Int64.add !last_id 1L; !last_id
let with_early_exit f =
let id = generate_id () in
let cell = ref None in
let cont : 'a cont = make_cont (cell, id) in
try
f cont
with Unwind i when i = id ->
match !cell with
| Some result -> result
(* This should never happen... *)
| None -> failwith "with_early_exit"
end
let _ =
let nested_function i k = k 15; i in
Continuation.with_early_exit (nested_function 42)
|> string_of_int
|> print_endline
As you can see, the above implements early exit by hiding an exception. The continuation is actually a partially applied function that knows the unique id of the context for which it was created, and has a reference cell to store the result value while the exception is being thrown to that context. The code above prints 15. You can pass the continuation k as deep as you want. You can also define the function f immediately at the point where it is passed to with_early_exit, giving an effect similar to having a label on a loop. I use this very often.
The problem with the above is the result type of 'a cont, which I arbitrarily set to unit. Actually, a function of type 'a cont never returns, so we want it to behave like raise – be usable where any type is expected. However, this doesn't immediately work. If you do something like type ('a, 'b) cont = 'a -> 'b, and pass that down to your nested function, the type checker will infer a type for 'b in one context, and then force you to call continuations only in contexts with the same type, i.e. you won't be able to do things like
(if ... then 3 else k 15)
...
(if ... then "s" else k 16)
because the first expression forces 'b to be int, but the second requires 'b to be string.
To solve this, we need to provide a function analogous to raise for early return, i.e.
(if ... then 3 else throw k 15)
...
(if ... then "s" else throw k 16)
This means stepping away from pure continuations. We have to un-partially-apply make_cont above (and I renamed it to throw), and pass the naked context around instead:
module BetterContinuation :
sig
type 'a context
val throw : 'a context -> 'a -> _
val with_early_exit : ('a context -> 'a) -> 'a
end =
struct
type 'a context = 'a option ref * int64
exception Unwind of int64
let throw ((cell, id) : 'a context) =
fun result -> cell := Some result; raise_notrace (Unwind id)
let generate_id = (* Same *)
let with_early_exit f =
let id = generate_id () in
let cell = ref None in
let context = (cell, id) in
try
f context
with Unwind i when i = id ->
match !cell with
| Some result -> result
| None -> failwith "with_early_exit"
end
let _ =
let nested_function i k = ignore (BetterContinuation.throw k 15); i in
BetterContinuation.with_early_exit (nested_function 42)
|> string_of_int
|> print_endline
The expression throw k v can be used in contexts where different types are required.
I use this approach pervasively in some big applications I work on. I prefer it even to regular exceptions. I have a more elaborate variant, where with_early_exit has a signature roughly like this:
val with_early_exit : ('a context -> 'b) -> ('a -> 'b) -> 'b
where the first function represents an attempt to do something, and the second represents the handler for errors of type 'a that may result. Together with variants and polymorphic variants, this gives a more explicitly-typed take on exception handling. It is especially powerful with polymorphic variants, as the set of error variands can be inferred by the compiler.
The Jane Street approach effectively does the same as what is described here, and in fact I previously had an implementation that generated exception types with first-class modules. I am not sure anymore why I eventually chose this one – there may be subtle differences :)
Just to answer a specific part of my question which was not mentioned in other answers:
... using a precomputed let exit = Exit exception to avoid allocations inside the loop. Is it still required?
I did some micro-benchmarks using Core_bench on 4.02.1+fp and the results indicate no significant difference: when comparing two identical loops, one containing a local exit declared before the loop and another one without it, the time difference is minimal.
The difference between raise Exit and raise_notrace Exit in this example was also minimal, about 2% in some runs, up to 7% in others, but it could well be within the error margins of such a short experiment.
Overall, I couldn't measure any noticeable difference, so unless someone would have examples where Exit/exit significantly affect performance, I would prefer the former since it is clearer and avoids creating a mostly useless variable.
Finally, I also compared the difference between two idioms: using a reference to a value before exiting the loop, or creating a specific exception type containing the return value.
With reference to result value + Exit:
let res = ref 0 in
let r =
try
for i = 0 to n-1 do
if a.(i) = v then
(res := v; raise_notrace Exit)
done;
assert false
with Exit -> !res
in ...
With specific exception type:
exception Res of int
let r =
try
for i = 0 to n-1 do
if a.(i) = v then
raise_notrace (Res v)
done;
assert false
with Res v -> v
in ...
Once again, the differences were minimal and varied a lot between runs. Overall, the first version (reference + Exit) seemed to have a slight advantage (0% to 10% faster), but the difference was not significant enough to recommend one version over the another.
Since the former requires defining an initial value (which may not exist) or using an option type to initialize the reference, and the latter requires defining a new exception per type of value returned from the loop, there is no ideal solution here.
Exit is ok (I'm not sure whether I can say that it is idiomatic). But, make sure, that you're using raise_notrace, if you're using recent enough compiler (since 4.02).
Even better solution, is to use with_return from OCaml Core library. It will not have any problems with scope, because it will create a fresh new exception type for each nesting.
Of course, you can achieve the same results, or just take the source code of Core's implementation.
And even more idiomatic, is not to use exceptions for short-circuiting your iteration, and consider to use existing algorithm (find, find_map, exists, etc) or just write a recursive function, if no algorithm suits you.
Regarding the point
using a precomputed let exit = Exit exception to avoid allocations
inside the loop. Is it still required?
the answer is no with sufficiently recent versions of OCaml. Here is the relevant excerpt from the Changelog of OCaml 4.02.0.
PR#6203: Constant exception constructors no longer allocate (Alain Frisch)
Here is PR6203: http://caml.inria.fr/mantis/view.php?id=6203

Do loop index changing on its own

I have a couple hundred line program (including functions) in essentially free-form Fortran. At one point, I have a pair of nested do loops that call functions and store results in matrices. However, I don't believe any of that is the problem (although I could be wrong).
Immediately after the first do loop starts, I define an array using a column of another array. Immediately after that, the index is always set to 3. I haven't been able to find any useful information in the usual places. I've included a fragment of the code below.
do i = 1,n
print *, 'i:',i ! Gives i = 1
applyto = eig_vec(:,i)
print *, i ! Gives i = 3
state1 = create_state(ground,applyto,state,bin_state,num_s,ns)
first = destroy_state(ground,state1,state,bin_state,num_s,ns)
state1 = destroy_state(ground,applyto,state,bin_state,num_s,ns)
second = create_state(ground,state1,state,bin_state,num_s,
1 ns)
do j = 1,n
bra = eig_vec(:,j)
a_matrix(j,i) = sum(bra*first + bra*second)
matrix(j,i) = sum(bra*first - bra*second
end do
end do
Is this a bug? Am I missing something obvious? I am compiling the code with a high level of optimization, if that could potentially be a source of problems. I'm relatively new to Fortran, so debugging flags or commands (for gdb - I believe that's all I have available) would be welcome.

Plotting from a 2D Array Using a Loop

This seems like a trivial problem, though I've been hitting myself over the head with it for too long.
This doesn't even plot just the (0,0) -- I can't seem to find much about plotting from arrays -- rather just matrix plots (and only columns at that).
The data is properly in these arrays, I just need to make plots! Doesn't seem so complicated. I don't even need separate colors for the different sets...just all one big scatter plot.
Any suggestions?
pdf(mypath)
# Plot first point
plot(0,0, col = "blue", type = "n", xlab="PES", ylab=""%eff")
#Loop to Plot remaining points
for(rows in 1:nrowX)
{
for(cols in 1:ncolX)
{
points(X[rows,cols],Y[rows,cols], col = "blue", type = "p")
}
}
dev.off
I have also tried using plot.new() to have an empty plot...but no such luck.
SOLUTION!!
Turns out I'm just a fool. Code is acurate and the suggestions below do indeed work.
R happened to be open in another tab and since it was open, never let go of the plot (why? I don't know). As soon as it was closed, the plot appeared. Now I can get my plot again and again...
Thanks to everyone who tried helping a problem that wasn't a problem!
I like this place already!
When you set type = "n", the plot function will not plot anything at all. It is used to set up a basis for the rest of the plot (like axis labels, limits etc). That is why the first point at (0, 0) does not show up.
The rest of the points are probably outside the range. Use xlim and ylim to set up the ranges properly. I'm going to assume X and Y have the same size and dimension. Try this:
pdf(mypath)
# Set up the plot
plot(0, type="n", xlab="PES", ylab="%eff", xlim=range(X), ylim=range(y))
# Now plot
points(X,Y, col="blue")
dev.off
Of course you could let the plot function take care of the limits for you:
pdf(mypath)
plot(X, Y, xlab="PES", ylab="%eff")
dev.off()
Your initial plot will set up the coordinates, but since you only give it one point it does not know how much room to leave around the 0,0 point (so it does not leave very much). I expect that the rest of your points fall outside of that range which is why they don't show up on the plot (you can use par("usr") to see what the extents are).
When you create the initial plot you should include xlim and ylim arguments so that the plot includes the area where the new points will be added, something like:
plot(0,0, type='n', xlim=range(X), ylim=range(Y))
You may also be interested in the matplot function which will take a matrix as either or both the x and/or y argument and plot accordingly.
Edit
The following works for me:
X <- matrix( runif(390), nrow=10 )
Y <- matrix( rnorm(390), nrow=10 )
plot(0,0, col = "blue", type = "n", xlab="PES", ylab="%eff",
xlim=range(X), ylim=range(Y))
#Loop to Plot remaining points
for(rows in 1:nrow(X))
{
for(cols in 1:ncol(X))
{
points(X[rows,cols],Y[rows,cols], col = "blue", type = "p")
}
}
I did remove an extra " from the ylab, was that your problem?
But
plot(X,Y)
also worked without the looping.
Check with just the console to see if it works before worrying about sending to a pdf file. If this has not fixed it yet, we still need more details.

I want to extract values from an array and use them in a string expression

I am trying to do a for loop of a nonlinear fit where one of the coefficients changes values with each iteration. These values are in an array called YoungMod. I have:
for k=1:size(DataAll,3)
ft = fittype('E1*(YoungMod(k))-b*t','coefficients',{'E1','b'},'independent', 't','dependent','depth','options',fo);
[FittedData{k},gof{k}] = fit(DataAll(:,3,k),DataAll(:,1,k),ft1); %{k});
coeffs{k}=coeffvalues(FittedData{k});
end
The error message I receive is:
Error using fittype>iTestCustomModelEvaluation (line 726)
Expression
E1*(YoungMod(k))-b*t
is not a valid MATLAB expression, has non-scalar coefficients, or cannot be evaluated:
Error in fittype expression ==>
(E1*YoungMod(k))-b*t
??? Undefined function 'YoungMod' for input arguments of type 'double'.
To me, it looks like the issue is that the string is reading YoungMod*(k) instead of taking the k value of the YoungMod array. Help is greatly appreciated!
I managed to solve this problem using a dummy variable and the 'problem' option for fittype:
for k=1:size(DataAll,3)
ym = YoungMod(k)
ft = fittype('E1*(ym)-b*t','coefficients',{'E1','b'},'independent', 't','dependent','depth','options',fo,'problem','ym');
[FittedData{k},gof{k}] = fit(DataAll(:,3,k),DataAll(:,1,k),ft,'problem',ym);
coeffs{k}=coeffvalues(FittedData{k});
end
Try this instead to make sure k is evaluated as a variable and not a string:
ft = fittype(['E1*(YoungMod(' num2str(k) '))-b*t'],'coefficients',{'E1','b'},'independent', 't','dependent','depth','options',fo);

Resources