Confused about behaviour of remainder operator in Swift - swift

I am trying to calculate two random numbers constrained to a particular range using arc4random and the % operator.
I am not able to figure out why the compiler is complaining when calculating (x1,y1) when almost the same thing is done for x2,y2 except for using an int literal directly.
Any ideas?
The code sample is:
import Darwin
let w1:Int = 223
// error: Could not find an overload for '%' that accepts the supplied arguments
let (x1,y1) =
(
arc4random() % w1,
arc4random() % 345
)
let (x2,y2) =
(
arc4random() % 223,
arc4random() % 345
)

That's due to Swift's enforcement of type safety.
arc4random() returns a UInt32, while you've declared w as an Int, so a compiler error is thrown. That'd also happen if you had tried to sum or divide w and the result of calling arc4random(), so the behaviour is not exclusive to the remainder operator.
You have a few options, depending on how you intend to use the resulting value of the operation.
You can declare w1 as an UInt32 in the first place:
var w1: UInt32 = 223
Or, you can cast it to an UInt32 before performing the remainder operation:
arc4random() % UInt32(w1)
Finally, you can initialize an Int from the result of the arc4random() call and use it with the Int version of w1
Int(arc4random()) % w1
Note that this behaviour does not apply to literals.
From the Apple provided iBook:
The rules for combining numeric constants and variables are different
from the rules for numeric literals. The literal value 3 can be added
directly to the literal value 0.14159, because number literals do not
have an explicit type in and of themselves. Their type is inferred
only at the point that they are evaluated by the compiler.
That's why you don't see the same problem occur when doing arc4random() % 345.

You need to use the same type for both variables, to wit:
let w1:UInt32 = 223
Should solve the problem
The error is because you are trying to use an Int and a UInt32

Related

Arrays have incompatible sizes for this operation

function r = fun(x, params, type)
h = #(x) x(1)-x(8);
x= sym('x',[1,8]);
gamma = 16;
if type == 'linear'
r = gamma*h(x);
elseif type == 'sin'
r = gamma*sin(h(x));
end
end
When I run this function for type 'sin' I always get this error
Arrays have incompatible sizes for this operation.
Error in fun (line 7)
if type == 'linear'
How to fix this?
I just one to pass type and depending on that create my ouput, I though string could be okay, but it doesn't work.
I want to multiply my function handle with gamma in case of linear and multiply and take sin in case of sine.
You may mean
if strcmp(type,'linear')
type is a char array, and matlab does not support that type of direct array to array comparison for text. It tries to compare each letter with each other, but if length(type) is not the same as length('linear') it errors.

Support for pow() with decision variables in MiniZinc

I am trying to build a model with a decision variable that takes the range 0..10 with the constraint
that it must be divisible by 4.The output must be the one that minimizes the value (x-7)^2. Investigating I see that Gecode already supports it.
I have tried to build the model as follows but I get an error using the built-in pow()
% Decision variable
var 0..10: x;
% Constraints
constraint (x mod 4) == 0;
% Call to the resolver
int: obj = pow(x-7, 2);
solve minimize obj;
% Solution
output["x = ", show(x), "\nobj = ", show(obj)];
I get the following error:
MiniZinc: type error: initialisation value for `obj' has invalid type-inst: expected `int', actual `var int'
I think it occurs because is considering the variable as a decision variable instead of just an integer parameter.
#hankank's solution is correct. Using var int: obj = pow(x-7, 2);
Variables (e.g., var int) in MiniZinc are decision variables and other names (which you might call variables in Python) are referred to as parameters (e.g., par int or int). These are two distinct types for a good reason: any calculation with only parameter is guaranteed to be able to be executed during MiniZinc compilation, while any calculation that uses a variable will generally have to be decided by a solver.
Note, that using pow actually might also bring problems for linear solver (i.e., MIP solvers). In this case the calculation can still be made linear because the transformation is using a constant, but the expression pow(x,y) where both arguments are variables could not be decided by a linear solver.
To move the pow() call from solution time to compilation time, you could use a pre-calculated array:
% Decision variable
var 0..10: x;
set of int: DomainX = 0..10;
array[DomainX] of int: xa = array1d(DomainX, [pow(i-7, 2) | i in DomainX]);
% Constraints
constraint (x mod 4) == 0;
% Call to the resolver
var int: obj = xa[x];
solve minimize obj;
% Solution
output["x = ", show(x), "\nobj = ", show(obj)];
As commented by hakank, variable obj must be of type var int, as it depends on a decision variable.

matlab can't use dot operator on object

