Pi, Montecarlo y Kotlin

Pi, Montecarlo y Kotlin

Hace unos dias, escribí un artículo sobre el método Montecarlo para calcular la probabilidad de la posición final de un robot en una línea. Luego me acordé del clásico para calcular una aproximación de PI lanzando dardos y al final pensé, ¿que tal se defenderá Kotlin con coroutines en este ambiente?. Bien

fun main (args: Array){

    val averages = mutableListOf()
    val time = measureTimeMillis {
        (0..100000).forEach { _ ->
            runBlocking{
                averages.add(calculate())
            }
        }
        println("PI= ${averages.average()}")
    }
    println("time: $time")
}

fun calculate(): Double{
    val successful = mutableListOf()
    (0..500).forEach { _ ->
        GlobalScope.run {  successful.add((Random.nextDouble().pow(2) + Random.nextDouble().pow(2)) k }.toDouble() / successful.count().toDouble()
}

la verdad que las coroutines van de maravilla, consumen poco y superrápidas.

Funciones estadísticas

Funciones estadísticas

Vamos a ver las funciones estadísticas de varianza, desviación típica y coefeciente de variación con Kotlin. Partiremos de una lista de elementos Double y crearemos extensiones de la lista para calcularlas.

Varianza. La varianza tiene la siguiente formula.

quicklatex.com-d5166eaa9614351e91ec76dec4fc3faf_l3

o lo que es lo mismo

quicklatex.com-220898e23d5d0c3236780d6397b187a2_l3

Equivale al cuadrado de la desviación típica

fun List.variance(): Double {
    val n = this.count()
    val average = this.average()
    return this.map { (it - average).pow(2.0) / n}.sum()
}

Así que si la la desviación al cuadro es la varianza, podemos obtener la desviación obteniendo la raiz de la varianza.

fun List<Double>.stdDeviation() = sqrt(this.variance())

Por último el coeficiente de variación que es igual a la relación entre la desviación típica y el promedio.

cv.png

fun List<Double>.coefficientOfVariation() = stdDeviation() / this.average()

Obtenermos una muestra aleatoria y con pocas líneas de código el resultado:

val list = (0..10).map { n-> Random.nextDouble(5.0,10.0) }
println(list)
println("Average: ${list.average()}")
println("Variance: ${list.variance()}")
println("Std Deviation: ${list.stdDeviation()}")

 

[5.1126146370135555, 7.961926277327813, 6.030297997339725, 7.346200593709344, 6.977298121605789, 6.480337764164781, 9.12926821809771, 9.830048028655337, 7.107841652359342, 7.047870562367113, 8.943727133742051]
Average: 7.451584635125688
Variance: 1.8100002521711398
Std Deviation: 1.3453624984260337
Coefficient: 0.18054716738828816

Calculadora de números complejos en Kotlin

Calculadora de números complejos en Kotlin
I kt
Siempre me ha gustado C#, quero recordar cuando apareció Linq y las funciones lambda, operador Elvis, inicializadores de propiedades automáticas, la magia asincrónica, etc.. Java añadió a su código novedades, la guerra de “mi lenguaje es mejor” y… de un lenguaje de una empresa que casi nadie conocía, se va haciendo hueco hasta que Google alabando su velocidad de compilación, facilidad y simplicidad, lo nombra lenguaje oficial de Android allá por el 2017. En 2018, me da por investigar Kotlin, porque no seré el primero que ha aprendido un lenguaje que luego no ha pasado de cuartos y según avanzaba con Kotlin, más y más me gustaba, de hecho cada día me asombra y descubro alguna bondad que me aporta.Bueno, ya que he halagado, alabado, agasajado, piropeado y adulado a Kotlin, retomo una calculadora de números complejos en este lenguaje ya que la tengo en este blog en C# y Java y se ha alineado las mates y este lenguaje, así que no hay más remedio (le tocará a la calculadora IP, a matrices, a…).

Lo mejor de esta, su simplicidad en tan poco tiempo, seguro que si le dedicas un poco de tiempo, se puede simplificar más, pero esto lo dejo para vosotros. He aquí el código de una calculadora de números complejos para consola o para lo que queráis con Kotlin.


class Complex (var x: Double = 0.0, var y: Double = 0.0, val isDegrees: Boolean = false){

    var module: Double = 0.toDouble()
    var grades: Double = 0.toDouble()

    init {
        this.module = Math.sqrt(Math.pow(x, 2.0) + Math.pow(x, 2.0))
        this.grades = Math.atan2(y, x)
    }

    operator fun plus(complex: Complex):Complex = plusComplex(complex)
    operator fun minus(complex: Complex):Complex = substractComplex(complex)
    operator fun times(complex: Complex):Complex = multiplyComplex(complex)
    operator fun div(complex: Complex):Complex = divideComplex(complex)

    fun toVectorialString(): String ="(${toNumber(this.x, 2)}, ${toNumber(this.y, 2)})"

    override fun toString(): String ="${toNumber(this.x, 2)} ${if (this.y < 0) "" else  "+"} ${toNumber(this.y, 2)}i"

    fun toPolarString(): String {
        val angle = if (isDegrees) this.grades * 180 / Math.PI else this.grades
        val angleToString =
            "${(if (isDegrees) toNumber(angle, 1) else toNumber(angle, 3))} ${if (isDegrees) 'º' else " radians"}"
        return "${toNumber(this.module, 1)} )  $angleToString"
    }

    fun conjugate(complex: Complex = this): Complex = Complex(complex.x, -complex.y)

    fun opposite(complex: Complex = this): Complex = Complex(-complex.x, -complex.y)

    fun reverse(complex: Complex = this): Complex {
        return Complex(complex.x / denominator(), -complex.y / denominator())
    }

    fun equals(complex: Complex?): Boolean =complex != null && this.javaClass == complex.javaClass && this.x == complex.x && this.y == complex.y

    private fun denominator(complex: Complex=this) = Math.pow(complex.x, 2.0) + Math.pow(complex.y, 2.0)

    private fun plusComplex(complex: Complex): Complex {
        return Complex(this.x + complex.x, this.y + complex.y)
    }

    private fun substractComplex(complex: Complex): Complex = Complex(this.x - complex.x, this.y - complex.y)

    private fun multiplyComplex(complex: Complex): Complex {
        return Complex(
            this.x * complex.x - this.y * complex.y,
            this.x * complex.y + this.y * complex.x
        )
    }

    private fun divideComplex(complex: Complex): Complex = divideComplex(this, complex)

    private fun divideComplex(complex1: Complex, complex2: Complex): Complex {
        val xx = (complex1.x * complex2.x + complex1.y * complex2.y) / (Math.pow(
            complex2.x,
            2.0
        ) + Math.pow(complex2.y, 2.0))
        val yy = (complex1.y * complex2.x - complex1.x * complex2.y) / (Math.pow(
            complex2.x,
            2.0
        ) + Math.pow(complex2.y, 2.0))
        return Complex(xx, yy)
    }

    companion object {

        fun convertToBinomial(module: Double, argument: Double):Complex = convertPolarToBinomial(module, argument)

        fun convertPolarToBinomial(module: Double, argument: Double): Complex = Complex(abs(module) * cos(argument), -abs(module) * sin(argument))

        fun toNumber(number: Double, digits: Int): String {
            val fn = NumberFormat.getNumberInstance()
            fn.maximumFractionDigits = digits
            return fn.format(number)
        }
    }
}


y el resultado


fun main(args:Array){
    val c1 = Complex(3.0,4.0)
    val c2 = Complex(5.0,6.0)

    println(c1.toString())


    println(c2.toString())
    println(c1+c2)
    println(c1-c2)
    println(c1*c2)
    println(c1/c2)
    println(c1.reverse())
    println(c1.conjugate())

}

3 + 4i
5 + 6i
8 + 10i
-2  -2i
-9 + 38i
0,64 + 0,03i
0,12  -0,16i
3  -4i

PD: Kotlin es el lenguaje oficial de Android, pero también permite desarrollar aplicaciones de consola, de escritorio, WEB, etc., es multiplataforma, ya que corre bajo la JVM y puede ser compilado a JavaScript.

Señores de WordPress, ¿Cuando podré publicar lenguaje Kotlin en su editor?