4

I have two float variables:

x = 0.5;
y = 1.5;

I would like to floor them:

x = floor(x);
y = floor(y);

Can i do it in a single command? this raises an error:

[x y] = floor([x y]);
Ben Brocka
  • 2,006
  • 4
  • 34
  • 53
dynamic
  • 46,985
  • 55
  • 154
  • 231
  • Why is it you "need" the two variables separately? – Rody Oldenhuis Nov 30 '12 at 14:22
  • Nothing really in particular... but this is a general question that can be applied to another usage. Don't focus on x, y – dynamic Nov 30 '12 at 14:22
  • Then why not use `z = floor([x y])`? It's bound to be faster than @H.Muster's solution...If you must, just do `x = z(:,1), y = z(:,2)` at some point. – Rody Oldenhuis Nov 30 '12 at 14:24
  • Like @RodyOldenhuis, I would also prefer the clean `floor` version over the wrapper I posted below to answer what the OP specifically asked for. – H.Muster Nov 30 '12 at 14:27

4 Answers4

7

You can write your own wrapper for floor:

function varargout = myFloor(varargin)
for k = 1:nargin
    varargout{k} = floor(varargin{k});
end

This function shows the required behavior if you provide x and y as two separated arguments

[a, b] = myFloor(x,y)

This results in

a =

     0


b =

     1

If you want to use the concatenated array [x y] as input (like in your example) you can use the following function:

function varargout = myFloor(x)
for k = 1:numel(x)
    varargout{k} = floor(x(k));
end

Then you would call

[a, b] = myFloor([x y])

This results in

a =

     0


b =

     1
H.Muster
  • 9,297
  • 1
  • 35
  • 46
2

Just adding a random idea here...

Building on H.Muster solution, you might want to define a personalized deal function, which is like deal but also applies a function to each argument:

function varargout = myDeal(fun, varargin)
    if nargin == 2
        varargout(1:nargout) = {feval(fun, varargin{1})};
    elseif nargin-1 == nargout
        for k = 1:nargout
            varargout{k} = feval(fun, varargin{k}); end
    else
        error('Argument count mismatch.');
    end
end

This way, you can multi-assign any function:

>> [x,y,z] = myDeal(@floor, 0.5, 0.6, 2.7)
x =
     0
y =
     0
z =
     2

>>  [x,y,z] = myDeal(@sin, pi/6)
x =
     4.999999999999999e-01
y =
     4.999999999999999e-01
z =
     4.999999999999999e-01

>> [a, b] = myDeal(@fix, 10*rand(2), 8*rand(5))         
a =
     7     2
     7     6
b =
     5     2     4     1     6
     1     4     5     1     1
     0     1     7     2     7
     3     6     7     6     2
     7     2     4     2     1
Rody Oldenhuis
  • 37,726
  • 7
  • 50
  • 96
  • @yes123: It will not be fast, at least, not as fast as doing things the vectorized way. Therefore I'd advise against using this in any "production code" or in performance-sensitive areas. – Rody Oldenhuis Nov 30 '12 at 15:12
  • 1
    @yes123: a similar idea can be found in the function `disperse` [on the File Exchange](http://blogs.mathworks.com/pick/2012/03/02/when-deal-doesnt-work-disperse-2/) – Jonas Nov 30 '12 at 15:18
  • @Jonas: yes, I thought as much...truly new ideas are rare :) – Rody Oldenhuis Nov 30 '12 at 16:12
  • @Jonas: Ah! But `disperse` doesn't pass things through functions, like the one above! :) – Rody Oldenhuis Nov 30 '12 at 16:14
1

No it is not possible.
Floor can only accept one argument as it can be seen from the syntax. You can see the reference below to verify:

http://www.mathworks.in/help/symbolic/mupad_ref/floor.html

Fyre
  • 1,180
  • 8
  • 12
0

if

    A = [0.5 1.5]

then you can do

    floor(A)

that would result in

    ans = [0 1]

Here's an example: http://www.matlabtutorials.com/functions/floor.html

Rodrigo Neves
  • 220
  • 2
  • 12
  • I need the results to be in the x and y var in a single command if it's possible – dynamic Nov 30 '12 at 14:15
  • Then the answer is no. As Fyre said, floor() can only take one argument, which can in fact be a vector, but it will return a vector back. – Rodrigo Neves Nov 30 '12 at 14:16