I am trying out the questions in programming assignment of Coursera course on Matlab programming as an exercise. This is my Question:
Write a function called sort3 that takes three scalar arguments. It uses if-statements, possibly nested, to
return the three values of these arguments in a single row-vector in increasing order (or more precisely,
non-decreasing order), i.e., element one of the output vector equals the smallest input argument and
element three of the output vector equals the largest input argument.
Here is my code:
function sv = sort3(x,y,z)
if nargin < 3
error('must have at least three input argument');
else
if ~isscalar(x) || x ~= fix(x)
error('x needs to be a scalar');
end
if ~isscalar(y) || y ~= fix(y)
error('y needs to be a scalar');
end
if ~isscalar(z) || z ~= fix(z)
error('z needs to be a scalar');
end
end
a=x;
b=y;
c=z;
if a >= b
t=a;
a=b;
b=t;
end
if b >= c
t=b;
b=c;
c=t;
end
if a >= b
t=a;
a=b;
b=t;
end
if nargout == 1
sv=[a b c];
end
I got the below result on Matlab.
Problem 3 (sort3):
Feedback: Your program made an error for argument(s) -1.3719900292403, -0.639443998445333, 1.04704952581735
Please help me.
Thanks.
When you compare x with fix(x) your program moves to the command error that you have written.
When you pass to your function a decimal number, obviously x is always not equal to fix(x) and then your function will always end with an error.
If you want to work only with scalars or integers, you can think to apply function fix to your input before to start with your algorithm.
Related
Question: Write a function file that returns the sum of the positive components and the sum of the negative components of the input vector.
This problem has to be done in MATLAB but I am completely new in MATLAB? Can anyone give idea how to do this?
Attempts:
V= input(Enter a vector)
function [Ps, Ns] = mysmallfunction(V)
Ps== sum(V(V>0));
Ns= sum(V(V<0));
end
I don't know whether it will work or not.
You pretty much had it. Below is a script that'll guide you through passing the arguments and calling the function. A small issue was the double == for the assignment of Ps within the function (simply use one = unless it's for a conditional statement). To call/test the function simply use the line [Ps, Ns] = mysmallfunction(V); above your function definition (alternatively can put function definitions in separate scripts).
V = input("Enter a vector: ");
%Function call%
[Ps, Ns] = mysmallfunction(V);
%Printing the results to the command window%
fprintf("The positive numbers sum up to %f\n",Ps);
fprintf("The negative numbers sum up to %f\n",Ns);
%*******************************************************************************************************%
%FUNCTION DEFINITION (this can alternatively go in a separate script named: mysmallfunction.m)%
%*******************************************************************************************************%
function [Ps, Ns] = mysmallfunction(V)
Ps = sum(V(V>0));
Ns = sum(V(V<0));
end
Command Window (sample input)
Important to include the square brackets, [] in this case when inputting the vector.
Enter a vector: [1 2 3 -2 -5]
I'm trying to build a function in Matlab which generates a Taylor series around 0 for sine and the user can insert x (the value for which the sine is approximated) and a maximum error. Thus I want the function to check the maximum error and from this maximum it generates the amount of elements in the Taylor series.
I get the following error:
Error using factorial (line 20)
N must be an array of real non-negative integers.
Error in maxError (line 19)
y(x) = y(x) + (-1)^(j) * x^(2j+1)/factorial(2j+1)
Below my code.
function [n] = maxError(x,e);
%Computes number of iterations needed for a given absolute error.
n=1;
while abs(x)^(n+1)/factorial(n+1) >= e
n = n+1;
end
if mod(n,2) == 0
n=n+1;
end
y=#(x) x;
j=1;
while j<n
y(x) = y(x) + (-1)^(j) * x^(2j+1)/factorial(2j+1)
j=j+1;
end
return
I think I get the error because the factorial function can only take up integers, but the way I see it, I am feeding it an integer. Since j=1; and then gets larger by one per iteration, I don't see how Matlab can perceive this as something else than a integer.
Any help is appreciated.
You are using j as an indexing variable, which is also the complex number in Matlab, and your are forgetting a * multiply.
You can use j as a variable (not recommended!) but when you are putting a number in front of it, Matlab will stil interpret is as the complex number, and not as the variable.
Adding the multiplication symbol will solve the issue, but using i and j as variables will give you these hard to debug errors. If you had used a, the error would have been easier to understand:
>> a=10;
>> 2a+1
2a+1
↑
Error: Invalid expression. Check for missing multiplication operator, missing or
unbalanced delimiters, or other syntax error. To construct matrices, use brackets
instead of parentheses.
I am trying to pass a vector into a function, and evaluate the vector over a piecewise function. When I run the code below, I am only returned a single number rather than a vector. Any ideas?
Thanks!
t[-5:1:50]
velocity(t)
function [v] = velocity( t )
%This function takes vector 't' and evaluates a velocity over a given
%piecewise function
if t>=0 & t<=8
v=10*t^2-5*t;
elseif t>=8 & t<=16
v=624-5*t;
elseif t>=16 & t<=26
v= 36*t+12*(t-16)^2;
elseif t>26
v=2136*exp(-0.1*(t-26));
else t<0
end
When you elevate a vector to the square, you are performing a scalar product with itself.
Replace t^2 with t.^2 for element-wise operators.
Do the same for (t-16).^2.
All the other operators should fall automatically into the element wise case but you can add points before them to be sure.
And, furthermore, the conditions as you have wrote them apply to a t as a scalar value. You can get the researched effect by doing the following:
Instead of
if cond1:
v = something
elif cond2:
v = something_else
Do
indices1 = (cond1) % where cond1 is t < 10 for example
indices2 = (cond2) % and cond2 is t >= 10
v[indices1] = something
v[indices2] = something_else
I hope you get the gist.
I have a function that returns three values [A,B,C]=ABC(x).
Is it possible to define a function A(x) in an elegant way such that returns the first value of ABC(x), B(x) for the second value, etc.?
Thanks
Not completely clear whether you really mean that ABC returns a vector, or that it returns three values (each of which might be any object). If you really mean "vector" with three elements, [A B C]. then you could do:
function a = A(x)
temp = ABC(x);
a = temp(1);
As you wrote your function ([A,B,C]=ABC(x)) it does not return a vector per say, it returns 3 values.
If you call your function like this
a = ABC(x)
a would be equal to A.
EDIT :
function b = B(x)
[~, b, ~] = ABC(x)
end
You could include a 2nd input argument if it is acceptable to you. You could use varargin to accept variable number of input arguments.
function outValue=ABC(varargin);
if nargin==0
error('Need at least one argument');
elseif nargin==1
%obtain result
outValue=result;
elseif nargin==2
%obtain result
outValue=result(index);
else
error('Function accepts maximum of 2 arguments');
end
end
Once again I have a problem with the Gauss-Seidel Method in Matlab. Here it is:
function [x] = ex1_3(A,b)
format long
sizeA=size(A,1);
x=zeros(sizeA,1);
%Just a check for the conditions of the Gauss-Seidel Method (if it has dominant diagonal)
for i=1:sizeA
sum=0;
for j=1:sizeA
if i~=j
sum=sum+abs(A(i,j));
end
end
if abs(A(i,i))<sum
fprintf('\nGauss-Seidel''s conditions not met!\n');
return
end
end
%Actual Gauss-Seidel Method
max_temp=10^(-6); %Pass first iteration
while max_temp>(0.5*10^(-6))
xprevious=x;
for i=1:sizeA
x(i,1)=b(i,1);
for j=1:sizeA
if i~=j
x(i,1)=x(i,1)-A(i,j)*x(j,1);
end
end
x(i,1)=x(i,1)/A(i,i);
end
x
%Calculating infinite norm of vector x-xprevious
temp=x-xprevious;
max_temp=temp(1,1);
for i=2:sizeA
if abs(temp(i,1))>max_temp
max_temp=abs(temp(i,1));
end
end
end
It actually works fine for a 100x100 matrix or smaller. However, my tutor wants it to work for 100000x100000 matrices. At first it was difficult to even create the matrix itself, but I managed to do it with a little help from here:
Matlab Help Center
Now, I call the ex1_3 function with A as a parameter, but it goes really slow. Actually it never ends. How can I make it work?
Here's my code for creating the specific matrix my tutor wanted:
The important part is just that it meets these conditions:
A(i; i) = 3, A(i - 1; i) = A(i; i + 1) = -1 n=100000
b=ones(100000,1);
b(1,1)=2;
b(100000,1)=2;
i=zeros(299998,1); %Matrix with the lines that we want to put nonzero elements
j=zeros(299998,1); %Matrix with the columns that we want to put nonzero elements
s=zeros(299998,1); %Matrix with the nonzero elements.
number=1;
previousNumberJ=0;
numberJ=0;
for k=1:299998 %Our index in i and j matrices
if mod((k-1),3)==0
s(k,1)=3;
else
s(k,1)=-1;
end
if k==1 || k==2
i(k,1)=1;
j(k,1)=k;
elseif k==299997 || k==299998
i(k,1)=100000;
j(k,1)=(k-200000)+2;
else
if mod(k,3)==0
number=number+1;
numberJ=previousNumberJ+1;
previousNumberJ=numberJ;
end
i(k,1)=number;
j(k,1)=numberJ;
numberJ=numberJ+1;
end
end
A=sparse(i,j,s); %Creating the sparse array
x=ex1_3(A,b);
the for loop works very slowly in Matlab, perhaps you may want to try the matrix form of the iteration:
function x=gseidel(A,b)
max_temp=10^(-6); %Pass first iteration
x=b;
Q=tril(A);
r=b-A*x;
for i=1:100
dx=Q\r;
x=x+1*dx;
r=b-A*x;
% convergence check
if all(abs(r)<max_temp) && all(abs(dx)<max_temp), return; end
end
For your A and b, it only takes 16 steps to converge.
tril extracts the lower triangular part of A, you can also obtain this Q when you build up the matrix. Since Q is already the triangular matrix, you can solve the equation Q*dx=r very easily if you are not allowed to use \ function.