Converting java.util.function.Function to kotlin - kotlin

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 ?

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.

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.

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)

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

Type mismatch: inferred type is Double but (Double) -> Double was expected

I am working on a solution for the Temperature Control Problem. It is one of the problems in Kotlin learning fundamentals. So for the thrid argument inside printFinalTemprature function, I am passing a function called conversionFormula but what ever I do, I kept getting the type mismatch error. What am I missing?
fun main() {
var temp : Double = 10.0
fun celsiusToFahrenheit(celsius : Double): Double {
return 9/5 * (celsius) + 32
}
fun kelvinToCelsius(kelvin : Double):Double {
return kelvin - 273.15
}
fun conversionFormula(fahrenheit: Double): Double {
var fiveNine :Double = 0.56
var result :Double = (fiveNine*(fahrenheit - 32.0) + 273.15)
return result
}
printFinalTemperature(temp, "Kelvin", "Celsius", conversionFormula(temp))
}
fun printFinalTemperature(
initialMeasurement: Double,
initialUnit: String,
finalUnit: String,
conversionFormula: (Double) -> Double
) {
val finalMeasurement = String.format("%.2f", conversionFormula(initialMeasurement)) // two decimal places
println("$initialMeasurement degrees $initialUnit is $finalMeasurement degrees $finalUnit.")
}
You just need to switch how you are passing the function. Everything is an expression in Kotlin, and since your printFinalTemperature expects a function as the final argument, you have 2 ways to accomplish this.
The first is to use the function reference with ::. This will only work if the function you are referencing has the same expected signature, so in this case (Double) -> Double. You can try changing one of the Double to Int and you'll see how it breaks.
printFinalTemperature(temp, "Kelvin", "Celsius", ::conversionFormula)
Secondarily, you can pass in a lambda as the final argument, allowing it to "infer" that the function is the correct signature.
printFinalTemperature(temp, "Kelvin", "Celsius") {
conversionFormula(it)
}
In this case, the it comes from the lambda as the default argument name. You could give it an explicit name such as:
printFinalTemperature(temp, "Kelvin", "Celsius") { newTemp ->
conversionFormula(newtemp)
}

app\src\main\kotlin\KotlinApp.kt: (48, 34): Expression 'f[2]' of type 'Any' cnvoked as a function. The function 'invoke()' is not found

