How to write a function that returns the element that is the center of a vector or matrix?

how do I start writing a function to do this? I have an idea how to write a script, but not as a function.
example:
123
458
112
ans=[2;5;1]
or
1233
ans=[2,3]

4 Comments

It's a vector. If there is an odd number it will return 1 number, even will return the 2 center numbers
I think Azzi's question was just because the way you wrote the input:
[1 2 3 3]
is a row-vector, however:
[1223]
is just a number
oh I see. The first should be a matrix, [1,2,3;4,5,8;1,1,2] The second [1,2,2,3]

Sign in to comment.

 Accepted Answer

Hi Kimberly,
Your function signature could look something like this:
function [ctr] = find_centre (x)
<code to be filled in by you!>
end
where x is your input (from your examples 1233 or [123;458;112]) and ctr is the found centre of the x (again from your examples, [2 3] or [2;5;1]).
I'm guessing that if your input is a matrix then the output should be the centre of each row?
Since you say that your input can be a vector or a matrix (a string of characters can be a vector so whether your input is a row of characters, numbers, cells, or whatever, the logic should be the same) then you probably want to handle the inputs separately by checking to see if x is a vector or is a matrix using the isvector and ismatrix functions respectively. (Note that a vector can be a matrix but not the other way around, so you will want to start with the vector check.)
If the input is a vector, then check its size/length using either of numel (number of elements) or length. The centre of your vector then will be dependent upon whether the size is even or odd (as you have shown in your examples) and you can then extract it from x and set it in ctr via the ctr = x(cstart:cstop); where cstart and cstop are the centre start and stop indices within the vector. From your example of 1223, then cstart=2 and cstop=3. If just 123, then cstart=2 and cstop=2 as well.
If the input is a matrix then you can get the number of rows and columns and do something similar to the above.
Geoff

12 Comments

