Simple MATLAB Variable Question - matlab

Please help me write a MATLAB program that constructs a column matrix b, such that
b1 = 3x1 - 3/4y0
b2 = 3x2
...
bn-2 = 3xn-2
bn-1 = 3xn-1 - 3/4yn
where x and y are variables. Notice that y only appears in the first and last entries of b.
My problem is that I don't know how variables work in MATLAB. I tried
b = 3*x
and it says
??? Undefined function or variable 'x'
So, how do we create variables instead of constants?
Thanks!

EDIT:
From your comments above, what you need is MATLAB's symbolic toolbox, which allows you to perform computations in terms of variables (without assigning an explicit value to them). Here's a small example:
syms x %#declare x to be a symbolic variable
y=1+x;
z=expand(y^2)
z=
x^2 + 2*x + 1
You will need to use expand sometimes to get the full form of the polynomial, because the default behaviour is to keep it in its simplest form, which is (1+x)^2. Here's another example to find the roots of a general quadratic
syms a b c x
y=a*x^2+b*x+c;
solve(y)
ans =
-(b + (b^2 - 4*a*c)^(1/2))/(2*a)
-(b - (b^2 - 4*a*c)^(1/2))/(2*a)
I think you meant bn and xn in the last line... Anyway, here's how you do it:
b=3*x;
b([1,end])=b([1,end])-3/4*y([1,end])
You can also do it in a single line as
b=3*x-3/4*[y(1); zeros(n-2,1); y(end)];
where n is the length of your vector.

You never stated your problem...
Anyways just set the first entry of b individually first. Then use a loop to set the next values of b from 2 up to n-2. Then set the last entry of b individually.
On a side note, if x is a vector, you can simply vectorize the loop part.

Related

Row--wise application of an inline function

