"The compiler is unable to type-check this expression in reasonable time" for a simple formula - swift

I have what appears to be a rather simple arithmetic expression:
let N = 2048
// var c = (0..<N).map{ sin( 2.0 * .pi * Float($0) / (Float(N)/2.0)) }
let sinout = (0..<N * 10).map { x in
sin(2 * .pi * Float(x) / Float(N / 2))
}
But this is generating:
The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
Why is such a simple equation not parse-able by the Swift compiler? How do we write equations that Swift can actually parse? This must be a major headache for persons writing DSP and/or linear algebra libraries: what workarounds or patterns do you use?

You just have to explicitly set the return type of your map expression:
map { x -> Float in

Sometimes it is hard for Swift to compile some seemingly easy code. The best thing you can do in those cases is modulate it in smaller chunks. I honestly think that this is an error that should be fixed but that for some reason is still there.

Related

Hints on getting basic arithmetic expressions to be parsed in Swift

Consider the following expression:
let N = 2048
var c = (0..<N).map{ f -> Float in sin( 2 * .pi * f / (N/2)) }
Swift can not really parse it:
This is already a very small expression: it's absurd to break it into even smaller pieces. So I am trying to use type-casts. But I am getting weary of adding many explicit type casts :
let N = 2048
var c: [Float] = (0..<N).map{ f -> Float in
Float(sin( 2.0 * .pi * f / (Float(N/2)))) }
Even with the above the error continues
Why is swift so weak in parsing these simple arithmetic expressions? What can I do short of breaking it into pieces of the form
let c = a * b
let f = c * d
That is just too simplistic to be practical for signal processing. I am guessing that there were tricks to get the compiler to be a bit more intelligent: please do share.
The issue is that the arithmetic operators (+,-,* and /) have a lot of overloads. Hence, when you write expressions containing a lot of those operators, the compiler cannot resolve them in time.
This is especially true when you have type errors. The compiler tries to find the correct overload, but cannot do so, since your types are mismatching and there's no matching overload. However, by the time the compiler could infer this, it's already past the timeout for resolving expressions and hence you get that error instead of the actual type error.
As soon as you resolve the type errors by casting all Ints to Float, the single line expression compiles just fine.
let c = (0..<N).map{ f -> Float in sin( 2 * .pi * Float(f) / Float(N/2)) }
Once you do that, you don't even need the named closure argument and type annotation of the return value anymore.
let c = (0..<N).map{ sin(2 * .pi * Float($0) / Float(N/2)) }
That looks like java. What about
let N = 2048
var c = (0..<N).map{ f in
sin( 2.0 * .pi * Float(f) / Float(N/2))
}

Swift Compiler Error: “Expression too complex” on a mathematical equation

When I add this equation
colViewHeight = (colItemSize * CGFloat(Counts)) + (colLineSpace *
CGFloat(Counts)) + (colViewTopSpace+colViewBottomSpace) as CGFloat
I get the below mentioned error.
The compiler is unable to type-check this expression in reasonable
time; try breaking up the expression into distinct sub-expressions
How to solve this issue? I am using xcode 10.01 version
Split it into multiple subexpressions and check if type casting is working fine
Such as:
let first = (colItemSize * CGFloat(Counts))
let second = (colViewTopSpace + colViewBottomSpace) as CGFloat
colViewHeight = first + second
Just delete the redundant bridge cast as CGFloat and the redundant parentheses
colViewHeight = colItemSize * CGFloat(Counts) + colLineSpace * CGFloat(Counts) + colViewTopSpace + colViewBottomSpace

Swift: Multiplication and brackets calculation doesn't work

This is a example equation which I want to be solved:
let equation = (5-2) * (10-5) / (4-2) * (10-5)
print (equation)
//35
The result which is printed is 35. But the right result would be 1,5. Whats wrong?
your expression is incorrect I hope you want the result 1.5
put '(' correctly * and / Precedence to execution are same but () is greater than * and /
let equation = ((5-2) * (10-5)) / ((4-2) * (10-5))
print (equation)
if you put the multiplication in another '()' then you will get result one perhaps the right part is integer so its auto conver to integer type
let equation = Double ( (5 - 2) * (10 - 5)) / Double ((4 - 2) * ( 10 - 5 ))
print (equation)
this code will print 1.5
Just look out operators Precedence in programming language
This should work:
let numerator: Double = (5-2) * (10-5)
let denumerator: Double = (4-2) * (10-5)
Fist you calculate the numerator and denumerator. And finally the result:
print(result)
let result: Double = numerator/denumerator
//1.5
As #araf has answered you should look out for the operator precedence in programming language.
Which follow a simple rule of the BODMAS evaluated in following order:
Brackets
Orders
Division and Multiplication (left to right)
Addition and Subtraction (left to right)
In your scenario:
let equation = (5-2) * (10-5) / (4-2) * (10-5)
the output is as follows:
3*5/2*4 = 15/2*5 = 7*5 = 35
#L.Stephan has suggested a better approach of calculating numerator and denumerator separately and then perform the division part.
To know more you can check this link:
https://en.wikipedia.org/wiki/Order_of_operations

What's the difference between M_PI and M_PI_2?

I forked a project from Github, Xcode shows a lot of warnings:
'M_PI' is deprecated: Please use 'Double.pi' or '.pi' to get the value
of correct type and avoid casting.
and
'M_PI_2' is deprecated: Please use 'Double.pi' or '.pi' to get the value
of correct type and avoid casting.
Since both M_PI and M_PI_2 are prompted to be replaced by Double.pi, I assume there are in fact the same value. However, there's this code in the project:
switch angle {
case M_PI_2:
...
case M_PI:
...
case Double.pi * 3:
...
default:
...
}
I'm really confused here, are M_PI and M_PI_2 different? or are they just the same?
UPDATE:
It turns out to be my blunder, Xcode says 'M_PI_2' is deprecated: Please use Double.pi / 2 or .pi / 2 to get the value of correct type and avoid casting. so it isn't a bug, just too hard to notice the difference of 2 prompts.
Use Double.pi / 2 for M_PI_2 and Double.pi for M_PI.
You can also use Float.pi and CGFloat.pi.
In Swift 3 & 4, pi is defined as a static variable on the floating point number types Double, Float and CGFloat.
These constants are related to the implementations of different functions in the math library:
s_cacos.c: __real__ res = (double) M_PI_2 - __real__ y;
s_cacosf.c: __real__ res = (float) M_PI_2 - __real__ y;
s_cacosh.c: ? M_PI - M_PI_4 : M_PI_4)
...
s_clogf.c: __imag__ result = signbit (__real__ x) ? M_PI : 0.0;
M_PI, M_PI_2, and M_PI_4 show up quite often but there's no 2.0 * M_PI. 2π is just not that useful, at least in implementing libm.
M_PI_2 and M_PI_4, their existences are well justified. The documentation of the GNU C library suggests that "these constants come from the Unix98 standard and were also available in 4.4BSD". Compilers were not that smart back at that time. Typing M_PI/4 instead of M_PI_4 may cause an unnecessary division. Although modern compilers can optimize that away (GCC uses mpfr since 2008 so even rounding is done correctly), using numeric constants is still a more portable way to write high-performance code.
M_PI is defined as a macro
#define M_PI 3.14159265358979323846264338327950288
in math.h and part of the POSIX standard.
Follow This
You can find reference answer here
Check This Solution - How you can use it

