Sorting an array Imperative ocaml - arrays

I'm doing a rather easy example to learn how to use ocaml as an imperative language.
My guess is I messed up with the semicolons but I can't find any mistakes in the code
let sort array =
for index = 0 to (Array.length array -1) do
let boole = ref false;
let pos = ref index;
let max = ref array.(index);
let p = ref !pos;
let m = ref !max;
while !pos <> (Array.lenght array -1 ) do
if array.(!pos) > !max then begin
max := array(!pos);
boole := true;
p := !pos
end
pos := !pos + 1
done;
if (!boole = true) then begin
array.(index) <- max;
array.(pos) <- m
end
done ;;
Thank you.
Edit 1 :
In case someone comes across this question, I'm posting the correct code cause the above didn't sort the array correctly even with the correct syntax:
let sort array =
for index = 0 to (Array.length array -1) do
let boole = ref false in
let pos = ref index in
let max = ref array.(index) in
let p = ref !pos in
let m = ref !max in
for i = !pos to (Array.length array -1) do
if (array.(i) > !max) then begin
pos :=i;
max := array.(!pos);
boole := true;
end;
done;
if (!boole = true) then begin
array.(!pos) <- !m;
array.(!p) <- !max;
end;
done ;;

First off all, there is no let x = y; expression in OCaml, a correct syntax is let x = y in, also you shouldn't forget to dereference your references.
let sort array =
for index = 0 to (Array.length array -1) do
let boole = ref false in
let pos = ref index in
let max = ref array.(index) in
let p = ref !pos in
let m = ref !max in
while !pos <> (Array.length array -1 ) do
if array.(!pos) > !max then begin
max := array.(!pos);
boole := true;
p := !pos
end;
pos := !pos + 1;
done;
if (!boole = true) then begin
array.(index) <- !max;
array.(!pos) <- !m;
end;
done ;;

The following fix in the code may help - at least to get the code compiled - :
let sort toto =
for index = 0 to (Array.length toto - 1) do
let boole = ref false in
let pos = ref index in
let max = ref toto.(index) in
let p = ref !pos in
let m = ref !max in
begin
while !pos <> (Array.length toto - 1 ) do
begin
if (toto.(!pos) > !max) then
begin
max := toto.(!pos);
boole := true;
p := !pos;
end;
pos := !pos + 1;
end
done;
if (!boole = true) then begin
toto.(index) <- !max;
toto.(!pos) <- !m
end
end
done;;
Notably : the declaration of local variable, and also some missing semicolons.
I change the name of the argument (array to toto) - as array is a keyword, but I do not think it is necessary.

Related

how to debug arrays values in pinescript?

I have this script:
strategy("My strategy")
var float start_price = na
var float end_price = na
var float[] start_prices = array.new_float(0)
var float[] end_prices = array.new_float(0)
var float p = na
f(x) => math.round(x / 500) * 500
lo = (high + close) / 2
var i = 0
if bar_index == 1
start_price := f(lo)
end_price := f(start_price * 1.015)
else
if close <= start_price
strategy.entry(str.format("Long {0}",i), strategy.long)
array.push(end_prices, end_price)
array.push(start_prices, end_price)
i := i + 1
start_price := start_price - 500
end_price := f(start_price * 1.015)
for j = 0 to (array.size(end_prices) == 0 ? na : array.size(end_prices) - 1)
p := array.get(end_prices, j)
if close >= p
strategy.exit(str.format("Long {0}",j), limit=end_price)
I want to console/debug/display the values in start_prices array
But I can't figure out for the life of me how to do that, there's no console.log or anything like that. I'm a somewhat competent python programmer, but I always use the print()... Anyway, how do people debug in this language?
You can use the tostring() function (str.tostring() in v5) to generate a string of your array. You can then output it into a label or table.
eg.
start_prices_string = str.tostring(start_prices)
debug = label.new(x = bar_index, y = close, style = label.style_label_left, text = start_prices_string)
label.delete(debug[1])

Argument types problem ('float', 'const int') in array

