0

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 ?

4 Answers 4

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

i'm in intellij idea. i am indeed using this conversion feature, but the conversion failed for this part and generated erroneous code.
Maybe you can try with one of the online editors?
1

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.

5 Comments

thiank you, i like this syntax. if i remove the interface, how do i make a reference to it ? exemple of existing code : var defaultActivation = Neuron.Activation.LINEAR
@ker2x if it's located inside companion of Neuron, then just Neuron.LINEAR. If you're referring to it inside Neuron itself, then just LINEAR
i get some error about conflicting declaration if i keep the companion object and just remove the interface. i don't really understand what's happening. i'll leave it as is for now. finish my conversion to full kotlin (i still have a lot of java code here and there) and the proceed to cleanup and make it proper kotlin code instead of semi-automated conversion from java. thank you for your help.
@ker2x If you remove Activation. from every reference then it should work without interface just fine
i found the problem. there was a 1 line companion object already declared (at the very bottom) in this class. Hence the conflicting declaration error. i moved the 3 lines inside the already declared companion object and that solved the error. I also removed the reference to Activation as well, of course :)
0

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)

2 Comments

thank you, now i don't have to import java.util.function.Function anymore. calling activation directly also worked. about the function itself, is there a difference with the conversion i provided or is it purely syntaxic sugar ? i find my val = fun easier to understand (probably because of my C/C++ background, this function pointer-ish style look more intuitive to me (i can't believe i'm writting this))
The problem with both of these versions is that they produce function objects, not instances of the Activation interface. (Note also that you probably shouldn't have return.)
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.