I have been running an algorithm that is designed to take a postfix expression and return the evaluated value.
To carry out the individual functions, I designed an array of lists that basically functions as:
string representation of operation: String, values taken (-1): Integer, function describing what to do: Float
I wrote this as
val functions = arrayOf<List<Any>>(
listOf("+",1,fun (i:List<Float>):Float = i[0] + i[1]),
listOf("-",1,fun (i:List<Float>):Float = i[0] - i[1]),
// etc (rest of them are currently commented out)
)
On compiling this I got the error:
app\src\main\kotlin\KotlinApp.kt: (48, 34): Expression 'f[2]' of type 'Any' cnvoked as a function. The function 'invoke()' is not found
This is referring to how I call f[2](temp:List<Float>) at element f of the array.
I recognise the error here is how as my lists are of type any, the functions inside them aren't assumed to be functions by the compiler. But as I obviously can't cast these to a function, I'm at a loss.
I have tried using lambda expressions instead of anonymous single-expression functions, i.e.
val functions = arrayOf<List<Any>>(
listOf("+",1,i : List<Float> -> i[0] + i[1],
listOf("-",1,i : List<Float> -> i[0] - i[1]),
// etc
)
But as I'm not particularly familiar with lambdas, I don't know whether I did it correctly.
Any help would be appreciated
Full KotlinApp.kt file:
package gradleMain;
import org.shuntingyard.sya
import kotlin.math.*
import java.util.Stack
class KotlinApp {
val functions = arrayOf<List<Any>>(
listOf("+",1,fun (i:List<Float>):Float = i[0] + i[1]),
listOf("-",1,fun (i:List<Float>):Float = i[0] - i[1]),
// listOf("*",1,{ i : List<Float> -> i[0]*i[1]}),
// listOf("/",1,{ i : List<Float> -> i[0]/i[1]}),
// listOf("^",1,{ i : List<Float> -> i[0].pow(i[1])}),
// listOf("sin",0,{ i : List<Float> -> sin(i[0])}),
// listOf("cos",0,{ i : List<Float> -> cos(i[0])}),
// listOf("tan",0,{ i : List<Float> -> tan(i[0])}),
// listOf("asin",0,{ i : List<Float> -> asin(i[0])}),
// listOf("acos",0,{ i : List<Float> -> acos(i[0])}),
// listOf("atan",0,{ i : List<Float> -> atan(i[0])}),
// listOf("sinh",0,{ i : List<Float> -> sinh(i[0])}),
// listOf("cosh",0,{ i : List<Float> -> cosh(i[0])}),
// listOf("tanh",0,{ i : List<Float> -> tanh(i[0])}),
// listOf("fact",0, /* TODO: Need to incorporate gamma function, once established integrals" */ ),
// listOf("int",1,/* TODO: Incorporate integrals */),
// listOf("dif",1,/* TODO: Incorporate differentiation */),
// listOf("log",0,{ i : List<Float> -> log(i[0], 10F)}),
// listOf("ln",0,{ i : List<Float> -> ln(i[0])}),
// listOf("sqrt",0,{ i : List<Float> -> i[0].pow(0.5F)}),
// listOf("sec",0,{ i : List<Float> -> 1/cos(i[0])}),
// listOf("csc",0,{ i : List<Float> -> 1/sin(i[0])}),
// listOf("cot",0,{ i : List<Float> -> 1/tan(i[0])})
)
fun calculate(eq:List<String>):Float{ // takes the rpn of the equation and returns the result
var operand: Stack<String> = Stack()
var temp = listOf<Float>()
for(i in eq){
var n = false
for(f in functions){
if(i==f[0]){
val x: Int = f[1].toString().toInt()
for(j in 0..x){
temp+=operand.pop().toFloat()
}
operand.push(f[2](temp))
n = true
break;
}
}
if(!n){ // when i isnt an operator/function
operand.push(i)
}
}
val result = operand.peek().toFloat()
return result
}
}
fun main(){
val k = KotlinApp()
val e = sya(" 3 + 7 - 2") // runs shunting yard algorithm on equation
val f = k.calculate(e)
println("$f")
}
Note: I didnt look at your logic. Helping just to solve your problem of accessing function.
So here is the thing.
Instead of List of List, you can use Triple object which will help to hold the type of the variable.Since you have only three items in inner list triple might suits you. Because the inner list you are having of multiple types. So you can do typecasting , but it is not recommended.
You can define a function type using TypeAlias for better readability.
Calculate function:
fun calculate(eq:List<String>):Float{ // takes the rpn of the equation and returns the result
var operand: Stack<String> = Stack()
val temp = mutableListOf<Float>()
for (i in eq){
var n = false
for (f in functions){
if (i == f.first){
val x: Int = f.second.toString().toInt()
for(j in 0..x){
temp+=operand.pop().toFloat()
}
operand.push(f.third(temp).toString()) // Float to String
n = true
break
}
}
if(!n){ // when i isnt an operator/function
operand.push(i)
}
}
val result = operand.peek().toFloat()
return result
}
Custom type of the function:
typealias MyFunctionType = (a:List<Float>) -> Float
List of functions:
val functions = arrayListOf<Triple<String,Int,MyFunctionType>>(
Triple("+",1,fun (i:List<Float>):Float = i[0] + i[1]),
Triple("-",1,fun (i:List<Float>):Float = i[0] + i[1])
)

Kotlin: How to define a variable whose type depends on the input?

I have a function in Kotlin which takes a particular string as input. Depending on the input, I want to create a variable of a specific type and do some computations on it.
For example,
fun compute(input: String): Any{
if(input=="2d"){
var point: Point2D;// Points2D - x: int, y: int
//initilize and do some computations
return point.findDistanceFromOrigin()
}else if(input=="2d-1"){
var point: Point2DWithP1AsOrigin;// Point2DWithP1AsOrigin - x: int, y: int
//initilize and do some computations
return point.findDistanceFromOrigin()
}else if(input=="2d-2"){
var point: Point2DWithP2AsOrigin;
//initilize and do some computations
return point.findDistanceFromOrigin()
}
.
.
.
}
You can see in the above example, I want to initilize the type of point depending on the input and do computation and return.
All the if-else conditions have the same code except for the definition of the variable. How can I put all this in a single block with something like this:
var point: if(input=="2d) Point2D::class else if(input=="2d-1") Point2DWithP1AsOrigin::class.....
How can I do that?
You could do something like this
fun compute(input: String): Any{
val point: MyPoint = when(input) {
"2d" -> Point2D()
"2d-1" -> Point2DWithP1AsOrigin()
"2d-2" -> Point2DWithP2AsOrigin()
else -> Point2D() //fallback is necessary
}
//initilize and do some computations
return point.findDistanceFromOrigin()
}
But then it's essential that all those classes share the same interface. Because they need to have the same methods in order to do the same operations on them.
For example like this:
class Point2D : MyPoint {
override fun findDistanceFromOrigin() = 5
}
class Point2DWithP1AsOrigin : MyPoint{
override fun findDistanceFromOrigin() = 6
}
class Point2DWithP2AsOrigin : MyPoint{
override fun findDistanceFromOrigin() = 7
}
interface MyPoint {
fun findDistanceFromOrigin() : Int
}
You can store constructor references and then invoke required one
fun main() {
val constructors = mapOf(
"2d" to ::Point2D,
"2d-1" to ::Point2DWithP1AsOrigin,
"2d-2" to ::Point2DWithP2AsOrigin,
)
val type = "2d-2"
val constructor = constructors[type] ?: throw IllegalArgumentException("$type not supported")
val point = constructor()
println(point::class)
}
Output
class Point2DWithP2AsOrigin

How do I need to write the 3rd line - Not enough information to infer type variable T

I'm new to Kotlin and try to convert a project from Java to Kotlin
I just need one last step and I don't understand what's going on :(
I'm getting a Not enough information to infer type variable T on model.predict call
override fun link(word: String): LinkSuggestion {
val input: DoubleArray = gramToInt.toArray(word)
val output: Array<Any> = model.predict(input)
// ~~~~~~~ Not enough information to infer type variable T
val maxPredictionIndex: Int = (output[output.size - 1] as Long).toInt()
val maxPredictionProbability: Double = output[maxPredictionIndex] as Double
return LinkSuggestion(word, intToLink.fromInt(maxPredictionIndex), maxPredictionProbability)
}
where model is import org.pmml4s.model.Model
The previous Java code:
#Override
public LinkSuggestion link(String word) {
double[] input = gramToInt.toArray(word);
Object[] output = model.predict(input);
int maxPredictionIndex = ((Long) output[output.length - 1]).intValue();
double maxPredictionProbability = (Double) output[maxPredictionIndex];
return new LinkSuggestion(word, intToLink.fromInt(maxPredictionIndex), maxPredictionProbability);
}
I needed to write
val output: Array<Any> = model.predict<Any>(input)

Is there a sumBy equivalent for multiplication?

I have an array of classes with values. E.g.
class MyData(val value: Double)
class MyClass(val values: List<MyData>)
it's pretty easy to get the sum of all values in the array:
values.sumByDouble { it.value }
Is there an equivalent to multiply these values inside those classes?
You can create an extension function:
public inline fun <T> Iterable<T>.multiplyByDouble(selector: (T) -> Double): Double {
this.firstOrNull() ?: return 0.0
var result = 1.0
for (element in this) {
result *= selector(element)
}
return result
}
and use it:
listOf(2.0, 3.0).multiplyByDouble { it } // 6.0
listOf<Double>().multiplyByDouble { it } // 0.0
There is no dedicated function for that, but you can use reduce for that. But there is a problem. Since the element (in this case of type T with S as upper bound) has to be a subtype of the accumulator (in this case of type S),
inline fun <S, T : S> Iterable<T>.reduce(
operation: (acc: S, T) -> S
): S
which is not the case in your example, it would be a good idea to first map the MyData elements to the Double value:
val l = listOf(MyData(1.0), MyData(2.0), MyData(3.0))
.map { it.value }
.reduce { acc, ele -> acc * ele }
println(l) // 6.0
Alternatively, you could change your data model (like shown here) but that might not be a good idea just for the sake of multiplying all values, but it depends on your use-case.