Why CFloat and CDouble?? func addNewValue(newVal: CFloat, atTime time: CDouble) -> CFloat {} - swift

I converted
-(float) addNewValue:(float) newVal atTime:(double) time {
to
func addNewValue(newVal: CFloat, atTime time: CDouble) -> CFloat {}
There are no errors but I don't know why it works. Why do Float and Double become CFloat and CDouble?
There are also no errors with:
func addNewValue(newVal: Float, atTime time: Double) -> Float {}
So which am I supposed to use?
Full code
let maxPeriod:Double = 1.5
let minPeriod:Double = 0.1
let invalidEntry = -100
let maxPeriodsToStore = 20
let averageSize:Int = 20
class Detector {
let session = AVCaptureSession()
var camera : AVCaptureDevice?
var upVals = [averageSize]
var downVals = [averageSize]
var upValIndex: Int?
var downValIndex: Int?
var lastVal: Float?
var periodStart: Float?
var periods = [maxPeriodsToStore]
var periodTimes = [maxPeriodsToStore]
var periodIndex: Int?
var started: Bool?
var freq: Float?
var average: Float?
var wasDown: Bool?
func reset() {
for var i:Int = 0; i < maxPeriodsToStore; i++ {
periods[i] = invalidEntry
}
for var i:Int = 0; i < averageSize; i++ {
upVals[i] = invalidEntry
downVals[i] = invalidEntry
}
freq = 0.5
periodIndex = 0
downValIndex = 0
upValIndex = 0
}
// SO Question is regarding this function
func addNewValue(newVal: Float, atTime time: Double) -> Float {
// we keep track of the number of values above and below zero
if newVal > 0 {
upVals[upValIndex!] = newVal
upValIndex!++
if upValIndex >= averageSize {
upValIndex = 0
}
}
if newVal < 0 {
downVals[downValIndex!] -= newVal
downValIndex!++
if downValIndex! >= averageSize as! Int {
downValIndex = 0
}
}
// work out the average value above zero
var count: Float
var total: Float
for var i=0; i < averageSize; i++ {
if upVals[i] != invalidEntry {
count++
total += upVals[i]
}
}
var averageUp = total/count
// and the average value below zero
count=0;
total=0;
for var i=0; i < averageSize; i++ {
if downVals[i] != invalidEntry {
count++
total+=downVals[i]
}
}
var averageDown = total/count
// is the new value a down value?
if newVal < (-0.5*averageDown) {
wasDown = true
}
// is the new value an up value and were we previously in the down state?
if (newVal >= (0.5*averageUp) && (wasDown) != nil) {
wasDown = false
// work out the difference between now and the last time this happenned
if (time - periodStart) < maxPeriod && (time - periodStart) > minPeriod {
periods[periodIndex]=time-periodStart
periodTimes[periodIndex]=time
periodIndex++
if periodIndex >= maxPeriodsToStore {
periodIndex = 0
}
}
// track when the transition happened
periodStart = time
}
// return up or down
if newVal < (-0.5*averageDown) {
return -1
} else if newVal > (0.5*averageUp) {
return 1
}
return 0
}

So which am I supposed to use?
Float and Double. The terms CFloat and CDouble are merely typealiases (synonyms) for these, so there is no point using them; they are there merely for compatibility.

Because Swift is an entirely different language than C.
Objective-C (which is an extension of the C language) can use C-types like float and double, but Swift has to define their own interpretations of these.
More information can be found in the Primitive Types section of this Apple documentation.

Related

Union-find: largest component size by common factor algorithm gives different results on every run

I was practicing data structure algorithm and made a Union - Find solution for the question.
The problem is, I think the code seems ok, but when I run it on Xcode playground, it shows different answers for the same input.
For example, I put an array [4, 6, 15, 35] in the function largestComponentSize, then it shows 2, 3, or 4 as the answer. I don't understand what's happening behind.
class Solution {
var uf = UnionFind()
func largestComponentSize(_ nums: [Int]) -> Int {
var maxNum:Int = 0
var numFactorMap = [Int:Int]()
var factorAdded = Set<Int>()
for num in nums {
var pFactors = getPrimeFactors(num)
numFactorMap[num] = pFactors[0]
for (i, val) in pFactors.enumerated() {
if !factorAdded.contains(val) {
uf.addSet(val)
factorAdded.insert(val)
}
if i > 0 {
uf.union(pFactors[i-1], val)
}
}
}
var groupCountMap = [Int:Int]()
for num in nums {
var groupId = uf.find(numFactorMap[num]!)!
if groupCountMap.keys.contains(groupId) {
groupCountMap[groupId]! += 1
} else {
groupCountMap[groupId] = 1
}
maxNum = max(maxNum, groupCountMap[groupId]!)
}
return maxNum
}
func getPrimeFactors(_ num: Int) -> [Int] {
var ans:Set<Int> = []
if num == 1 {
return []
}
var crrNum = num
var deno = 2
while crrNum >= deno {
if crrNum % deno == 0 {
ans.insert(deno)
crrNum = crrNum / deno
} else {
deno = deno + 1
}
}
return Array(ans)
}
class UnionFind {
var index = [Int: Int]()
var parent: [Int]
var size: [Int]
init() {
parent = []
size = []
}
func addSet(_ ele: Int) {
index[ele] = parent.count
parent.append(parent.count)
size.append(1)
}
func getSetSize(_ ele: Int) -> Int {
if let found = find(ele) {
return size[found]
}
return 0
}
func find(_ ele: Int) -> Int? {
if let indexOfEle = index[ele] {
if parent[indexOfEle] == indexOfEle {
return indexOfEle
} else {
if let found = find(parent[indexOfEle]) {
parent[indexOfEle] = found
}
return parent[indexOfEle]
}
} else {
return nil //never come here
}
}
func union(_ first: Int, _ second: Int) {
guard let indexOfFirst = index[first], let indexOfSecond = index[second] else {
return
}
if parent[indexOfFirst] == parent[indexOfSecond] {
return
}
var indexOfLarger = indexOfFirst
var indexOfSmaller = indexOfSecond
if size[indexOfFirst] < size[indexOfSecond] {
indexOfLarger = indexOfSecond
indexOfSmaller = indexOfFirst
}
parent[indexOfSmaller] = indexOfLarger
size[indexOfLarger] += size[indexOfSmaller]
return
}
}
}
var sol = Solution()
var nums = [4, 6, 15, 35]
var ans = sol.largestComponentSize(nums)
Thank you for your help in advance!
I just tried it on Xcode playground.

How to safely pass an array as parameter in swift

Hi this is my first question posted here. I have a class which updates an array from a stream of audio samples which I periodically need to process within another class. This is the code that updates the array and removes the oldest element when it reaches a maximum size:
public func update(sample: Sample) {
lastPeak = abs(sample.val) > abs(lastPeak) ? sample.val : lastPeak
if let last = lastSample {
if last.val * sample.val < 0 && abs(lastPeak) > minPeakSize { // this is a zero crossing
let offset = Double(sample.index) + Double(round((sample.val/(last.val - sample.val)) * 100) / 100)
let crossing = ZeroCrossing(
index: sample.index,
previousPeak: lastPeak,
indexWithOffset: offset
)
self.crossings.array.append(crossing) \\ <-- ARRAY UPDATE
lastPeak = 0
while crossings.array.count > crossingsMaxSize {
crossings.array.remove(at: 0) \\ <--ARRAY RESIZE
}
}
}
lastSample = sample
I then pass the array to a method within a separate class and occasionally get an index out of range error.
mutating func run(crossings: Crossings, octave: Int = 2) -> CorrelationResult? {
var result: CorrelationResult? = nil
if crossings.array.count > 4 {
var lastIndex: UInt = 0
if let lastCrossing = crossings.array.last {
lastIndex = lastCrossing.index
}
var startPoint = 0
var completeSet = false
for (i, crossing) in crossings.array.reversed().enumerated() { \\ <-- INDEX OUT OF RANGE
if lastIndex > crossing.index {
if lastIndex - crossing.index > windowSizeForOctave[octave] && crossing.previousPeak < 0 {
startPoint = crossings.array.count - i
completeSet = true
break
}
}
}
The array is wrapped within a struct
struct Crossings {
var locked = false
var array = [ZeroCrossing]()
}
struct ZeroCrossing {
var index: UInt
let previousPeak: Float
let indexWithOffset: Double
}
When the error occurs the array contains 500 elements and i = 0. Is there a safe way to pass arrays between classes (and I assume threads) without blocking updates to the original array?

Can you explain the output of the following Swift Projected Value?

#propertyWrapper
struct smallNumber {
private var num: Int
private var maximum: Int
var projectedValue: Bool
var wrappedValue: Int {
get { return num }
set {
if num > maximum {
num = maximum
projectedValue = true
}
else {
num = newValue
projectedValue = false
}
}
}
init() {
num = 0
maximum = 12
projectedValue = false
}
init(wrappedValue: Int) {
maximum = 12
projectedValue = false
num = min(wrappedValue, maximum)
}
init(wrappedValue: Int, maximum: Int) {
self.maximum = maximum
projectedValue = false
num = max(wrappedValue, maximum)
}
}
struct Rectangle {
#smallNumber var height: Int
#smallNumber var width: Int
var area: Int {
get {
return height * width
}
}
}
var x = Rectangle()
x.height = 9
x.width = 89
//x.width = 78
print(x.$height, x.$width, x.area)
Hi, I am learning swift and I am having trouble in the above code. In the swift reference(Projected Values), it's written that if we set the value of x greater than 12 then projectedValue becomes true. But after running the above code x.$width prints false. After removing the comment at 2nd last line x.$width prints true. Can someone explain me how is it working?
You copied the code incorrectly.
You have
if num > maximum {
but need
if newValue > maximum {

Convert Char in Int swift

I'm trying to convert a char in int, in C it works, but in Swift I've got some problem. It's not the same in C, using ascii I've got no problem.
This func is a piece of my atoi func.
I tried with binaryInt and UnicodeScalar, but didn't get success
func scanNumber(_ strArray: [Character], _ index: Int, _ flag: Int) -> Int {
var resalt = 0
while ((strArray[index] >= "0") && (strArray[index] <= "9")) {
// flag mean plus or minus sign in strArray, if flag = 2 it's like a ["-", "1", "2", "3"]
if flag != 2 {
resalt *= 10
resalt = resalt + Int(strArray[index]) //error
} else {
resalt *= 10
resalt = resalt - Int(strArray[index]) //error
}
}
return resalt
}
Int(strArray[index]) return:
Initializer 'init(_:)' requires that 'Character' conform to 'BinaryInteger'
Here is a solution using asciiValue
func scanNumber(_ strArray: [Character], _ index: Int, _ flag: Int) -> Int {
var resalt = 0
var arrayIndex = index
while (arrayIndex < strArray.count && (strArray[arrayIndex] >= "0") && (strArray[arrayIndex] <= "9")) {
guard let ascii = strArray[arrayIndex].asciiValue else {
return resalt
}
resalt *= 10
if flag != 2 {
resalt += Int(ascii) - 48
} else {
resalt -= Int(ascii) - 48
}
arrayIndex += 1
}
return resalt
}
I also fixed the loop
With a Character you can create a String. And with a String you can create an Int.
let char: Character = "1"
if let number = Int(String(char)) {
// use number
}

Practical number algorithm too slow

I am trying to write a program to find the practical numbers, from an input from 1 to n.
Practical numbers : https://en.wikipedia.org/wiki/Practical_number
My code is running correctly but it is extremely slow - takes over 20 minutes when it should take 10 seconds. This happens when calculating numbers around 50 - it gets stuck at 44.
It is written in Swift
import Foundation
func getInteger() -> Int {
var firstNum:Int = 0
while true {
// get value from user. Using optional input since readLine returns an optional string.
let input = readLine()
// ensure string is not nil
if let unwrappedInput = input {
if let unwrappedInt = Int(unwrappedInput) {
firstNum = unwrappedInt
break
}
else { // the input doesn't convert into an int
print("`\(unwrappedInput)` is not an integer. Please enter an integer")
}
}
else { // did not enter anything
print("Please enter an integer")
}
}
return firstNum
}
func addOne(signArray: [Int]) -> [Int] { // finds the combinations
var signArray2 = [Int]()
for i in 0...signArray.count-1 {
signArray2.append (signArray[i])
}
for i in 0...signArray2.count-1 {
if signArray2[i] == 1 {
signArray2[i] = 0
}
else {
signArray2[i] = 1
break
}
}
return signArray2
}
func signEval (signArray: [Int], divArray: [Int], inNum: Int) -> Bool {// changes 2nd
var counts = 0
for i in 0...divArray.count-1 {
if signArray[i] == 0 {
counts = divArray[i] + counts }
if counts == inNum {
return true
}
}
return false
}
print("Please enter a number to find the summable numbers up to that number:")
var input2 = getInteger()// if num = 1 print 1 if num = 2 print 1 and 2 else print >2 1, 2
var inNum = 0
var numHalf = 0.0
var numRound = 0.0
var numCheck = false
var numCheck2 = false
var numQuarter = 0.0
var numSixth = 0.0
var divArray:[Int] = []
var theirArray = [Int]()
var signArray = [Int]()// array of 0s and 1s
var summableArray:[Int] = [1,2] // need to check if num is bigger than 2!
for input in 1...input2 {
numHalf = Double (input) / 2.0
numRound = round(numHalf)
if numRound == numHalf {
numCheck = true }
if input > 2 && numCheck == false { // odd numbers greater than one are not summable
}
else { // these are possible summable nums
numQuarter = Double (input) / 4.0
numRound = round(numQuarter)
if numRound == numQuarter {
numCheck = true
}
else {
numCheck = false
}
numSixth = Double(input) / 6.0
numRound = round(numSixth)
if numRound == numSixth {
numCheck2 = true }
else { numCheck2 = false}
if numCheck == true || numCheck2 == true {
theirArray = []
divArray = []
signArray = []
summableArray = []
for i in 1...input {
theirArray.append (i)
}
for i in 1...input { // creates an array of all the diviors of inputted number
if input%i == 0 {
divArray.append (i)
}
}
for j in 1...divArray.count {//
signArray.append(0)
}
for i in 1...input{
let x: Int = Int(pow(Double(2),Double(input-1)))// int 2 to the power of input -1
var Boolcheck = false
for q in 1...x-1 { // i to 2^n -1 (sequence to check)
Boolcheck = (signEval(signArray: signArray, divArray: divArray, inNum: i))// checks
signArray = addOne(signArray: signArray)// adding the ones to the array
if Boolcheck == true {
summableArray.append(i)// creates array of mini summable numbers
break
}
}
if summableArray.count == input {
print ("\(input)")
}
}
}
}
}