I defined an inline function f that takes as argument a (1,3) vector
a = [3;0.5;1];
b = 3 ;
f = #(x) x*a+b ;
Suppose I have a matrix X of size (N,3). If I want to apply f to each row of X, I can simply write :
f(X)
I verified that f(X) is a (N,1) vector such that f(X)(i) = f(X(i,:)).
Now, if I a add a quadratic term :
f = #(x) x*A*x' + x*a + b ;
the command f(X) raises an error :
Error using +
Matrix dimensions must agree.
Error in #(x) x*A*x' + x*a + b
I guess Matlab is considering the whole matrix X as the input to f. So it does not create a vector with each row, i, being equal to f(X(i,:)). How can I do it ?
I found out that there exist a built-in function rowfun that could help me, but it seems to be available only in versions r2016 (I have version r2015a)
That is correct, and expected.
MATLAB tries to stay close to mathematical notation, and what you are doing (X*A*X' for A 3×3 and X N×3) is valid math, but not quite what you intend to do -- you'll end up with a N×N matrix, which you cannot add to the N×1 matrix x*a.
The workaround is simple, but ugly:
f_vect = #(x) sum( (x*A).*x, 2 ) + x*a + b;
Now, unless your N is enormous, and you have to do this billions of times every minute of every day, the performance of this is more than acceptable.
Iff however this really and truly is your program's bottleneck, than I'd suggest taking a look at MMX on the File Exchange. Together with permute(), this will allow you to use those fast BLAS/MKL operations to do this calculation, speeding it up a notch.
Note that bsxfun isn't going to work here, because that does not support mtimes() (matrix multiplication).
You can also upgrade to MATLAB R2016b, which will have built-in implicit dimension expansion, presumably also for mtimes() -- but better check, not sure about that one.

matlab Pythagorean Theorem without using for

I am doing a matlab homework and I solved the next problem. and the grader say it is a correct answer. I used for in the program and we didn't take yet in the course. can someone suggest a program with out for or if.
Write a function called pitty that takes a matrix called ab as an input argument. The matrix ab has exactly two columns. The function should return a column vector c that contains positive values each of which satisfies the Pythagorean Theorem, a2 + b2 = c2, for the corresponding row of ab assuming that the two elements on each row of ab correspond to one pair, a and b, respectively, in the theorem. Note that the built-in MATLAB function sqrt computes the square root and you are allowed to use it.
my code
function c = pitty(ab)
[n , m] = size(ab)
for i = 1:n
c(i) = sqrt(ab(i,1)^2 + ab(i,2)^2)
end
c = c'
end
You can square each element of the matrix by using the .^2 operator. Then summing along each row sum(...,2) and finally taking the root.
ab = [1,2;3,4;5,6]
c = sqrt(sum(ab.^2,2));
No for needed for that.
MATLAB has a function for this called hypot short for hypotenuse. The main reason for existence of it is that it takes care of overflow (and underflow) problem. If the input values are too large (or small) the square of them (or sum of square of them) can be larger (smaller) than the largest (smallest) representable value in floating-point, while still the corresponding c value is representable. In your case you can use it like this:
c=hypot(ab(:,1), ab(:,2));
Cleve Moler, one of the founders of MathWorks and original author of MATLAB, tells the story behind hypotin this article.
I'd recommend hypot as in Mohsen's answer.
Just for some variety, here's another approach, using complex numbers. This approach avoids overflow and underflow, just like hypot does:
abs(ab*[1; 1j])
Examples (taken from Cleve Moler's post):
>> ab = [1e154 1e154]; %// LARGE VALUES: possible overflow
>> sqrt(sum(ab.^2,2))
ans =
Inf %// overflow
>> hypot(ab(:,1), ab(:,2))
ans =
1.414213562373095e+154 %// correct result
>> abs(ab*[1; 1j])
ans =
1.414213562373095e+154 %// correct result
>> ab = [3e-200 4e-200]; %// SMALL VALUES: possible underflow
>> sqrt(sum(ab.^2,2))
ans =
0 %// underflow
>> hypot(ab(:,1), ab(:,2))
ans =
5.000000000000000e-200 %// correct result
>> abs(ab*[1; 1j])
ans =
5.000000000000000e-200 %// correct result

Summation of sines with limits and a variable?

I need help to add a function, from 1 to 10, using MATLAB. The function is ((1/n)*sin(n*pi*x)) where n goes from 1 to 10 and x stays as a variable. Ultimately I want to have a summation of ten sines (i.e K1*sin(pi*x)+K2*sin(2*pi*x)+k3*sin(3*pi*x)+...etc) where k is a constant. I would really appreciate any assistance. Thanks
Edit: Thanks to everyone who helped with my problem However I should have been more specific when asking my question. After getting the summation, I want to plot the sine series. I tried doing this but I kept getting an error saying that "conversion from sym to double is not possible" Now I tried doing a for loop to get my graph. My code is as follows:
n = 0:10;
while i <= n
for i = 1:length(n);
T = (1/n(i))*sin(n(i)*pi*x);
end
i = 1+i;
max = sum(T);
end
plot(x,max,'black')
However this doesn't work. I don't think that this is the proper way to get the sum of a double. I would really appreciate it if someone could help me again. Thanks again
Learn to exploit MATLAB's vector nature.
For one-off shots:
>> f = #(n,x) sin((1:n)*pi*x) * (1./(1:n).');
>> f(200, 0.5)
ans =
7.828982258896381e-001
To be able to evaluate f(n,x) with vector/matrix input x:
>> f = #(n,x) reshape( sin( bsxfun(#times, (1:n)*pi, x(:)) ) * (1./(1:n).'), size(x) );
>> f(15,rand(2))
ans =
5.077194963950054e-001 2.660834723822258e-001
1.416130930552744e+000 1.012255979042172e-001
Replace (1./(1:n).') by [K1 K2 K3 ...].' when you want to use other constants than 1/n.
From my understanding you are trying to sum the multivariable expression. In your case, you have two variables n and x. You want to sum the expression from n = 1 to 10 keeping x as a variable. You can do this in MATLAB by using symsum function, whose syntax is
symsum(expr,var,a,b)
Where expression expr defines the terms of a series, with respect to the symbolic variable var. The value of the variable var changes from a to b. If you do not specify the variable, symsum uses the default variable determined by symvar. If expr is a constant, then the default variable is x.
So in your case
expr = (1/n*sin(n*pi*x)
var = n
a = 1
b = 10
The simple code would be
>>syms n x
>>F = symsum ((1/sym('n'))*sin(sym('n')*pi*x), n, 1, 10)
Answer to Edit: MATLAB cannot convert the sys variable to double. You can instead substitute the value of sym variable with variable from MATLAB workspace. For example you can plot the above function for the range 0 to 10 by using following command.
>> x = 0:0.1:10;
>> plot(x, subs(F))

Find entrance of matrix for each adjacent pair of numbers in vector and multiply

I have a (transition) function defined by a matrix say P=[0.75,0.25;0.25,0.75] and I have a vector say X=[1,2,1] then i would like to find P(1,2)*P(2,1). How is the easiest way to generalise this? I tried creating a function handle for P(i,j) and then X_temp=[X(1:end-1);X(2:end)], using the function of each column and finally using the product function, but it seems a lot more comprehensive than it has to be.
The X i want to use is 1000 dimensional and P is 3x3 and I would have to repeat it a lot of times so speed I think will matter.
You can use sub2ind to get your relevant P values:
Ps = P(sub2ind(size(P), X(1:end-1), X(2:end)))
Now just multiply them all together:
prod(Ps)
EDIT:
For function handles you had the right idea, just make sure that you function itself handles vectors. For example lets say your function f(i,j) = i + j, I'm going to assume it's actually f(x) = x(1) + x(2) but I want it to handle many xs at once sof(x) = x(:,1) + x(:,2):
f = #(x)(x(:,1) + x(:,2))
f([X(1:end-1)', X(2:end)'])
OR
f = #(ii, jj)(ii + jj)
f(X(1:end-1)', X(2:end)') %//You don't actually need the transposes here anymore
just note that you need to use element wise operators such as .*, ./ and .^ etc instead of *, /,^...

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]