I've been trying my first codes in pine script. The question is this. I have created few array.new_float to use as buffers in the 'for' statement. The thing is that I need to do some math over the data. Now, once the 'for' is done, an error pops: 'Cannot call 'operator -' with argument 'expr0' = 'High'.An argument of 'float[]' type was used but a 'const int' is expected'.
Please, if anyone knows what am I doing wrong, I will thank you.
Edit: I will leave the script of what I'm trying to do here
//#version=5
// Indicator name
indicator("DAF_Swing_Index", shorttitle= 'DAF_SwInd', overlay=false)
// Input
T = input.int(30000, title = 'Ratio de escala', minval = 1000, maxval = 150000)
Shift = input.int(0, title = 'Desplazamiento horizontal', minval = 0, maxval = 100)
// Array
SWINGINDEX = array.new_float(200)
Open = array.new_float(200)
Open1 = array.new_float(200)
Close = array.new_float(200)
Close1 = array.new_float(200)
High = array.new_float(200)
Low = array.new_float(200)
// Other variable
var float SwingIndex = 0
var int StartBars = 1
Prev_calculated = bar_index
Rates_total = bar_index + 1
var float SH1 = 0
var float SI = 0
var float R = 0
// Initial bar verification
if Rates_total < StartBars
SwingIndex := 0
Primero = 1
if Prev_calculated > Rates_total or Prev_calculated <= 0
Primero := 1
else
Primero := Prev_calculated-1
// Main process
for bar = Primero to Rates_total
array.push(Open, high[bar])
array.push(Open1, open[bar-1])
array.push(Close, close[bar])
array.push(Close1, close[bar-1])
array.push(High, high[bar])
array.push(Low, low[bar])
K = math.max(math.abs(High - Close1), math.abs(Low - Close1))
TR = math.max(math.max(math.abs(High-Close1), math.abs(Low-Close1)), math.abs(High-Low))
ER = 0.0
if Close1 > High
ER := math.abs(High - Close1)
if Close1 < Low
ER := math.abs(Low - Close1)
SH1 := math.abs(Close1 - Open1)
R := TR - 0.5 * ER + 0.25 * SH1
SI := 0.0
if R != 0
SI := 50 * ((Close - Close1) + 0.5 * (Close - Open1)) * (K / T) / R
SwingIndex := SI
// ploting result
plot(SwingIndex, title = 'Swing Index', style = plot.style_line, color = color.rgb(193, 255, 51, 10))
So, what the error message tells you is, your are passing an array, where it expects a const value.
Like here:
K = math.max(math.abs(High - Close1), math.abs(Low - Close1))
All those variables (High, Close1, Low) are arrays. It simply can not subtract one array from another. You can however, subtract one element from another element.
So for that line, I believe you want something like this:
K = math.max(math.abs(array.get(High, bar) - array.get(Close1, bar)), math.abs(array.get(Low, bar) - array.get(Close1, bar)))
With array.get(), you can get value the of the element at the specified index.
You should fix this in all other occurences.

Lua: Search key in table, increment index if not and retry

