Java-версия Matlab's Linspace - PullRequest
4 голосов
/ 02 июня 2011

Существует ли Java-версия оператора двоеточия Matlab или linspace? Например, я хотел бы сделать цикл for для равномерно распределенных чисел, но я не хочу беспокоиться о создании массива этих чисел вручную.

Например, чтобы получить все целые числа от 1 до 30, в matlab я набрал бы:

1:30

или

linspace(1,30)

Ответы [ 6 ]

5 голосов
/ 02 июня 2011

Для вызова двух переменных @ x4u является правильным.Вызов трех переменных будет немного сложнее эмулировать.

Например, я думаю, что linspace (1,30,60) должно выдавать значения 1, 1,5, 2, 2,5, 3, 3,5 ...или, может быть, это значения для linspace (1,30,59) - в любом случае, та же проблема.

С этим форматом вам придется делать вычисления самостоятельно - лично я бы создал новыйобъект, чтобы сделать все это для меня и забыть цикл for.

counter=new Linspace(1,30,60);
while(counter.hasNext()) {
    process(counter.getNextFloat())
}

или просто

while(float f : new Linspace(1,30,60)) {
    process(f);
}

, если ваш объект Linspace реализует Iterable.

Тогдавнутренняя часть объекта counter должна быть достаточно очевидна для реализации, и она будет легко сообщать вам, что он делает, не запутывая ваш код кучей числовых вычислений для выяснения соотношений.

Реализация может быть чем-то вродеэто: (ПРИМЕЧАНИЕ: не проверено, и я уверен, что это будет уязвимо для крайних случаев и ошибок с плавающей запятой! Вероятно, он также не будет обрабатывать end

public class Linspace {
    private float current;
    private final float end;
    private final float step;
    public Linspace(float start, float end, float totalCount) {
        this.current=start;
        this.end=end;
        this.step=(end - start) / totalCount;
    }
    public boolean hasNext() {
        return current < (end + step/2); //MAY stop floating point error
    }
    public float getNextFloat() {
        current+=step;
        return current;
    }
}
3 голосов
/ 23 июля 2013

Мне просто нужно было сделать это для проекта Java, над которым я работаю.Я хотел убедиться, что он реализован так же, как в MATLAB, поэтому я сначала написал эквивалент MATLAB:

function result = mylinspace(min, max, points)  
answer = zeros(1,points);  
    for i = 1:points  
answer(i) = min + (i-1) * (max - min) / (points - 1);  
end  
result = answer;  

Я проверил это по встроенной функции linspace и вернул правильный результат,поэтому я затем преобразовал это в статическую функцию Java:

public static double[] linspace(double min, double max, int points) {  
    double[] d = new double[points];  
    for (int i = 0; i < points; i++){  
        d[i] = min + i * (max - min) / (points - 1);  
    }  
    return d;  
}  

На мой взгляд, это гораздо проще, чем создать новый класс для этой функции.

3 голосов
/ 02 июня 2011

Вы хотите сделать это?

for( int number = 1; number <= 30; ++number )

Если вам нужно, чтобы они были разнесены на фиксированную сумму, т.е. 3, вы можете написать это следующим образом:

for( int number = 1; number <= 30; number += 3 )

Левая часть цикла for инициализирует переменную, средняя часть - это условие, которое оценивается перед каждой итерацией, а правая часть выполняется после каждой итерации.

1 голос
/ 19 июля 2011

Я сам искал решение этой проблемы и исследовал, как MatLab реализует свое Linspace. Я более или менее преобразовал это в Java и закончил с методом ниже. Насколько я тестировал, он работает довольно хорошо, и вы получаете конечные точки. Вероятно, есть ошибки с плавающей запятой, как в большинстве случаев.

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

public static List<Double> linspace(double start, double stop, int n)
{
   List<Double> result = new ArrayList<Double>();

   double step = (stop-start)/(n-1);

   for(int i = 0; i <= n-2; i++)
   {
       result.add(start + (i * step));
   }
   result.add(stop);

   return result;
}
0 голосов
/ 20 января 2014

Вот основной алгоритм, который работает для matlab, вы можете преобразовать его в Java со всеми деталями ООП в вашем распоряжении:

>>> st=3;ed=9;num=4;
>>> linspace(st,ed,num)

ans =

     3     5     7     9
>>> % # additional points to create (other than 3)
>>> p2c=num-1;
>>> % 3 is excluded when calculating distance d.
>>> a=st;
>>> d=ed-st;
>>> % the increment shall calculate without taking the starting value into consideration.
>>> icc=d/p2c;

>>> for idx=[1:p2c];
a(idx+1)=a(idx)+icc;
end;
>>> a

a =

     3     5     7     9

>>> diary off
0 голосов
/ 02 июня 2011

Я думаю, что Билл К. правильно понял, но я думаю, что нет необходимости иметь класс Linspace.

// If you write linspace(start,end,totalCount) in Matlab ===>

for(float i = start; i < end; i += (end-start)/totalCount)
    something(i);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...