Помимо ошибки, которую вы получаете, я вижу еще несколько ошибок новичка в вашем коде.Я перечислю их все для вас.
Сначала вы создаете две последовательности с именами arr1
и arr2
, а затем обращаетесь к ним по индексу в цикле.Я сильно подозреваю, что вы подразумевали, что они являются массивами, потому что доступ к последовательности по индексу - это операция O (N), тогда как доступ к индексу массива - это O (1).Таким образом, ваш цикл на данный момент O (N ^ 2), и он должен быть O (N).Чтобы это исправить, добавьте вызов к Array.ofSeq
после Seq.take cnt
при создании arr1
и arr2
:
let arr1 = r.GetValues(1, 262144) |> Seq.take cnt |> Array.ofSeq
let arr2 = r.GetValues(1, 262144) |> Seq.take cnt |> Array.ofSeq
Во-вторых, вы создаете массив, вызывая Array2D.init
сфункция инициализации, которая всегда возвращает 0. Существует гораздо более быстрый способ сделать это: вызвать Array2D.zeroCreate
.Использование Array2D.init
вызовет вашу функцию dispreso * dispreso
раз, тогда как Array2D.zeroCreate
исключит все эти вызовы функций.В любое время, когда вы хотите инициализировать массив нулем (или значением по умолчанию любого типа в массиве), всегда используйте функцию zeroCreate
, поскольку она является наиболее эффективной.
Далее эта строканичего не делает:
dat.[x, y] + 1
Я предполагаю, что вы хотите увеличить значение, сохраненное в 2D-массиве в позиции x, y
.Но эта строка извлекает значение, добавляет к нему 1 и выдает результат, который отбрасывается, поскольку он нигде не сохраняется и не используется в каких-либо вычислениях.(Возможно, у вас есть предупреждение компилятора об этой строке, говорящее что-то вроде «Это значение эффективно игнорируется» и говорящее вам, чтобы это исправить).Вы хотели сохранить это значение обратно в массив следующим образом:
dat.[x, y] <- dat.[x, y] + 1
Наконец, причина вашей ошибки "незавершенного блока" заключается в том, что строка dat.[x, y] + 1
имеет слишком большой отступ, поэтомунет заявления сразу после let y = ...
строки.Это синтаксическая ошибка в F #: после оператора let
всегда должно быть что-то.Простое отступление строки dat.[x, y] + 1
даст вам правильные результаты.
Вот ваш код со всеми исправленными ошибками:
type System.Random with
/// Generates an infinite sequence of random numbers within the given range.
member this.GetValues(minValue, maxValue) =
Seq.initInfinite (fun _ -> this.Next(minValue, maxValue))
let cnt = 10000
let r = System.Random()
let arr1 = r.GetValues(1, 262144) |> Seq.take cnt |> Array.ofSeq
let arr2 = r.GetValues(1, 262144) |> Seq.take cnt |> Array.ofSeq
let datareso = 262144
let dispreso = 64
let bucketsiz = datareso / dispreso
let Contour =
let dat = Array2D.zeroCreate dispreso dispreso
for idx in 0 .. cnt-1 do
let x = System.Math.Round(arr1.[idx] / bucketsiz)
let y = System.Math.Round(arr2.[idx] / bucketsiz)
dat.[x, y] <- dat.[x, y] + 1
dat