Как использовать случайное число из распределения Вейбулла?

Я пытаюсь разместить распределенные случайные числа Вейбулла в секторе круга.

Я сгенерировал случайное число, а затем распределил его по распределению Вейбулла. Теперь я хочу использовать эти распределенные по Вейбуллу случайные числа.

RadarSpace GetWeibullClutter()
{ 
    Random _randomNumberGenerator = new Random();
    Weibull myweibull = new Weibull(3,2,_randomNumberGenerator);

    int n = 50; // number of clutter elements
    var maxRange = _detectionModel.MaximumRange;
    var centreX = 0; // Centre of the field of view -- X coordinates
    var centreY = 0; // Centre of the field of view -- Y coordinates

    var minimumAngle = Math.PI / 4; // _detectionModel.MinimumPhi;
    var maximumAngle = (3 * Math.PI) / 4; // _detectionModel.MaximumPhir;

    var theta = (maximumAngle - minimumAngle) * myweibull + minimumAngle;
    var r = maxRange * Math.Sqrt(_randomNumberGenerator.Next(n));

    var x = centreX + r * Math.Cos(theta);
    var y = centreY + r * Math.Sin(theta);

Я хочу, чтобы распределенное случайное число Вейбулла умножалось на var theta, но оно скорее говорит

оператор «*» не может применяться к операндам типа «double» и «weibull»

обновленный код

RadarSpace GetWeibullClutter()
            { 
                Random _randomNumberGenerator = new Random();
                Weibull myweibull = new Weibull(3,2,_randomNumberGenerator);

                int n = 50; // number of clutter elements
                var maxRange = _detectionModel.MaximumRange;
                var centreX = 0; // Centre of the field of view -- X coordinates
                var centreY = 0; // Centre of the field of view -- Y coordinates

                var minimumAngle = Math.PI / 4; // _detectionModel.MinimumPhi;
                var maximumAngle = (3 * Math.PI) / 4; // _detectionModel.MaximumPhir;

                var theta = 0.0;
                var r = 0.0;

                var randomNumbers = new double[n];
                myweibull.Samples(randomNumbers);
                for (int i = 0; i < n; i++)
                {
                    theta = (maximumAngle - minimumAngle) * randomNumbers[i] + minimumAngle;
                    r = maxRange * Math.Sqrt(randomNumbers[i]);
                }
                //var theta = (maximumAngle - minimumAngle) * myweibull.Sample() + minimumAngle;
                //var r = maxRange * Math.Sqrt(_randomNumberGenerator.Next(n));

                var x = centreX + r * Math.Cos(theta);
                var y = centreY + r * Math.Sin(theta);

person Muhammad Shaheer Munir    schedule 31.01.2019    source источник
comment
Откуда взялся класс Weibull? Math.NET Числа?   -  person Sentry    schedule 31.01.2019
comment
я думаю, что это исправлено var time = (maximumAngle - minimumAngle) * myweibull.RandomSource.NextDouble() + minimumAngle;, но не уверен. подскажите пожалуйста правильный путь или нет?   -  person Muhammad Shaheer Munir    schedule 31.01.2019
comment
@Часовой, да. я использую Math.Net   -  person Muhammad Shaheer Munir    schedule 31.01.2019
comment
@Sentry, не могли бы вы еще раз взглянуть?   -  person Muhammad Shaheer Munir    schedule 31.01.2019
comment
Ваш обновленный код синтаксически в порядке, но, не зная, что вы хотите вычислить, трудно определить, является ли он правильным. Что должны представлять time и r? Являются ли они независимыми переменными? Они оба распределены по Вейбуллу? С теми же параметрами?   -  person Sentry    schedule 31.01.2019
comment
@Sentry, не могли бы вы взглянуть на нижнюю часть страницы здесь: de.mathworks.com/matlabcentral/answers/ Это то, что я хочу сделать в С#   -  person Muhammad Shaheer Munir    schedule 31.01.2019


Ответы (1)


Похоже, вы используете библиотеку Math.NET Numerics. класс распределения Weibull реализует IContinuousDistribution интерфейс, который предлагает свойства и методы:

double Mode { get; }
double Minimum { get; }
double Maximum { get; }
double Density(double x);
double DensityLn(double x);
double Sample();
void Samples(double[] values);
IEnumerable<double> Samples();

Ваша переменная myweibull содержит экземпляр класса Weibull, поэтому вы не можете умножить его на double.

Вы сказали, что сгенерировали случайное число, но это не так. Для этого используйте метод Sample():

var theta = (maximumAngle - minimumAngle) * myweibull.Sample() + minimumAngle;

Это даст вам одно случайное число, распределенное Вейбуллом. Если вам нужно больше случайных чисел, либо повторно вызовите Sample():

for( int i = 0; i < n; i++ )
{
    var theta = (maximumAngle - minimumAngle) * myweibull.Sample() + minimumAngle;
    ...
}

или сгенерируйте сразу несколько случайных чисел, используя Samples()

var randomNumbers = new double[n];
myweilbull.Samples(randomNumbers);
for( int i = 0; i < n; i++ )
{
    var theta = (maximumAngle - minimumAngle) * randomNumbers[i] + minimumAngle;
    ...
}

Изменить для обновленного вопроса

Для вашей задачи r и theta должны быть независимыми, иначе угол и радиус будут полностью коррелированы, и все сгенерированные точки будут на одной линии.

for( int i = 0; i < n; i++ )
{
    var theta= (maximumAngle - minimumAngle) * myweibull.Sample() + minimumAngle;
    var r = maxRange * Math.Sqrt( myweibull.Sample() );

    var x = centreX + r * Math.Cos(theta);
    var y = centreY + r * Math.Sin(theta);

    // Do something with your generated point (x, y)
}

Если вы просто сгенерируете 50 случайных значений для theta и r, но вычислите x и y только один раз, у вас будет только одна случайная точка.

Но мне все еще интересно, чего вы пытаетесь достичь, потому что очки не будут равномерно распределены в секторе, а распределены по Вейбуллу.

person Sentry    schedule 31.01.2019
comment
Ok. а как насчет следующей строки var r = maxRange * Math.Sqrt(_randomNumberGenerator.Next(n));, так как я хочу, чтобы она также была случайным образом распределена по Вейбуллу. как я могу заменить Next(n) ? - person Muhammad Shaheer Munir; 31.01.2019
comment
Вы хотите, чтобы r также распространялся Weibull? Используя то же распределение Вейбулла (с теми же параметрами)? Просто позвоните myweibull.Sample() еще раз - person Sentry; 31.01.2019
comment
да, я использую это в цикле для генерации обоих, как вы сказали, например, ``` var randomNumbers = new double[n]; myweilbull.Samples(randomNumbers); for (int i = 0; i ‹ n; i++) { var time = (максимальный угол - минимальный угол) * randomNumbers[i] + минимальный угол; var r = maxRange * Math.Sqrt(randomNumbers[i]); } ``` но теперь он говорит The name ''Weibull'' doesnot exist in the current context - person Muhammad Shaheer Munir; 31.01.2019
comment
@MuhammadShaheerMunir Похоже, вы случайно удалили импорт или что-то подобное. Трудно прочитать этот код в комментарии. Пожалуйста, либо добавьте информацию к своему вопросу, либо (если это другая проблема) создайте новый вопрос. - person Sentry; 31.01.2019
comment
@MuhammadShaheerMunir Кроме того, теперь вы используете одно и то же случайное число несколько раз, что, вероятно, не то, что вам нужно. Может быть, вы могли бы уточнить, что вы хотите сделать в своем вопросе. - person Sentry; 31.01.2019
comment
не могли бы вы сказать мне, исправлена ​​​​ли проблема того же случайного числа в обновленном коде или нет? - person Muhammad Shaheer Munir; 31.01.2019
comment
Это не фиксировано, вы используете один и тот же номер randomNumbers[i] несколько раз. Я предлагаю вам генерировать их по мере необходимости с помощью myweibull.Sample(). Но это действительно зависит от чего вы хотите - person Sentry; 31.01.2019
comment
я хочу создать, предположим, 50 случайных чисел Вейбулла в секторе круга, как в de.mathworks.com/matlabcentral/answers/ взгляните на нижнюю часть страницы, на которой может объяснить, что я хочу сделать. есть изображение, которое может объяснить - person Muhammad Shaheer Munir; 31.01.2019