Situation:
table = { this, that, something else, x_coord, y_coord }
table.x_coord = { 1,2,3,4,7,8,n}
table.y_coord = { 2,4,5,9,n} -- numbers aren't fix
table.check_boxes = { [12] = a function,
[14] = a function,
[15] = a function,
[24] = a function,
[29] = a function,
....(n) }
As you can see, the x/y_coords forming check_boxes. For example:
table.x_coord[1]..table.y_coord[1] ~ table.check_boxes[1]
I use this to move the cursor in the Terminal between the check_boxes.
The problem now is in my cursormovement.
Currently I got a function that's searching for the next x/y_coord to the left/right/up/down depending on the given input (arrow-keys).
With return/space I call the function behind the checkbox.
Now, that could set the Cursor on positions where no check_boxes are given. Actually that's not a big deal, because when input == space/return, an inputhandler calls the function at
table.check_boxes[table.x_coorx[x_index]..table.y_coords[y_index]]
So if the cursor doesn't point on a function, just nothing happens.
But now I want the cursor to be forced to the next check_box. What can I do?
My Idea so far:
following function either for x or y, depending on input left/right up/down:
while true do
for k, v in pairs(table.check_boxes) do
if(table.x_coord[x_index] .. table.y_coord[y_index] == k then break end
end -- break -> okay, coord is at a checkbox
x_index = x_index + 1 -- or -1
if table.x_coord[x_index] == nil then
x_index = 1
end
end
The Problem now is that the last if will not allow cases like x_coord = {1,3} because it will set x_index to 1 if 2 is reached.
Any tips?
Edit:
Now I got that one going:
function cursorTioNextBoxRight()
searc_index = x_index
search = true
while search do
search_index = search_index + 1
if search_index > #table.x_coord then
search_index = 1
end
for k, v in pairs(table.check_boxes) do
if tonumber(table.x_coord[search_index..table.y_coord[y_index] == k then
x_index = search_index -- YAAAY
search = false
break
end
end
end
I'ts damn slow.
local x_newIndex = x_index + 1 --[[ or -1 --]]
x_index = table.x_coord[x_newIndex] and x_newIndex or x_index
x_index becomes x_newIndex when x_newIndex exists in the table otherwise it stays the old x_index
function cursorTioNextBoxRight()
searc_index = x_index
search = true
while search do
search_index = search_index + 1
if search_index > #table.x_coord then
search_index = 1
end
for k, v in pairs(table.check_boxes) do
if tonumber(table.x_coord[search_index..table.y_coord[y_index] == k then
x_index = search_index -- YAAAY
search = false
break
end
end
end

How to use a self made Type in F#?

I made a type, but I don't know how to use it properly and I don't found any solution on google.
type Sample =
{
TrackPosition : int
TubePosition : int
Barcode : string
}
let arraySamples = Array.create Scenario.Samples.NumberOfSamples **Sample**
BarcodeGenerieren.Samples.Sample
let mutable trackPosition = Scenario.Samples.StartTrackPositions
let mutable index = 1
for i in 1 .. Scenario.Samples.NumberOfSamples do
let randomNumber = System.Random().Next(0,9999)
if index > 24 then
trackPosition <- trackPosition + 1
index <- 1
arraySamples.[index] <- **new Sample{TrackPosition= trackPosition, TubePosition = index, Barcode = sprintf "100%s%06d" ((trackPosition + 1) - Scenario.Samples.StartTrackPositions) randomNumber}**
So my question is, what should I changed so that it works, when I will give the type of the array and when I will give the sample with data to the array?
You have created what is referred to as a record type. You can initialise it with the following syntax
{TrackPosition = 0;TubePosition = 0;Barcode = "string"}
your syntax in the last line is almost correct - it should be
arraySamples.[index] <- Sample{
TrackPosition= trackPosition;
TubePosition = index;
Barcode = sprintf "100%s%06d" ((trackPosition + 1) - Scenario.Samples.StartTrackPositions) randomNumber}
The changes are
Eliminate new
replace , with ;

Matlab: stepping through an array and incrementing from one value to the next

I have an array:
step1 = [0,0;
0,1;
1,1;
2,3;
3,4;
3,5;
3,6;
3,7;
4,7;
5,7;
6,7;
6,6;
6,5;
6,4;
6,3;
6,2;
5,1];
I want to step through this array and create new arrays for the row and column that increment by 0.1 from one row to another. This is what I did:
z=1;
u=length(step1);
step_b4X = zeros(u,1);
step_b4Y = zeros(u,1);
while z <= length(step1)
step_b4X = step_presentX;
step_presentX(z,1) = step1(z,1);
step_b4Y = step_presentX;
step_presentY(z,1) = step1(z,2);
pathX = step_b4X:0.1:step_presentX;
pathY = step_b4Y:0.1:step_presentY;
z = z+1;
end
I get zeros.
I want pathX = 0:0.1:0....pathY = 0:0.1:1
next pathX = 0:0.1:1....pathY = 1:0.1:1... and so on
If you do
start:increment:end
where start == end, you'll get a scalar equal to start (which is logical).
If you want pathX and pathY to have the same length at each iteration, you'll have to do this:
z = 1;
while z <= length(step1)
currentX = step(z,1); nextX = step(z+1,1);
currentY = step(z,2); nextY = step(z+1,2);
pathX = currentX : 0.1 : nextX;
pathY = currentY : 0.1 : nextY;
if numel(pathX) == 1
pathX = repmat(pathX, numel(pathY),1); end
if numel(pathY) == 1
pathY = repmat(pathY, numel(pathX),1); end
z = z+1;
end
Now you'll have the right arrays at each iteration, that you'll use directly or save in a cell-array for later. If you want everything in one big array, add this to the end of the loop:
pathX_final = [pathX_final; pathX];
pathY_final = [pathY_final; pathY];
and initialize them as empty before the loop, of course.
Alternatively (much cleaner and possibly a bit faster), ditch the whole loop and use interp1:
x = step1(:,1);
y = step1(:,2);
xx = interp1(1:numel(x), x, 1:0.1:numel(x));
yy = interp1(1:numel(y), y, 1:0.1:numel(y));

Resources