Matlab - make function work with vectors and scalars - matlab

I'm trying to write a function that can be a scalar and a vector. This function should handle scalars, column vector and row vector. My thought was that I try with a for loop but I'm not successful in my attempts.
function f=funk1(x);
for i =1:length(x)
f=exp(-3*x(i).^2)-log(x(i)+0.6)+1/(x(i)-6);
end
end
This only return the last value of the vector (in my function) but I want it to return every value from my vector.

For this specific function you can vectorize, that is, do all computations element-wise at once without a loop. You only need to add a dot before *, ^, / operators when applied between arrays (log and exp are element-wise already):
function f = funk1(x);
f = exp(-3*x.^2)-log(x+0.6)+1./(x-6);
end

You missed indexing of f. Do that;
function f=funk1(x);
for i =1:length(x)
f(i)=exp(-3*x(i).^2)-log(x(i)+0.6)+1/(x(i)-6);
end
end

Related

Perform a function on each value of a vector in matlab?

I have a vector, a, shape (10000,1) filled with values. I also have vector b, same shape, filled with zeros. I want to take my function, apply it to each value in vector a, return those values into vector b. Below is what I tried, as well as a few variations of this. How can I perform this function on each value of the vector and replace each zero in vector b with what that function returns?
for i=1:length(a)
b(i) = function(a)
end
You can use arrayfun to do this
b = arrayfun(#someFunction, a); % Calls b(i) = someFunction(a(i)) for all elements of a
(Although it's common in MATLAB to try and make someFunction be "vectorised", so that you can instead say simple b = someFunction(a))

Vectorize function evaluation in MATLAB

I have the following function,
function Vectorize()
a = randn(1,5)
b = randn(1,5)
c = zeros(1,5)
for i=1:5
c(i) = (a(i) - b(i))/(1+a(i)/2+b(i)/3)
end
I want to vectorize the above function evaluation and replace the for loop.
I could do c = a -b, that finds the difference between two row vectors.I am not sure how to handle the division a/2 and b/2.
Could someone help?
You need the element wise division operation ./
c = (a - b)./(1+a/2+b/3)
If you divide a vector by a scalar, this is not required, but where you divide an array by an array you will have to use ./ in your case. See here for the other element wise operators.

Octave complex element-wise operations

Is there a way to write 'complex' element-wise operations in one line, or do we have to separate them into multiple lines?
For example, let us have this mathematical function: 1/(1+e^-x)
Which I want to calculate for each element on x (x may be a scalar, vector or a matrix).
This is a working code I have written:
function r = sigmoid(x)
r = zeros(size(x));
r = e.^(-x);
r = 1.+r;
r = 1./r;
end
My question is - can we simplify it to one line?
yeah you can do it by below function
function r=sigmoid(x)
r=1./(1+exp(-x))
end
this first consider that the exp function calculate exponential values wise element and added by one and finally result divided 1 over matrix element wise and you can get what you want.

Refactor a function in MATLAB to accept originally scalar argument as an array

Imagine you have a function in MATLAB of two variables, f(x,y). And it was written in a way that x can be a scalar or a 1D array, but y is strictly meant to be a scalar. For an array x the function returns the array of elements of the same length as x.
Next, you need to refactor this function to accept both x and y to be 1D arrays of equal length, the value of a function f([x1,x1],[y1,y2]) = [f(x1,y1), f(x2,y2)].
How would you do this in the most efficient way?
This is exactly suited for arrayfun:
f = #(x,y) y*x.^2; %an example where y should not be an array, x can
fnew = #(xv,yv) arrayfun(f,xv,yv);
This new function will return f(xv(k),yv(k)) for each k as long as the two arrays are of the same size.
Note that arrayfun is quite slow, so using a loop to the same effect or implementing the vectorization for the specific function f (possibly making use of bsxfun) might be faster.
The explicit looping alternative would be
function fv=fnew(xv,yv)
if numel(xv)~=numel(yv)
exit('fnew> xv and yv should have same length');
end
fv=zeros(size(xv));
for k=1:numel(xv)
fv(k) = f(xv(k),yv(k));
end
You can spare some runtime by skipping the size check, similar checks are the reason why arrayfun tends to be slower.

Matlab Function with Varying parameters

I need help figuring out how to code the following problem. Any help would be greatly appreciated!
Create a function that will take a vector/array input for x (1 by n) and a scalar input for a, and produce the output defined by the following equation:
y(x,a)=((xsin(ax-2))/(sqrt(1+(ax)^2)
-π ≤ x ≤ π
a={.5 1 1.5 2}
The equation must be vectorized in terms of x and the output from the function is the array y which has the same dimension as the array x.
Write a script that calls this function to compute y(x,a) for the range of x defined above and each value of the parameter a. Results should be stored in a solution matrix using a different row of the solution matrix for each value of a.
So far for my function I have:
function [y] = part1(a,x)
y=((x*sin(a*x-2))/(sqrt(1+(a*x).^2)));
end
I'm not sure how to output this into the solution matrix
For my script I have:
%%
clear,clc
a={0.5 1 1.5 2};
x=-pi:0.1:pi;
for
part1(x,a)
end
I'm getting the following errors when I run this now:
Undefined function 'mtimes' for input arguments of type 'cell'.
Error in part1 (line 4)
y=((x*sin(a*x-2))/(sqrt(1+(a*x).^2)));
Error in labtest2 (line 8)
y(i,:)=part1(x,a(i));
EDIT
I've made some changes and am still getting some errors that I cannot resolve.
Here is my full code for function followed by full code for script:
Function
function [y] = part1(x,a)
nx=numel(x);
na=numel(a);
y=((x.*sin(a.*x-2))./(sqrt(1+(a.*x).^2)));
size(y)=[nx na]
end
Script
%%
clear,clc
a={0.5 1 1.5 2};
x=-pi:0.1:pi;
for i = 1:length(a)
y(i,:)=part1(x,a(i));
end
Errors
Undefined function 'times' for input arguments of type 'cell'.
Error in part1 (line 6)
y=((x.*sin(a.*x-2))./(sqrt(1+(a.*x).^2)));
Error in labtest2 (line 8)
y(i,:)=part1(x,a(i));
The reason you're getting Undefined function 'times' for input arguments of type 'cell' is because your variable a is a cell array. You need to change your assignment of a from
a={0.5 1 1.5 2};
to
a=[0.5 1 1.5 2];
which will make it just a normal array. Alternatively, you need to reference it with cell array notation: a{i} instead of a(i).
You're almost there. Note that you've written
function [y] = part1(a,x)
but you call it in your script as
part1(x,a)
so you should probably correct that.
A few things jump out at me:
You never assign the output of part1(x,a) to anything. You're told that
Results should be stored in a solution matrix using a different row of the solution matrix for each value of a.
What I take this to mean is that the 1st row corresponds to part1() evaluated for the 1st element of a. Since we're operating on x which is a vector, that row will have multiple columns. Your output is indeed a matrix. In your case, length(-pi:0.1:pi) == 63, therefore size(y) == [4 63], where y is your output matrix.
Your for loop is backwards. You're told to accept scalar a and vector x. Therefore, your script should be something like:
a = 0.5:0.5:2;
x = -pi:0.1:pi;
for i = 1:length(a)
y(i,:) = part1(x, a(i));
end
Note the use of length and the : operator. I want to iterate between 1 to length(a) (in this case, length(a) == 4) so that I can use the current a(i) value as an index into my output matrix, y. The : operator in y(i,:) signifies "The ith row and all columns of y will take the value output by part1(x,a(i))."
Your function needs to be changed up for element-by-element operations. Notice that, for instance, x*sin(a*x-2) works for scalar x but not vectors. This is because x is a vector and sin(a*x-2) is also a vector (since the sin call will operate element-by-element and a is a scalar). Trying to multiply two vectors together will result in errors since MATLAB will try to perform a matrix multiplication. Resolve this by replacing * with .*. This way it is unambiguous that you are going to multiply these two vectors element-by-element. You'll also need to change / to ./.
On another note, thank you for attempting to do your homework before asking SO for help. We've been getting a huge influx of questions from students that have made no attempt to do their own work before dumping it on us, so it's refreshing that we regulars of the MATLAB tag get to actual help out instead of telling people to do their own work.
Finally got the whole thing worked out.
Function
function [y] = part1(x,a)
y=((x.*sin(a.*x - 2))./(sqrt(1 + (a.*x).^2)));
end
Script
%%
clear all;
clc;
close all;
x=[-pi:.1:pi];
a=[.5:.5:2];
for i=1:length(a)
y(i,:)=part1(x,a(i));
plot(x,y)
end
Sol=[y]