Why sometimes Apple Accelerate framework is slow?

I am playing with C and Swift 3.0 code using vecLib and Accelerate framework from Apple as dynamic lib + my code in C lang based project and Swift playground.
And in situation with calling Apple's wrapper from framework of SIMD instruction with 1 or < 4 elements computation function like vvcospif() from framework is slower than simple standart cos(x * PI) when functions calls from loop near 1.000 times as example.
I know about difference between vvcospif() and cos(), I should use exactly vvcospif() for x * PI.
Example in playground, you can just copy code and run it:
import Cocoa
import Accelerate
func cosine_interpolate(alpha: Float, a: Float, b: Float) -> Float {
let ft: Float = alpha * 3.1415927;
let f: Float = (1 - cos(ft)) * 0.5;
return a + f*(b - a);
}
var start: Date = NSDate() as Date
var interp: Float;
for index in 0..<1000 {
interp = cosine_interpolate(alpha: 0.25, a: 1.0, b: 0.75)
}
var end = NSDate();
var timeInterval: Double = end.timeIntervalSince(start);
print("cosine_interpolate in \(timeInterval) seconds")
func fast_cosine_interpolate(alpha: Float, a: Float, b: Float) -> Float {
var x: Float = alpha
var count: Int32 = 1
var result: Float = 0
vvcospif(&result, &x, &count)
let SINSIN_HALF_X: Float = (1 - result) * 0.5;
return a + SINSIN_HALF_X * (b - a);
}
start = NSDate() as Date
for index in 0..<1000 {
interp = fast_cosine_interpolate(alpha: 0.25, a: 1.0, b: 0.75)
}
end = NSDate();
timeInterval = end.timeIntervalSince(start);
print("fast_cosine_interpolate in \(timeInterval) seconds")
My question is:
Why vvcospif() is slow in this example?
May be because vvcospif() it is wrapper under Objective-C runtime and converting data structures / copying of memory from Intel SIMD -> Objective-C -> Swift runtime is slower then tiny cos()?
I also have performance issue with C code +
#include <Accelerate/Accelerate.h>
vvcospif(resultVector, inputVector, &count);
when inputVector and resultVector is small arrays with 1 or 2 elements or just float variable, and calls in loop with ~ 1.000.000 times.
cos(x * PI) computation time near 20 ms.
and
vvcospif(x) with processing one float or float array[2] - computation time near 80 ms! Where is Acceleration? :)
Yes, in Xcode I use compiler -O -whole-module-optimization optimisation with whole module opt. enabled.
For a more detailed discussion with examples, see "Introduction to Fast Bezier (and Trying the Accelerate.framework)".
The first, fundamental problem is that non-inlined function calls are extremely expensive. You don't want function calls if you can possibly help it in performance-critical code. Within a module, the compiler can often inline functions for you, and parts of stdlib can be inlined for you. But when you start crossing module barriers, Swift generally cannot optimize out the call.
The point of SIMD functions is that you set up all your data in the right format, and then call them just one time. That way the cost of the function call is made up by the SIMD optimized code you're calling.
But remember, you don't have to call into Accelerate to get SIMD optimizations. The compiler is perfectly capable of noticing you've written a loop and turning it into an inline SIMD algorithm itself (and it does this all the time). So for many simple problems, the compiler is going to win anyway. Think about it: if calling vvcospif with a count of 1 were faster than calling cos, wouldn't they just implement cos that way?
I haven't played with your code much, but if you want to improve its performance with Accelerate, you want to think about how to arrange all your input data so you can call vvcospif one time with a large N. It's quite possible in that case that it will be much faster that a loop (since cos is not trivial).
If you want an example of Accelerate in practice, and how you need to organize your data, see PinchText. This code is computing offsets for a page full of a few thousand glyphs based on up to 10 touches in real-time, with animations (see PinchText.mov for what the result looks like). In particular look at adjustViewPositions:count:forTouchPoint:. Notice how count is large, and the data is transformed step by step with no loops. Even throwing in a (very expensive) ObjC method call into that method doesn't matter very much because it's only made one time. Getting rid of function calls in loops is a huge part of performance programming.