Home > OS >  Converting java.util.function.Function to kotlin
Converting java.util.function.Function to kotlin

Time:01-30

The java code :

public class Neuron implements Comparable<Neuron>, Serializable {

public interface Activation extends Function<Float, Float>, Serializable {
    Activation SIGMOID = z -> 1 / (1   (float) Math.exp(-z));
    Activation LINEAR = z -> z;
    Activation TANH = x -> (float) Math.tanh(x);
}
...

somehow, i managed to translate it to this kotlin code (with the help of various answer i found on stackoverflow) :

class Neuron(
val id: Int,
val inputs: Array<Neuron?>,
val weights: FloatArray,
var type: Type?,
private var activation: (Float) -> Float,
val label: String?
) : Comparable<Neuron>, Serializable {

interface Activation : Function<Float?, Float?>, Serializable {
    companion object {
        val SIGMOID = fun(z: Float): Float { return 1 / (1   exp(-z)) }
        val LINEAR = fun(z: Float): Float { return z }
        val TANH = fun(x: Float): Float  { return tanh(x) }
    }
}

I'm probably doing it wrong and i still have some error when i try to use it. The very good news is that, while my code is still a mix of java and kotlin, this code is only called by kotlin code. So there could be a way to solve it all in a proper way.

I fixed a lot of stuff here and there to fix argument type in various method/function but i'm stuck with this one :

fun tick() {
    nextState = 0.0f
    for (i in inputs.indices) nextState  = inputs[i]!!.state * weights[i]
    nextState = activation!!.apply(nextState)!!
}

the errors, on the same line :

Type mismatch: inferred type is (Float) -> Float but Float? was expected
Type mismatch: inferred type is Float but TypeVariable(T).() -> Unit was expected

The first error is probably related to the type of "nextState" (which is indeed a Float), but apply is supposed to return a Float so i assume that solving the 2nd error will fix the 1st one. I don't understand the 2nd error.

Considering that SIGMOID, LINEAR, TANH, are (as far as i know) only called from Kotlin code, is there a way to fix it all in a graceful way ?

A temporary fix i just found :

nextState = activation.invoke(nextState)

is this the proper way to solve it all ? is there perhaps a nicer solution without interface and companion ? should i leave it as is and call it a day ?

CodePudding user response:

If you are working in android studio then a good way is to just copy the java code into a Kotlin file. You will be prompted to turn the code into kotlin. This worked for me when I had to copy code from online. I hope this works for you.

CodePudding user response:

You can drop this Activation interface in Kotlin because you never use it.

Instead you said in code you want your var activation to be of type (Float) -> Float. So you can do it like this

val SIGMOID: (Float) -> (Float) = { 1 / (1   exp(-it)) }
...

Oh, and then you can use activation(...) syntax.

CodePudding user response:

Probably change to

interface Activation : (Float?) -> Float?, Serializable {
  
}

Then the instances

 companion object {
        val SIGMOID = (Float) -> Float = { return 1 / (1   exp(-z)) }
        val LINEAR = (Float) -> Float =  { return z }
        val TANH = (Float) -> Float =   { return tanh(x) }
    }

and usage to

activation(nextState)

which is equvalent to .invoke(nextState)

CodePudding user response:

I am answering my own question since the full, clean, solution is a mixture of multiple answers and comments.


I replaced nextState = activation!!.apply(nextState)!!

with nextState = activation(nextState)

using nextState = activation.invoke(nextState) also worked but wasn't necessary.


I replaced

interface Activation : Function<Float?, Float?>, Serializable {
    companion object {
        val SIGMOID = fun(z: Float): Float { return 1 / (1   exp(-z)) }
        val LINEAR = fun(z: Float): Float { return z }
        val TANH = fun(x: Float): Float  { return tanh(x) }
    }
}

with

interface Activation : (Float) -> Float, Serializable {
    companion object {
        val SIGMOID: (Float) -> (Float) = { 1 / (1   exp(-it)) }
        val LINEAR : (Float) -> (Float) = { it }
        val TANH   : (Float) -> (Float) = { tanh(it) }
    } 
}

And got rid of the java import.


Then i realized that i didn't need this interface since it was only called from Kotlin code.

I changed all reference to the Activation type to (Float) -> Float and removed the interface. I already had a companion object declared in this class so i moved it all in this companion object.

companion object {
    private const val serialVersionUID = 1L  // this one was already there
    val SIGMOID: (Float) -> (Float) = { 1 / (1   exp(-it)) }
    val LINEAR : (Float) -> (Float) = { it }
    val TANH   : (Float) -> (Float) = { tanh(it) }
}

I changed all my reference to theses function from Neuron.Activation.LINEAR to Neuron.LINEAR

eg :

var defaultActivation = Neuron.Activation.LINEAR // with interface
var defaultActivation = Neuron.LINEAR // without interface

Thank you everyone. I hope this will help, it seems to be a common problem because intellij failed to convert automatically this kind code from java to kotlin using the builtin functionality.

  • Related