I came across a weird problem today while practicing using classes in MATLAB. It seems like MATLAB can't parse parentheses around an object.
I created a user-defined class named vector that has various attributes: magnitude, angle, length in the x and y directions. I overloaded the unary minus operator so that I can have
a = vector(5,50) % creates a vector with magnitude 5 and angle 50 (in degrees)
a.ang % prints the angle
b = -a
b.ang % 230 degrees
This is all fine and good, but say that I want to find the angle of the -a in one line. You'd expect something like
(-a).ang
to work but instead I get
(-a).ang
|
Error: Unexpected MATLAB operator.
I can't use
-a.ang
either because the dot operator has higher precedence than the minus. Any explanation of why matlab can't parse parentheses around an object?
EDIT: Here's the vector class that I created.
classdef vector
properties
mag
ang % in degrees
x
y
end
methods
function v = vector(mag,ang)
if nargin == 2
v.mag = mag;
v.ang = ang;
v.x = mag*cosd(ang);
v.y = mag*sind(ang);
end
end
function res = plus(u,v)
x = u.x + v.x;
y = u.y + v.y;
res = vector(norm([x,y]), atan2d(y,x));
end
function res = minus(u,v)
x = u.x - v.x;
y = u.y - v.y;
res = vector(norm([x,y]), atan2d(y,x));
end
function res = uminus(v)
res = vector;
res.x = -v.x;
res.y = -v.y;
res.mag = v.mag;
res.ang = mod(v.ang+180,360);
end
end
end
I think I've found the answer. In general, Matlab does not support two sets of parentheses chained together because it could either be an indexing or a function call.
MATLAB's parser is limited, partly for historical reasons. It has never
been possible to do something like f(4)(1) because of the ambiguity. Does it mean that f(4) is a function handle and then we want to pass 1 into that function or does it mean that f is a function, we pass 4 into that function, it returns a vector and then we index into the first element of that? Well, the parser doesn't know either. It could be defined, but it hasn't up till now.
Source: https://www.mathworks.com/matlabcentral/newsreader/view_thread/280225
Also, once I had realized that the two side-by-side parentheses were the problem, it seems that the main workarounds are either:
Use the SUBSREF function to explicitly evaluate the parentheses
Define your own anonymous function to perform the indexing and array handling for you.
Those workarounds are explained in the first two answers in the below link.
How can I index a MATLAB array returned by a function without first assigning it to a local variable?
Thanks for looking over my question guys!
I cannot replicate vector function but for a simple structure like this
a.ang=[2,4,6,8]
what you need is
-a.ang
instead of
(-a).ang
which will reproduce the error you mentioned

Matlab nchoosek got difference answer using int64 and sym

This is a question about the function nchoosek in Matlab.
I want to find nchoosek(54,25), which is the same as 54C25. Since the answer is about 10^15, I originally use int64. However the answer is wrong with respect to the symbolic one.
Input:
nchoosek(int64(54),int64(25))
nchoosek(sym(54),sym(25))
Output:
1683191473897753
1683191473897752
You can see that they differ by one. This is not really an urgent problem since I now use sym. However can someone tell me why this happens?
EDIT:
I am using R2013a.
I take a look at the nchoosek.m, and find that if the input are in int64, the code can be simplified into
function c = nchoosek2(v,k)
n = v; % rename v to be n. the algorithm is more readable this way.
classOut = 'int64';
nd = double(n);
kd = double(k);
nums = (nd-kd+1):nd;
dens = 1:kd;
nums = nums./dens; %%
c = round(prod(nums));
c = cast(c,classOut);
end
However, the outcome of int64(prod(nums./dens)) is different from prod(sym(nums)./sym(dens)) for me. Is this the same for everyone?
I don't have this problem on R2014a:
Numeric
>> n = int64(54);
>> k = int64(25);
>> nchoosek(n,k)
ans =
1683191473897752 % class(ans) == int64
Symbolic
>> nn = sym(n);
>> kk = sym(k);
>> nchoosek(nn,kk)
ans =
1683191473897752 % class(ans) == sym
% N!/((N-K)! K!)
>> factorial(nn) / (factorial(nn-kk) * factorial(kk))
ans =
1683191473897752 % class(ans) == sym
If you check the source code of the function edit nchoosek.m, you'll see it specifically handles the case of 64-bit integers using a separate algorithm. I won't reproduce the code here, but here are the highlights:
function c = nchoosek(v,k)
...
if int64type
% For 64-bit integers, use an algorithm that avoids
% converting to doubles
c = binCoef(n,k,classOut);
else
% Do the computation in doubles.
...
end
....
end
function c = binCoef(n,k,classOut)
% For integers, compute N!/((N-K)! K!) using prime factor cancellations
...
end
In 2013a this can be reproduced...
There is as #Amro shows a special case in nchoosek for classOut of int64 or unit64,
however in 2013a this is only applied when the answer is between
flintmax (with no argument) and
double(intmax(classOut)) + 2*eps(double(intmax(classOut)))
which for int64 gives 9007199254740992 & 9223372036854775808, which the solution does not lie between...
If the solution had fallen between these values it would be recalculated using the subfunction binCoef
for which the help states: For integers, compute N!/((N-K)! M!) using prime factor cancellations
The binCoef function would have produced the right answer for the given int64 inputs
In 2013a with these inputs binCoef is not called
Instead the "default" pascals triangle method is used in which:
Inputs are cast to double
The product of the vector ((n-k+1):n)./(1:k) is taken
this vector contains k double representations of fractions.
So what we have is almost certainly floating point error.
What can be done?
Two options I can see;
Make your own function based on the code in binCoef,
Modify nchoosek and remove && c >= flintmax from line 81
Removing this expression will force Matlab to use the more accurate integer based calculation for inputs of int64 and uint64 for any values within their precision. This will be slightly slower but will avoid floating point errors, which are rightfully unexpected when working with integer types.
Option one - should be fairly straight forward...
Option two - I recommend keeping an unchanged backup of the original function, or makeing a copy of the function with the modification and use that instead.

How to make a modulo operation in objective-c / cocoa touch?

I have two CGFloat values, and want to calculate the modulo result. Or in other words: I want to know what's left if valueA is placed as much as possible into valueB.
So I just tried:
CGFloat moduloResult = valueB % valueA;
the compiler complains about the % and tells me: "invalid operands to binary %". Any idea?
% is for int or long, not float or double.
You can use fmod() or fmodf() from <math.h> instead.
Better is <tgmath.h> as suggested by the inventor of CGFloat.
If I remember correctly modulo requires 2 ints as its input so you'd need something like:
CGFloat moduloResult = (float)((int)valueB % (int)valueA);
Assuming that valueB and valueA are both floats