Создание Array2D из значений значений двух разных массивов - PullRequest
0 голосов
/ 15 ноября 2018

У меня проблемы с получением правильного кода. Результатом переменной Contour должен быть Array2D 64x64, содержащий данные для контура arr1 от arr2. Я сделал два массива случайными для примера. Синтаксическая ошибка говорит о том, что блок, следующий за последним let, не завершен.

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
let arr2 = r.GetValues(1, 262144) |> Seq.take cnt

let datareso = 262144
let dispreso = 64
let bucketsiz = datareso / dispreso

let Contour = 
        let dat = Array2D.init dispreso dispreso (fun i j -> 0)
        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] + 1
        dat

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Помимо ошибки, которую вы получаете, я вижу еще несколько ошибок новичка в вашем коде.Я перечислю их все для вас.

Сначала вы создаете две последовательности с именами 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
0 голосов
/ 15 ноября 2018

Под этой строкой:

    dat.[x, y] + 1

Вы имели в виду нечто подобное:

    dat.[x, y] <- dat.[x, y] + 1

Я заметил, что в вашем тексте в этой строке есть странный начальный пробел.

...