I have to write this using loops. For example :if matrix1 is odd it will have 1 return, the number in the center of the matrix. And if it is even it will return 2 center numbers. I will use matrix1(length(matrix1)) to give me the actual value of the numbers in the center. Fprintf to display it.
Calling length on a matrix (say x ) will just return the maximum dimension: so the maximum of the number of rows or the number of columns (assuming the matrix is 2D) which is fine if the matrix is square.
If the matrix is NOT square then use [r,c] = size(x); to get the number of rows (r) and the number of columns (c). Then loop over each row (since you are trying to find the centre of that row) and if the number of columns is odd (i.e. mod(c,2)~=0 here I'm checking to see if value of c is NOT divisible by two and so is odd) then just grab the centre x(i,(c+1)/2) of that row (where i is the row number and c is the number of columns in that row). Else if the number of columns is even (i.e. mod(c,2)==0 ) then grab the middle two elements of row i: x(i,c/2:c/2+1) (here I'm grabbing a range of consecutive elements of row i).
Note that the above is valid for vectors too.
I'm sorry its not loops its "if" and "elseif" i have to use. this is the actual question, 1. Write a function that will return the element(s) that is in the center of a vector or matrix. If the vector or matrix has an even number of elements, return the two elements that are in the center. If the matrix has an odd number of elements, return the single element. Run this code for Matrix1 and VectorA and VectorB. Example: [0, 1, 2, 3, 4, 5]  2,3 [0,1,2]  1 [0, 1, 2, 3, 4, 5; 9, 8, 7, 6, 5, 4]  [2,3;7,6] Hint: Use size( ) , rem( ,2), and if, elseif and ceil( ) and floor( )
I have my function written, but how do I write code to find if the matrix is odd or even?
numel(mtx) will return the number of elements in the matrix (or vector). If that number is even, then it is divisible by two i.e. mod(numel(mtx),2)==0. Here the code is just using the modulo function to return the remainder of dividing the number of elements by two.
this is what ive gotten so far,
function(cntr)=(findcenter)(data)
if rem(length(data), 2) == 1
B=data(ceil(end/2))
else
C = data(cstart:cstop)
length will return the maximum dimension size/value and is suitable when your input (data) is a vector but not for a matrix since it returns on,y the largest dimension and not the number of elements in the matrix. numel is more appropriate or use [r,c]=size(data); to return the number of rows (r) and columns(c) of the matrix. Then the product of r and c will tell you how many elements in the matrix, and if that product is even or odd will be handled in your code.
Use of rem as you gave done above is sufficient for determining if the number of elements is odd or even.
Some of the syntax above is incorrect for your function signature.
The code for B and C (why the different variable names) may be fine for a vector but not necessarily for a matrix.
How did you find start and stop?
the start and stop is where I'm getting confused. I know what I want to find, just have trouble writing it in a code that works.
The first if statments will work for a matrix. but not the second. Im guessing I have to define cstart and cstop, but how would I do that?
So the second case is for when the number of elements is even. If your vector is 1x6 the you need to return the middle two elements at indices 3 and 4: 3=6/2 and 4=6/2 + 1. So for the more general case of a 1xN vector with N even, then the middle two elements are N/2 and N/2 + 1. These will be your start and stop indices respectively.
Now when you have a matrix (can we assume that it will always be square?) if the number of elements is odd then you have to return the middle element: so if the matrix A is 5x5 then the middle element is A(3,3) or is it the middle element of each row so A(:,3). I am not sure based on the provided examples...
But if the matrix has an even number of elements, say A is 6x6, then the middle is A(3:4,3:4). Or is it the middle of each row A(:,3:4)?
So I think that all that you need to figure out for matrices, what exactly is the middle: the middle of each row or the four elements from the middle two rows and middle two columns.
Im assuming its asking for the dead center of the entire matrix, not of each individual row.
function [ cntr ] = findcenter( data )
%UNTITLED4 Summary of this function goes here
% Detailed explanation goes here
[a,c]=size(data)
if rem(length(data), 2) == 1
B=data(ceil(end/2))
else
cstart=(data./2)
cstop =(data./2+1)
B= data(cstart:cstop)
end
end
now this returns this error,
??? Output argument "cntr" (and maybe others) not assigned during call
to "F:\matlab\findcenter.m>findcenter".
Ive checked the libraries where the functions are stored and theyre in the right folders..
All that the error is telling you is that you have not assigned the output variable cntr to anything. This variable should be your B in your above code. So just replace B with cntr or vice-versa.
You have a line of code
[a,c]=size(data);
which returns the rows (may want to chane a to r). This is good because from this you can determine the number of elements in the matrix or vector, call it n say where
n=r*c;
Now use this n in place of your call to length since that command will only work correctly for vectors and you want the count of all elements in the matrix and not just the number of elements along the largest dimension.
The assignments to cstart and cstop are not correct: you are taking the input matrix and dividing each element by 2 and so the start and stop variables are matrices! Instead replace with the number of elements in the matrix, n.
You may still want to handle the case of the input being a vector or a matrix because I'm not convinced the code will always work correctly for matrices (and I don't have access to MATLAB right now to test it out).
And please consider putting break points in your code and stepping through it to see what is happening for your different test cases.
Thank you for all your help. I played around with it and got it to run for both matrices and vectors.

Sign in to comment.

More Answers (1)

Hi Kimberly, try this:
% Set up some input
x = [1 2 3
4 5 8
1 1 2]
% Grab the middle column(s)
xMidVal = (size(x,2)+1) / 2;
midInds = unique([floor(xMidVal) ceil(xMidVal)]);
out = x(:,midInds)
Did that answer the question for you?

4 Comments

This returned a strange answer in decimals. Ill write the return here once i get to class to use matlab.
Kimberly, this answer will only return decimals (into the variable I have called out) if the input (in variable x) contains decimals. You can just copy into MATLAB and see that it returns exactly what you're looking for:
out =
2
5
1
It works similarly when you set x = [1 2 3 3]:
out =
2 3
Ha, thanks SS :)
Kimberley, you are receiving quite detailed answers from Geoff who has (kindly) devoted time to helping you. I think that an hour or so reading some of the getting started guide will also be of much benefit. Two topics: Matrices and arrays and Programming and scripts would be great places to start.

Sign in to comment.

Categories

Asked:

on 17 Apr 2014

Commented:

on 21 Apr 2014

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!