@@ -16,6 +16,7 @@ end arrayUtil
1616
1717object arrays :
1818 export vecxt .JsNativeDoubleArrays .*
19+ export vecxt .JsNativeFloatArrays .*
1920
2021 extension (d : Float64Array ) def printArr : String = d.mkString(" [" , " ," , " ]" )
2122 end extension
@@ -491,6 +492,252 @@ object arrays:
491492 // val t = js.Math.max( vec.toArray: _* )
492493 end extension
493494
495+ extension (vec : Array [Float ])
496+
497+ inline def apply (index : Array [Boolean ])(using inline boundsCheck : BoundsCheck .BoundsCheck ): Array [Float ] =
498+ dimCheck(vec, index)
499+ val trues = index.trues
500+ val newVec = Array .ofDim[Float ](trues)
501+ var j = 0
502+ for i <- 0 until index.length do
503+ if index(i) then
504+ newVec(j) = vec(i)
505+ j = 1 + j
506+ end for
507+ newVec
508+ end apply
509+
510+ inline def mean : Float =
511+ var sum = 0.0
512+ var i = 0
513+ while i < vec.length do
514+ sum += vec(i)
515+ i += 1
516+ end while
517+ (sum / vec.length).toFloat
518+ end mean
519+
520+ inline def variance : Float = variance(VarianceMode .Population )
521+
522+ inline def variance (mode : VarianceMode ): Float =
523+ meanAndVariance(mode).variance
524+ end variance
525+
526+ inline def meanAndVariance : (mean : Float , variance : Float ) =
527+ meanAndVariance(VarianceMode .Population )
528+
529+ inline def meanAndVariance (mode : VarianceMode ): (mean : Float , variance : Float ) =
530+ var mean = 0.0
531+ var m2 = 0.0
532+ var i = 0
533+ while i < vec.length do
534+ val n = i + 1
535+ val delta = vec(i).toDouble - mean
536+ mean += delta / n
537+ val delta2 = vec(i).toDouble - mean
538+ m2 += delta * delta2
539+ i += 1
540+ end while
541+ val denom = mode match
542+ case VarianceMode .Population => vec.length.toDouble
543+ case VarianceMode .Sample => (vec.length - 1 ).toDouble
544+
545+ (mean.toFloat, (m2 / denom).toFloat)
546+ end meanAndVariance
547+
548+ inline def std : Float = std(VarianceMode .Population )
549+
550+ inline def std (mode : VarianceMode ): Float =
551+ Math .sqrt(vec.variance(mode).toDouble).toFloat
552+
553+ inline def stdDev : Float = stdDev(VarianceMode .Population )
554+
555+ inline def stdDev (mode : VarianceMode ): Float = std(mode)
556+
557+ inline def dot (v1 : Array [Float ])(using inline boundsCheck : BoundsCheck ): Float =
558+ dimCheck(vec, v1)
559+ var product = 0.0
560+ var i = 0
561+ while i < vec.length do
562+ product = product + vec(i) * v1(i)
563+ i = i + 1
564+ end while
565+ product.toFloat
566+ end dot
567+
568+ inline def norm : Float =
569+ Math .sqrt(vec.dot(vec)(using vecxt.BoundsCheck .DoBoundsCheck .no).toDouble).toFloat
570+ end norm
571+
572+ inline def + (d : Float ): Array [Float ] =
573+ vec.clone().tap(_ += d)
574+
575+ inline def += (d : Float ): Unit =
576+ var i = 0
577+ while i < vec.length do
578+ vec(i) = vec(i) + d
579+ i = i + 1
580+ end while
581+ end +=
582+
583+ inline def - (d : Float ): Array [Float ] =
584+ vec.clone().tap(_ -= d)
585+ end -
586+
587+ inline def -= (d : Float ): Unit =
588+ var i = 0
589+ while i < vec.length do
590+ vec(i) = vec(i) - d
591+ i = i + 1
592+ end while
593+ end -=
594+
595+ inline def - (vec2 : Array [Float ])(using inline boundsCheck : BoundsCheck .BoundsCheck ): Array [Float ] =
596+ dimCheck(vec, vec2)
597+ vec.clone().tap(_ -= vec2)
598+ end -
599+
600+ inline def -= (vec2 : Array [Float ])(using inline boundsCheck : BoundsCheck .BoundsCheck ): Unit =
601+ dimCheck(vec, vec2)
602+ var i = 0
603+ while i < vec.length do
604+ vec(i) = vec(i) - vec2(i)
605+ i = i + 1
606+ end while
607+ end -=
608+
609+ inline def + (vec2 : Array [Float ])(using inline boundsCheck : BoundsCheck .BoundsCheck ): Array [Float ] =
610+ dimCheck(vec, vec2)
611+ vec.clone().tap(_ += vec2)
612+ end +
613+
614+ inline def += (vec2 : Array [Float ])(using inline boundsCheck : BoundsCheck .BoundsCheck ): Unit =
615+ dimCheck(vec, vec2)
616+ var i = 0
617+ while i < vec.length do
618+ vec(i) = vec(i) + vec2(i)
619+ i = i + 1
620+ end while
621+ end +=
622+
623+ inline def +:+ (d : Float ): Array [Float ] =
624+ vec.clone().tap(_ +:+= d)
625+ end +:+
626+
627+ inline def +:+= (d : Float ): Unit =
628+ var i = 0
629+ while i < vec.length do
630+ vec(i) = vec(i) + d
631+ i = i + 1
632+ end while
633+ end +:+=
634+
635+ inline def *= (d : Float ): Unit =
636+ var i = 0
637+ while i < vec.length do
638+ vec(i) = vec(i) * d
639+ i = i + 1
640+ end while
641+ end *=
642+
643+ inline def * (d : Float ): Array [Float ] =
644+ vec.clone().tap(_ *= d)
645+ end *
646+
647+ inline def /= (d : Float ): Unit =
648+ var i = 0
649+ while i < vec.length do
650+ vec(i) = vec(i) / d
651+ i = i + 1
652+ end while
653+ end /=
654+
655+ inline def / (d : Float ): Array [Float ] =
656+ vec.clone().tap(_ /= d)
657+ end /
658+
659+ inline def pearsonCorrelationCoefficient (thatVector : Array [Float ])(using
660+ inline boundsCheck : BoundsCheck .BoundsCheck
661+ ): Float =
662+ dimCheck(vec, thatVector)
663+ val n = vec.length
664+ var i = 0
665+
666+ var sum_x = 0.0
667+ var sum_y = 0.0
668+ var sum_xy = 0.0
669+ var sum_x2 = 0.0
670+ var sum_y2 = 0.0
671+
672+ while i < n do
673+ sum_x = sum_x + vec(i)
674+ sum_y = sum_y + thatVector(i)
675+ sum_xy = sum_xy + vec(i) * thatVector(i)
676+ sum_x2 = sum_x2 + vec(i) * vec(i)
677+ sum_y2 = sum_y2 + thatVector(i) * thatVector(i)
678+ i = i + 1
679+ end while
680+ ((n * sum_xy - (sum_x * sum_y)) / Math .sqrt(
681+ (sum_x2 * n - sum_x * sum_x) * (sum_y2 * n - sum_y * sum_y)
682+ )).toFloat
683+ end pearsonCorrelationCoefficient
684+
685+ inline def spearmansRankCorrelation (thatVector : Array [Float ])(using
686+ inline boundsCheck : BoundsCheck .BoundsCheck
687+ ): Float =
688+ dimCheck(vec, thatVector)
689+ val theseRanks = vec.elementRanks
690+ val thoseRanks = thatVector.elementRanks
691+ theseRanks.pearsonCorrelationCoefficient(thoseRanks)
692+ end spearmansRankCorrelation
693+
694+ inline def corr (thatVector : Array [Float ])(using inline boundsCheck : BoundsCheck .BoundsCheck ): Float =
695+ pearsonCorrelationCoefficient(thatVector)
696+
697+ def elementRanks : Array [Float ] =
698+ val indexed1 = vec.zipWithIndex
699+ val indexed = indexed1.toArray.sorted(using Ordering .by(_._1))
700+
701+ val ranks : Array [Float ] = new Array (vec.length)
702+ ranks(indexed.last._2) = vec.length.toFloat
703+ var currentValue : Float = indexed(0 )._1
704+ var r0 : Int = 0
705+ var rank : Int = 1
706+ while rank < vec.length do
707+ val temp : Float = indexed(rank)._1
708+ val end : Int =
709+ if temp != currentValue then rank
710+ else if rank == vec.length - 1 then rank + 1
711+ else - 1
712+ if end > - 1 then
713+ val avg : Float = ((1.0 + (end + r0)) / 2.0 ).toFloat
714+ var i : Int = r0;
715+ while i < end do
716+ ranks(indexed(i)._2) = avg
717+ i += 1
718+ end while
719+ r0 = rank
720+ currentValue = temp
721+ end if
722+ rank += 1
723+ end while
724+ ranks
725+ end elementRanks
726+
727+ def covariance (thatVector : Array [Float ]): Float =
728+ val μThis = vec.mean
729+ val μThat = thatVector.mean
730+ var cv : Double = 0
731+ var i : Int = 0
732+ while i < vec.length do
733+ cv += (vec(i) - μThis ) * (thatVector(i) - μThat )
734+ i += 1
735+ end while
736+ (cv / (vec.length - 1 )).toFloat
737+ end covariance
738+
739+ end extension
740+
494741 extension (vec : Array [Array [Double ]])
495742 inline def horizontalSum : Array [Double ] =
496743 val out = Array .ofDim[Double ](vec.head.length)
0 commit comments