UInt32 array to Double array Swift - arrays

I need to multiply 2 matrices in swift, so in order to use accelerate I need 2 arrays with type double. The issue is, the two arrays that I need to multiply are type UInt32. Is there anyway to convert a UInt32 array to a double array?
var UInt32TestArray: [UInt32] = [1,4,2,3]
var Int32TestArray: [Double] = [Double](UInt32) //Doesn't work

Use
UInt32TestArray.map { Double($0) }
to get an array of Double.

I don't think you can use a cast for these types of things. Usually you use a map function for converting an array of one type to another. An answer to a similar question can be found here. Conversion of entire array from int to double in order to do some aritmetic operations

Try this
var Int32TestArray = UInt32TestArray.map{UInt32(abs($0))}

Related

Declaring array with specific type but arbitrary number of dimensions

I am curious if there is any way in Swift to declare a multi-dimensional array that has a specific type(for this example we'll say Float) but isn't confined to a fixed number of dimensions(E.g., let arr: Array<Array<Float>>)?
I'd like to create a function that accepts a multi-dimensional array and currently the only way I'm aware of is:
func testFunction(arr: [Any]) {}
This is problematic though as it doesn't specify the actual scalar type of the array. As the type Any implies, this function can accept anything that is stuck inside of an Array. Any ideas?
Not with just an Array. Each array needs to know what type it contains. To contain an arbitrary number of dimensions, each array would need to be able to hold either a Float or an Array.
You could possible do something custom with an enum that has two cases.
enum MultidimensionalArray<Element> {
case array([MultidimensionalArray<Element>])
case values([Element])
}
but you'll probably have add a bunch more methods to it based on how you want to use ie.
How about generics
func testFunction<T>(arr: [T]) { }
T is a specific type and can be anything even
let foo = [[[[Float]]]]()
testFunction(arr: foo)
I found a way that makes it pretty simple to do what I'm after with some generic constraints and extensions.
protocol TypedNDArrayProtocol {}
// Make the type you are trying enforce conform to our protocol
extension Float: TypedNDArrayProtocol {}
// Now make Array conform to the same protocol while constraining
// it to only elements that *also* conform to this protocol
extension Array: TypedNDArrayProtocol where Element: TypedNDArrayProtocol {}
func testFunction(arr: Array<TypedNDArrayProtocol>) {}
This creates a sort of recursive conformance where the Array is allowed to accept either another Array, or a Float. If it is an Array, that Array can again only accept another Array or a Float and so on. This way you can use an arbitrary number of dimensions, but it must eventually terminate with a specific type; in this case a Float.
// This will work
testFunction(arr: [1.0, 2.0])
// This will also work
testFunction(arr: [[[3.0], [4.0]], [[5.0], [6.0]]])
// This will NOT work
testFunction(arr: [[[3], [4]], [[5], [6]]])
// Neither will this
testFunction(arr: [[["3"], ["4"]], [["5"], ["6"]]])

Passing swift string to c function char *

I am trying to pass a string argument from swift function wrapper to C function which takes char*.
This a c function
long swe_fixstar2_ut(char* star, double tjd_ut, long iflag, double* xx, char* serr);
The parameter star must provide for at least 41 characters for the returned star name. If a star is found, its name is returned. This function searches the star name from the txt file.
When imported to Swift function looks like this
swe_fixstar_ut(star: UnsafeMutablePointer<Int8>!, tjd_ut: Double, iflag: int32,
xx: UnsafeMutablePointer<Double>!, serr: UnsafeMutablePointer<Int8>!)
I want to achieve something like this
public func sweFixStarsUT(star: String, tjdUT: Double, iFlag: Int32) {
let xx: UnsafeMutablePointer = UnsafeMutablePointer<Double>.allocate(capacity:6)
let serr:UnsafeMutablePointer = UnsafeMutablePointer<CChar>.allocate(capacity:256)
swe_fixstar_ut(star, tjdUT, iFlag, xx, serr)
}
I looked around few of the similar questions but it doesn't solve my problem.
Convert a Swift Array of String to a to a C string array pointer
How to pass an array of Swift strings to a C function taking a char ** parameter
Actually this function comes from Swiss ephemeris C library. Here is the link if you guys are interested to look
https://www.astro.com/swisseph/swephprg.htm#_Toc505244846
As far as I read the doc, the parameter star is used for both in and out, so your star of the Swift function should be inout.
And long is imported as Int, and in Apple's 64-bit platforms, it represents 64-bit signed integer type, if it is actually 32-bit, you may need to update the source files of your C code. I assume it as Int.
So, I would write the bridging code like this:
public func sweFixStarsUT(star: inout String, tjdUT: Double, iFlag: Int) {
let starLen = max(star.utf8.count, 41)
var starBuf: [CChar] = Array(repeating: 0, count: starLen+1)
strcpy(&starBuf, star)
var xx: [Double] = Array(repeating: 0.0, count: 6)
var serr: [CChar] = Array(repeating: 0, count: 256)
swe_fixstar2_ut(&starBuf, tjdUT, iFlag, &xx, &serr)
star = String(cString: starBuf)
}
I prefer using Arrays when passing pointers to a C-function, when the function does not keep the pointers for later use. With using Arrays, you have no need to worry about deallocating.
You can see how the code is converting the input star to an Array of CChar and coverting back the Array into String.
If you find something wrong with this code, please tell me.

How to define an extention method for a non-generic array?

I cannot figure out what is the correct syntax to define an extension method on a non-generic array. This question deals with generic arrays, but trying a similar construct for a byte array doesn't work.
I have tried a lot of options:
type Byte ``[]`` with
type byte ``[]`` with
type Byte array with
type byte array with
type array<Byte> with
type array<byte> with
type []<Byte> with
type []<byte> with
as well as all of these constructs wrapped in double backticks or parenthesis, but nothing works. I downloaded the language specification, but it only has a generic array example.
This is likely a quirk with Optional Type Extensions, which can get pretty funky when generics are involved. I'd use an extension method like this instead:
open System.Runtime.CompilerServices
[<Extension>]
type ByteArrayExtensions =
[<Extension>]
static member inline Sum(xs: byte[]) = Array.sum xs
let f() =
let xs = [| byte(1); byte(2); byte(3) |]
xs.Sum()

Declare a constant array

I have tried:
const ascii = "abcdefghijklmnopqrstuvwxyz"
const letter_goodness []float32 = { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }
const letter_goodness = { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }
const letter_goodness = []float32 { .0817,.0149,.0278,.0425,.1270,.0223,.0202, .0609,.0697,.0015,.0077,.0402,.0241,.0675, .0751,.0193,.0009,.0599,.0633,.0906,.0276, .0098,.0236,.0015,.0197,.0007 }
The first declaration and initialization works fine, but the second, third and fourth don't work.
How can I declare and initialize a const array of floats?
An array isn't immutable by nature; you can't make it constant.
The nearest you can get is:
var letter_goodness = [...]float32 {.0817, .0149, .0278, .0425, .1270, .0223, .0202, .0609, .0697, .0015, .0077, .0402, .0241, .0675, .0751, .0193, .0009, .0599, .0633, .0906, .0276, .0098, .0236, .0015, .0197, .0007 }
Note the [...] instead of []: it ensures you get a (fixed size) array instead of a slice. So the values aren't fixed but the size is.
As pointed out by #jimt, the [...]T syntax is sugar for [123]T. It creates a fixed size array, but lets the compiler figure out how many elements are in it.
From Effective Go:
Constants in Go are just that—constant. They are created at compile time, even when defined as locals in functions, and can only be numbers, characters (runes), strings or booleans. Because of the compile-time restriction, the expressions that define them must be constant expressions, evaluatable by the compiler. For instance, 1<<3 is a constant expression, while math.Sin(math.Pi/4) is not because the function call to math.Sin needs to happen at run time.
Slices and arrays are always evaluated during runtime:
var TestSlice = []float32 {.03, .02}
var TestArray = [2]float32 {.03, .02}
var TestArray2 = [...]float32 {.03, .02}
[...] tells the compiler to figure out the length of the array itself. Slices wrap arrays and are easier to work with in most cases. Instead of using constants, just make the variables unaccessible to other packages by using a lower case first letter:
var ThisIsPublic = [2]float32 {.03, .02}
var thisIsPrivate = [2]float32 {.03, .02}
thisIsPrivate is available only in the package it is defined. If you need read access from outside, you can write a simple getter function (see Getters in golang).
There is no such thing as array constant in Go.
Quoting from the Go Language Specification: Constants:
There are boolean constants, rune constants, integer constants, floating-point constants, complex constants, and string constants. Rune, integer, floating-point, and complex constants are collectively called numeric constants.
A Constant expression (which is used to initialize a constant) may contain only constant operands and are evaluated at compile time.
The specification lists the different types of constants. Note that you can create and initialize constants with constant expressions of types having one of the allowed types as the underlying type. For example this is valid:
func main() {
type Myint int
const i1 Myint = 1
const i2 = Myint(2)
fmt.Printf("%T %v\n", i1, i1)
fmt.Printf("%T %v\n", i2, i2)
}
Output (try it on the Go Playground):
main.Myint 1
main.Myint 2
If you need an array, it can only be a variable, but not a constant.
I recommend this great blog article about constants: Constants
As others have mentioned, there is no official Go construct for this. The closest I can imagine would be a function that returns a slice. In this way, you can guarantee that no one will manipulate the elements of the original slice (as it is "hard-coded" into the array).
I have shortened your slice to make it...shorter...:
func GetLetterGoodness() []float32 {
return []float32 { .0817,.0149,.0278,.0425,.1270,.0223 }
}
In addition to #Paul's answer above, you can also do the following if you only need access to individual elements of the array (i.e. if you don't need to iterate on the array, get its length, or create slices out of it).
Instead of
var myArray [...]string{ /* ... */ }
you can do
func myConstArray(n int) string {
return [...]string{ /* ... */ }[n]
}
and then instead of extracting elements as
str := myArray[i]
you extract them as
str := myConstArray(i)
Link on Godbolt: https://godbolt.org/z/8hz7E45eW (note how in the assembly of main no copy of the array is done, and how the compiler is able to even extract the corresponding element if n is known at compile time - something that is not possible with normal non-const arrays).
If instead, you need to iterate on the array or create slices out of it, #Paul's answer is still the way to go¹ (even though it will likely have a significant runtime impact, as a copy of the array needs to be created every time the function is called).
This is unfortunately the closest thing to const arrays we can get until https://github.com/golang/go/issues/6386 is solved.
¹ Technically speaking you can also do it with the const array as described in my answer, but it's quite ugly and definitely not very efficient at runtime: https://go.dev/play/p/rQEWQhufGyK

defining a new array of a specific type on F#

How can I specifically define a new array of a specific type T ?
Strangely, I couldn't find any helpful information about it..
I want to write something like this:
let arr = new Array()
only that the elements of arr must be of type T.
How can I do it on F# ?
If type of elements is unknown, you can use explicit type annotation:
let arrayOfTenZeroes = Array.zeroCreate<int> 10
let emptyIntArray: int array = [||]
When you use high-order functions from Array module, you don't have to do so since type of elements is automatically inferred by the type checker:
// arr is inferred as int array
let arr = Array.init 10 (fun i -> i+1)
Maybe the Array.init<'T> and Array.create<'T> functions are what you are looking for.
Also consider using a Sequence instead of an array.
A sequence is a logical series of elements all of one type. Sequences are particularly useful when you have a large, ordered collection of data but do not necessarily expect to use all the elements.
Perhaps you can try something like this.
let myStringArray : string array = Array.zeroCreate 10
let myIntArray : int array = Array.zeroCreate 10
let myCharArray : char array = Array.zeroCreate 10
It's described on msdn.
Automatic generalization and type inference are great features you should take advantage of.
When an array is created:
let arr = Array.zeroCreate 10
its type is generalized. In this case it's inferred to be 'T[] (as general as possible).
Once you do something like:
let x = arr.[0] + 1
or
printfn "%s" arr.[0]
it can infer the concrete type (int[] or string[], respectively).
The lack of explicit types makes your code much cleaner. Save type annotations for when they're truly needed.

Resources