royer
royer

Reputation: 645

how to autogenerate array in kotlin similar to numpy?

hello let me do a demonstration in python about what I want to achieve in kotlin:

np.linspace(start = 0, stop = 100, num = 5)

This results:

-------------------------
|0 | 25 | 50 | 75 | 100 |
-------------------------

Now in Kotlin how can I get the same result? Is there a similar library?

Upvotes: 3

Views: 1252

Answers (3)

Alexey Romanov
Alexey Romanov

Reputation: 170745

DoubleProgression used to exist but was removed, because it raises rounding issues; you can copy the sources from that commit as a starting point if you really need it. Or consider converting it to a BigDecimalProgression instead. Of course, you need division to get the step from your arguments, which isn't exact even for BigDecimal.

You can also use sequences:

fun linspaceD(start: Double, stop: Double, num: Double): Sequence<Double> {
    val step = (stop - start) / (num - 1)
    return sequence {
        for i in 0 until num yield(start + step*i)
    }
}

Note that this resolves rounding in a specific way, by always yielding num values even if the last one is slightly greater than stop.

Upvotes: 2

Rene Ferrari
Rene Ferrari

Reputation: 4206

This should work exactly like linspace (not handling cases when num is 0 or 1):

fun linspace(start: Int, stop: Int, num: Int) = (start..stop step (stop - start) / (num - 1)).toList()

It makes use of the rangestart..stop (a range in kotlin is inclusive) and the function step lets us define how far the steps in this ranges should be.

EDIT
As @forpas suggested in the comments the step should be calculated using (stop - start) and not only stop. Using stop alone would only work if the start was 0.

@Alexey Romanov correctly said that unless you explicitly need a List as return type you should return the IntProgression (it does not hold all the elements in memory like a list does) since its also Iterable.

Thank you both for your input!

Upvotes: 5

forpas
forpas

Reputation: 164099

Not exactly the same, but it generates an array with 5 integers, multiples of 25 starting from 0:

val array = Array(5) { it * 25  }

the result is:

[0, 25, 50, 75, 100]

You can create a function simulating what you need:

fun linspace(start: Int, stop: Int, num: Int) = Array(num) { start + it * ((stop - start) / (num - 1)) }

Upvotes: 4

Related Questions