Creating a FloatArray from an Array<Float> object in Kotlin - arrays

I am trying to convert a Array object to a FloatArray using a spread operator:
val x = arrayOf(0.2f, 0.3f)
val y = floatArrayOf(*x)
Unfortunetly I get Type mismatch: inferred type is Array<Float> but FloatArray was expected
Why is there an error and how to make this work?

You cannot write that but instead you can do:
val y = x.toFloatArray()

toFloatArray is the obvious choice, but if for some reason you wanted to create a new float array without calling that, you could do the same thing it does internally: call the FloatArray constructor:
val x = arrayOf(0.2f, 0.3f)
val y = FloatArray(x.size) { x[it] }

Related

Swift 5 Create 3D Array of Doubles And Pass To C Function

I need to call a legacy C function (from swift) that expects a 3D array of Doubles as an argument. I am fairly new to Swift and have begun converting a large ObjC and C code base written for iOS and Mac over to Swift. The C code does a lot of complex astronomical math and for which Swift is just too cumbersome. I will not convert those, but I need to use them from Swift
The C function is declared like this and the .H file is visible to swift:
void readSWEDayData(double dData[DATA_ROWS_PER_DAY][NUM_PLANET_ELEMENTS][NUM_ELEMENTS_PER_PLANET]);
The Constants used in the declaration are defined to be:
DATA_ROWS_PER_DAY = 1
NUM_PLANET_ELEMENTS = 35
NUM_ELEMENTS_PER_PLANET = 4
I am struggling with declaring the array of doubles in a way that Swift will allow to be passed to the C function. I've tried several approaches.
First Approach:
I declare the array and call it like so:
var data = Array(repeating: Double(EPHEMERIS_NA), count:Int(DATA_ROWS_PER_DAY * NUM_PLANET_ELEMENTS * NUM_ELEMENTS_PER_PLANET))
readSWEDayData(&data)
I get this error: Cannot convert value of type 'UnsafeMutablePointer' to expected argument type 'UnsafeMutablePointer<((Double, Double, Double, Double),...
Second Approach:
If I declare the array this way:
var data = [(Double, Double, Double, Double)](repeating: (EPHEMERIS_NA, EPHEMERIS_NA, EPHEMERIS_NA, EPHEMERIS_NA), count: Int(NUM_PLANET_ELEMENTS))
readSWEDayData(&data)
I get this error: Cannot convert value of type 'UnsafeMutablePointer<(Double, Double, Double, Double)>' to expected argument type 'UnsafeMutablePointer<((Double, Double, Double, Double),
So, how the heck does one declare a 3D Array in Swift of a specific size so that it can be passed to a C Function?
The function needs an UnsafeMutablePointer to a 35-tuple of things, where each of those things are 4-tuples of Doubles. Yes, C arrays translate to tuples in Swift, because Swift doesn't have fixed size arrays. You could do:
var giantTuple = (
(EPHEMERIS_NA, EPHEMERIS_NA, EPHEMERIS_NA, EPHEMERIS_NA),
(EPHEMERIS_NA, EPHEMERIS_NA, EPHEMERIS_NA, EPHEMERIS_NA),
(EPHEMERIS_NA, EPHEMERIS_NA, EPHEMERIS_NA, EPHEMERIS_NA),
// 32 more times...
)
readSWEDayData(&giantTuple)
But I don't think you'd like that. You can create an array, and use some pointer magic to convert that to a tuple, as discussed in this Swift Forums post. In fact, that post is highly relevant to your situation.
To save some typing, we can write some type aliases first:
typealias Tuple35<T> = (T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T)
typealias Double4x35 = Tuple35<(Double, Double, Double, Double)>
Then we can do:
var giantTuple = Array(repeating: (EPHEMERIS_NA, EPHEMERIS_NA, EPHEMERIS_NA, EPHEMERIS_NA), count: NUM_PLANET_ELEMENTS).withUnsafeBytes { p in
p.bindMemory(to: Double4x35.self)[0]
}
readSWEDayData(&giantTuple)
This works because tuples and arrays have essentially the same "layout" in memory.
Note that I "cheated" a little bit here, since DATA_ROWS_PER_DAY is 1, you can just create one such giantTuple, and get a pointer to it. However, if it is greater than 1, you'd have to do something like:
var giantTuples = Array(repeating:
Array(repeating: (EPHEMERIS_NA, EPHEMERIS_NA, EPHEMERIS_NA, EPHEMERIS_NA), count: NUM_PLANET_ELEMENTS).withUnsafeBytes { p in
p.bindMemory(to: Double4x35.self)[0]
},
count: DATA_ROWS_PER_DAY)
readSWEDayData(&giantTuples)
To convert from the giant tuple back to an array, you can do something like this:
// converting the first giantTuples in "giantTuples" as an example
let arrayOf4Tuples = asCollection(giantTuples[0], Array.init)
let finalArray = arrayOf4Tuples.map { asCollection($0, Array.init) }
// these are adapted from the Swift forum thread
// you'll need two of these, because you have 2 types of tuples
// yes, working with C arrays is hard :(
func asCollection<T, E>(_ tuple: Tuple35<E>, _ perform: (UnsafeBufferPointer<E>)->T) -> T {
return withUnsafeBytes(of: tuple) { ptr in
let buffer = ptr.bindMemory(to: (E.self))
return perform(buffer)
}
}
func asCollection<T, E>(_ tuple: (E, E, E, E), _ perform: (UnsafeBufferPointer<E>)->T) -> T {
return withUnsafeBytes(of: tuple) { ptr in
let buffer = ptr.bindMemory(to: (E.self))
return perform(buffer)
}
}
Because Swift 5 lacks support for interoperability with C language multi-dimensional Arrays of fixed size except via tuples of explicitly declared structure (See Sweeper's answer above) and which is something I wish to avoid to keep my code flexible for future changes to the C Library being used, I opted to write a wrapper for the C function and make it appear to Swift as a 1 dimensional array.
This was necessary because the Constants used in the C Code change when readSWEDayData increases the array sizes to support additional elements and tuple declarations like this:
let Double4x35 = Tuple35<(Double, Double, Double, Double)>
will DEFINITELY break in a way that will be hard to find:
So my C wrapper function looks like so:
void readSWEDayDataForSwift(double *dData) {
readSWEDayData((double (*)[NUM_PLANET_ELEMENTS][NUM_ELEMENTS_PER_PLANET])dData);
}
Making it easy to call it from Swift like so:
var data = Array(repeating: Double(EPHEMERIS_NA), count:Int(DATA_ROWS_PER_DAY * NUM_PLANET_ELEMENTS * NUM_ELEMENTS_PER_PLANET))
I was surprised that this far into Swift's evolution there is no better way to do this!
My two cents for others..Hoping will help.
I got a similar problem, but hope can save time for other.
I had to pass down:
path (from String to char *)
title (from String to char *)
columns ([String] to array of char *)
a counter
to sum up I had to call "C" function:
bool OpenXLSXManager_saveIn(const char * cFullPath,
const char * sheetName,
char *const columnTitles[],
double *const values[],
int columnCount);
I started from excellent:
// https://oleb.net/blog/2016/10/swift-array-of-c-strings/
expanded a bit:
public func withArrayOfCStringsAndValues<R>(
_ args: [String],
_ values: [[Double]],
_ body: ([UnsafeMutablePointer<CChar>?] , [UnsafeMutablePointer<Double>?] ) -> R ) -> R {
var cStrings = args.map { strdup($0) }
cStrings.append(nil)
let cValuesArrr = values.map { (numbers: [Double]) -> UnsafeMutablePointer<Double> in
let pointer = UnsafeMutablePointer<Double>.allocate(capacity: numbers.count)
for (index, value) in numbers.enumerated() {
pointer.advanced(by: index).pointee = value
}
return pointer
}
defer {
cStrings.forEach { free($0) }
for pointer in cValuesArrr{
pointer.deallocate()
}
}
return body(cStrings, cValuesArrr)
}
so I can call:
func passDown(
filePath: String,
sheetName:
String,
colNames: [String],
values: [[Double]]
) -> Bool
{
let columnCount = Int32(colNames.count)
return withArrayOfCStringsAndValues(colNames, values) {
columnTitles, values in
let retval = OpenXLSXManager_saveIn(filePath, sheetName, columnTitles, values, columnCount)
return retval
}
}
(SORRY for formatting, S.O. formatter has BIG issues ..)

Why does Swift's reduce function throw an error of 'Type of expression ambigious without more context' when all types are properly defined?

var nums = [1,2,3]
let emptyArray : [Int] = []
let sum1 = nums.reduce(emptyArray){ $0.append($1)}
let sum2 = nums.reduce(emptyArray){ total, element in
total.append(element)
}
let sum3 = nums.reduce(emptyArray){ total, element in
return total.append(element)
}
For all three approaches I'm getting the following error:
Type of expression ambiguous without more context
But looking at documentation and the method signature of reduce:
func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result
You can see that both the Result and Element can be correctly inferred. Result is obviously of type [Int] and Element is of type [Int].
So I'm not sure what's wrong. I also saw here but that doesn't help either
You're right that you're passing the correct types to be inferred. The error is misleading.
Had you instead wrote:
func append<T>(_ element: T, to array: [T]) -> [T]{
let newArray = array.append(element)
return newArray
}
Then the compiler would have given the correct error:
Cannot use mutating member on immutable value: 'array' is a 'let'
constant
So now we know what the correct error should have been:
That is both the Result and the Element are immutable within the closure. You have to think of it just like a normal func add(a:Int, b:Int) -> Int where a & b are both immutable.
If you want it to work you just need a temporary variable:
let sum1 = nums.reduce(emptyArray){
let temp = $0
temp.append($1)
return temp
}
Also note that the following is is wrong!
let sum3 = nums.reduce(emptyArray){ total, element in
var _total = total
return _total.append(element)
}
Why?
Because the type of _total.append(element) is Void it's a function. Its type is not like the type of 5 + 3 ie Int or [5] + [3] ie [Int]
Hence you have to do:
let sum3 = nums.reduce(emptyArray){ total, element in
var _total = total
_total.append(element)
return _total
}

Array declaration in Kotlin

The code below is an example for Array declaration in Kotlin,
fun main(args: Array<String>) {
var a = Array<Int>(2){0}
a[0] = 100
a[1] = 200
print(a[1])
}
Here variable a is an array of size 2 and having values 100 and 200 and it is printing the value of a[1] as 200.
My question is -> What is the role of "0" in var a = Array(2){0}?
I changed the value of "0" to some other integer value, still it is working fine, but i was not able to find the use case of it. Can anyone explain it?
Any help will be appreciated.
Thanks.
The 0 is what you initialize each element of your array (2 in your case) with, using the following constructor:
public inline constructor(size: Int, init: (Int) -> T)
You can make this visible by printing the array directly after its initialization:
var a = Array<Int>(2){0}
println(a.contentToString())
Please consider the use of arrayOf(0,0) for such a simple use case, which is more idiomatic.
Arrays in Kotlin are represented by the Array class, that has get and set functions (that turn into [] by operator overloading conventions), and size property, along with a few other useful member functions:
class Array<T> private constructor() {
val size: Int
operator fun get(index: Int): T
operator fun set(index: Int, value: T): Unit
operator fun iterator(): Iterator<T>
// ...
}
You can write
var a = Array(2){0}
Creates a new array with the specified [size], where each element is calculated by calling the specified
* [init] function. The [init] function returns an array element given its index.
public inline constructor(size: Int, init: (Int) -> T)
Read Arrays in Kotlin.

Declaring an array of int in xtend

How can I declare an array of int in xtend?
I've tried ArrayList but I get the error "The primitive 'int' cannot be a type argument".
Please refer to the docs for details, but essentially its something along these lines:
val int[] x = newIntArrayOfSize(5)
or if you want to define an array literal:
val int[] x = #[1, 2, 3]

Casting after comparison of two Array manifest in scala

I have some problem to cast my objeсt Variable[A] where A <: Array[_]
I create a function to compare manifest and cast data into Array to the good type.
My object Variable[A] store a Manifest[A] into the def 'type'
I make a plugin of an existent software, so it's not me which instanciate this Variable with good type.
Prototype object and class :
object Prototype {
def apply[T](n: String)(implicit t: Manifest[T]) = new Prototype[T] {
val name = n
val `type` = t
}
}
trait Prototype[T] {
def name: String
def `type`: Manifest[T]
}
Variable Object and Class :
object Variable {
def apply[T](p: Prototype[T], v: T) = new Variable[T] {
val prototype = p
val value = v
}
}
trait Variable[T] {
def prototype: Prototype[T]
def value: T
}
My class which use :
class XYDataReader[A <: Array[_]](var data: Iterable[Variable[A]]) {
def get[T](variable: Variable[A])(implicit m: Manifest[T]): Option[T] = {
if (variable.prototype.`type` <:< m) {
Some(variable.value.asInstanceOf[T])
} else {
None
}
}
}
There is probably a mistake of my part when i instanciate Variable object used to compare, so i give also the code of instanciation :
val v:List[Any] = List[Any](1.2,2,3)
val p = Prototype[Array[Any]]("col1")
val myVariable = Variable(p, v.toArray(ClassTag(p.`type`.runtimeClass)))
I don't understand why pattern matching failed when i call get[Array[Double]](myVariable) where myVariable.value contain an Array[Double]
When i println() the two manifest :
variable array type : Array[double]
m type : Array[Double]
It seem an Array[Double] is not an Array[double], how can i resolve/cast this ?
This started out as a comment, since it's not an answer, but it's too big and needs formatting (plus my browser tab's auto-reload caused it to be lost the first time...)
So... For starters, your snippet of code is incomplete and / or incorrect. Potentially there are imports in effect which could alter the meaning of that code. Secondly, as shown it would not compile 'cause what appears to be a formal type parameter, the A has no binding. Thus unless you have an actual type named A that won't compile.
Secondly, Double is potentially ambiguous. There is both scala.Double and java.lang.Double and they are distinct. Scala auto-boxes and -unboxes primitive types for you, typically when they're used to instantiate type parameters for generic methods (and specialization is not used). A consequence of this is that Array[scala.Double] is distinct from Array[java.lang.Double]. Scala will create arrays of primitive types when possible, but Array[java.lang.Double] is explicitly an array of boxed double-precision floating point.
E.g.:
scala> val d1: scala.Double = 123.456
d1: Double = 123.456
scala> val d2: java.lang.Double = 234.567
d2: Double = 234.567
scala> d1.getClass
res25: Class[Double] = double
scala> d2.getClass
res26: Class[_ <: Double] = class java.lang.Double
scala> val ad1: Array[scala.Double] = Array(123.456, 234.567)
ad1: Array[Double] = Array(123.456, 234.567)
scala> val ad2: Array[java.lang.Double] = Array(234.567, 345.678)
ad2: Array[Double] = Array(234.567, 345.678)
scala> ad1.getClass
res27: Class[_ <: Array[Double]] = class [D
scala> ad2.getClass
res28: Class[_ <: Array[Double]] = class [Ljava.lang.Double;
So please, if you would, fill in the missing details of your sample code?
Finally, with help of colleague methods to resursively unArrayify Array, i resolve my runtime type reification problem. Now i can compare equality between Array[double] with Array[Double].
// Convert unknow A en Array[T], so you need to call get with Type :
// example : get[Array[Double](myVariable)
// return an Array[Double] only if it's possible for this Variable, else it return None
def get[T](variable: Variable[A])(implicit m: Manifest[T]): Option[T] = {
if (ClassUtils.assignable(variable.prototype.`type`.runtimeClass, m.runtimeClass)) {
val casted = variable.prototype.`type`.runtimeClass.cast(variable.value)
Some(casted.asInstanceOf[T])
} else {
None
}
I hope these methods can help other people :)
You can see helping method ClassUtils.assignable here :
https://gist.github.com/4686167
and on the source forge project :
https://forge.iscpif.fr/projects/openmole/repository/revisions/master/entry/core/openmole/misc/org.openmole.misc.tools/src/main/scala/org/openmole/misc/tools/obj/ClassUtils.scala

Resources