I'm trying to execute a custom function within MatLab, such that x which is a vector is actually the exponent of a constant e. I've tried placing the dot in numerous places, but it keeps throwing an error which is telling me to use the . before the ^, which is not what I want to do on this occasion. Y needs to return a vector and not a constant.
x = [0:0.1:1];
function y = hyperT(x)
e = exp(1);
y = ((e^x*2)-1)/((e^x*2)+1);
end
I've taken the . out for the purpose of this thread.
To get a vector, you can use (MATLAB power operator):
y = ((e.^x*2) - 1) ./ (e.^(x*2) + 1);
The . operator basically means "element-wise". For example, if you are multiplying two vectors, x = [x1, x2, x3] and y = [y1, y2, y3], then using the .* operator multiplies each element by the corresponding element in the other vector, while using the * operator without the . performs an inner product (matrix multiplication):
x.*y = [x1y1, x2y2, x3y3]
x*y = error (inner matrix dimensions must agree)
x'*y = [x1y1, x2y1, x3y1;
x2y1, x2y2, x3y2;
x1y3, x2y3, x3y3]
x*y' = x1y1 + x2y2 + x3y3
Note that the ' in the above transposes the vector.
Some operators automatically broadcast because their use is un-ambiguous. Thus you do not need the . with the + and - operators. Oddly enough, the division operator does not auto-broadcast, so you need to use ./ there (MATLAB rdivide). I am not sure what it is doing when you omit the ., but it seems to be well defined and consistent at least.
In general, you can perform any operation (even one that you define) element-wise between two vectors, or between a constant and a vector, by using bsxfun (MATLAB bsxfun). For example, to perform the power operation that you are asking about, you could do:
bsxfun(#power, e, x)
or
bsxfun(#power, e, x*2)
This is actually a super-efficient way to do a lot of neat things, but in your case the functionality is already built in with .^.
Edit: Added some links
you may use:
expm(x) which is matrix exponential.
Related
i am solving a mathematical problem and i can't continue do to the error.
I tried all constant with sin^2(x) yet its the same.
clear
clc
t = 1:0.5:10;
theta = linspace(0,pi,19);
x = 2*sin(theta)
y = sin^2*(theta)*(t/4)
Error using sin
Not enough input arguments.
Error in lab2t114 (line 9)
y = sin^2*(theta)*(t/4)
sin is a function so it should be called as sin(value) which in this case is sin(theta) It may help to consider writing everything in intermediate steps:
temp = sin(theta);
y = temp.^2 ...
Once this is done you can always insert lines from previous calculations into the next line, inserting parentheses to ensure order of operations doesn't mess things up. Note in this case you don't really need the parentheses.
y = (sin(theta)).^2;
Finally, Matlab has matrix wise and element wise operations. The element wise operations start with a period '.' In Matlab you can look at, for example, help .* (element wise multiplication) and help * matrix wise calculation. For a scalar, like 2 in your example, this distinction doesn't matter. However for calculating y you need element-wise operations since theta and t are vectors (and in this case you are not looking to do matrix multiplication - I think ...)
t = 1:0.5:10;
theta = linspace(0,pi,19);
x = 2*sin(theta) %times scalar so no .* needed
sin_theta = sin(theta);
sin_theta_squared = sin_theta.^2; %element wise squaring needed since sin_theta is a vector
t_4 = t/4; %divide by scalar, this doesn't need a period
y = sin_theta_squared.*t_4; %element wise multiplication since both variables are arrays
OR
y = sin(theta).^2.*(t/4);
Also note these intermediate variables are largely for learning purposes. It is best not to write actual code like this since, in this case, the last line is a lot cleaner.
EDIT: Brief note, if you fix the sin(theta) error but not the .^ or .* errors, you would get some error like "Error using * Inner matrix dimensions must agree." - this is generally an indication that you forgot to use the element-wise operators
I would love to know why this code is not working. if anyone has any information on what is causing matlab to find so many errors, it would be greatly appreciated.
m = 1;
c = 1.5;
fun =#(x, epsilon) 1 .* (1 - (1 - cos(x))/(2.*epsilon)).^c .* cos(m.*x);
a = #(ep) acos(1-(2*ep));
lm =#(e) 1/(2.*pi) .* integral(#(x)fun(x, e), -1.*a(e), a(e));
fprintf('ball bearing at 0.6 is %4.4f', lm(0.6));
the function that I am trying to replicate is πΌπ(π) =1/2πβ«[1 β (1 β cos(π₯))/2π]^π cos(ππ₯)dx
There should be no need for the dot modifier on the multiplication to my knowledge, however Matlab was complaining that this required element-wise operations even though there are no matrices involved.
According to the documentation of integral the function to be integrated must be vectorized:
For scalar-valued problems, the function y = fun(x) must accept a vector argument, x, and return a vector result, y. This generally means that fun must use array operators instead of matrix operators. For example, use .* (times) rather than * (mtimes).
I have data like this:
y = [0.001
0.0042222222
0.0074444444
0.0106666667
0.0138888889
0.0171111111
0.0203333333
0.0235555556
0.0267777778
0.03]
and
x = [3.52E-06
9.72E-05
0.0002822918
0.0004929136
0.0006759156
0.0008199029
0.0009092797
0.0009458332
0.0009749509
0.0009892005]
and I want y to be a function of x with y = a(0.01 β b*n^βcx).
What is the best and easiest computational approach to find the best combination of the coefficients a, b and c that fit to the data?
Can I use Octave?
Your function
y = a(0.01 β b*nβcx)
is in quite a specific form with 4 unknowns. In order to estimate your parameters from your list of observations I would recommend that you simplify it
y = Ξ²1 + Ξ²2Ξ²3x
This becomes our objective function and we can use ordinary least squares to solve for a good set of betas.
In default Matlab you could use fminsearch to find these Ξ² parameters (lets call it our parameter vector, Ξ²), and then you can use simple algebra to get back to your a, b, c and n (assuming you know either b or n upfront). In Octave I'm sure you can find an equivalent function, I would start by looking in here: http://octave.sourceforge.net/optim/index.html.
We're going to call fminsearch, but we need to somehow pass in your observations (i.e. x and y) and we will do that using anonymous functions, so like example 2 from the docs:
beta = fminsearch(#(x,y) objfun(x,y,beta), beta0) %// beta0 are your initial guesses for beta, e.g. [0,0,0] or [1,1,1]. You need to pick these to be somewhat close to the correct values.
And we define our objective function like this:
function sse = objfun(x, y, beta)
f = beta(1) + beta(2).^(beta(3).*x);
err = sum((y-f).^2); %// this is the sum of square errors, often called SSE and it is what we are trying to minimise!
end
So putting it all together:
y= [0.001; 0.0042222222; 0.0074444444; 0.0106666667; 0.0138888889; 0.0171111111; 0.0203333333; 0.0235555556; 0.0267777778; 0.03];
x= [3.52E-06; 9.72E-05; 0.0002822918; 0.0004929136; 0.0006759156; 0.0008199029; 0.0009092797; 0.0009458332; 0.0009749509; 0.0009892005];
beta0 = [0,0,0];
beta = fminsearch(#(x,y) objfun(x,y,beta), beta0)
Now it's your job to solve for a, b and c in terms of beta(1), beta(2) and beta(3) which you can do on paper.
So I'm just trying to plot 4 different subplots with variations of the increments. So first would be dx=5, then dx=1, dx=0.1 and dx=0.01 from 0<=x<=20.
I tried to this:
%for dx = 5
x = 0:5:20;
fx = 2*pi*x *sin(x^2)
plot(x,fx)
however I get the error inner matrix elements must agree. Then I tried to do this,
x = 0:5:20
fx = (2*pi).*x.*sin(x.^2)
plot(x,fx)
I get a figure, but I'm not entirely sure if this would be the same as what I am trying to do initially. Is this correct?
The initial error arose since two vectors with the same shape cannot be squared (x^2) nor multiplied (x * sin(x^2)). The addition of the . before the * and ^ operators is correct here since that will perform the operation on the individual elements of the vectors. So yes, this is correct.
Also, bit of a more advanced feature, you can use an anonymous function to aid in the expressions:
fx = #(x) 2*pi.*x.*sin(x.^2); % function of x
x = 0:5:20;
plot(x,fx(x));
hold('on');
x = 0:1:20;
plot(x,fx(x));
hold('off');
The problem in the link:
can be integrated analytically and the answer is 4, however I'm interested in integrating it numerically using Matlab, because it's similar in form to a problem that I can't integrate analytically. The difficulty in the numerical integration arises because the function in the two inner integrals is a function of x,y and z and z can't be factored out.
by no means, this is elegant. hope someone can make better use of matlab functions than me. i have tried the brute force way just to practice numerical integration. i have tried to avoid the pole in the inner integral at z=0 by exploiting the fact that it is also being multiplied by z. i get 3.9993. someone must get better solution by using something better than trapezoidal rule
function []=sofn
clear all
global x y z xx yy zz dx dy
dx=0.05;
x=0:dx:1;
dy=0.002;
dz=0.002;
y=0:dy:1;
z=0:dz:2;
xx=length(x);
yy=length(y);
zz=length(z);
s1=0;
for i=1:zz-1
s1=s1+0.5*dz*(z(i+1)*exp(inte1(z(i+1)))+z(i)*exp(inte1(z(i))));
end
s1
end
function s2=inte1(localz)
global y yy dy
if localz==0
s2=0;
else
s2=0;
for j=1:yy-1
s2=s2+0.5*dy*(inte2(y(j),localz)+inte2(y(j+1),localz));
end
end
end
function s3=inte2(localy,localz)
global x xx dx
s3=0;
for k=1:xx-1
s3=s3+0.5*dx*(2/(localy+localz));
end
end
Well, this is strange, because on the poster's similar previous question I claimed this can't be done, and now after having looked at Guddu's answer I realize its not that complicated. What I wrote before, that a numerical integration results in a number but not a function, is true β but beside the point: One can just define a function that evaluates the integral for every given parameter, and this way effectively one does have a function as a result of a numerical integration.
Anyways, here it goes:
function q = outer
f = #(z) (z .* exp(inner(z)));
q = quad(f, eps, 2);
end
function qs = inner(zs)
% compute \int_0^1 1 / (y + z) dy for given z
qs = nan(size(zs));
for i = 1 : numel(zs)
z = zs(i);
f = #(y) (1 ./ (y + z));
qs(i) = quad(f, 0 , 1);
end
end
I applied the simplification suggested by myself in a comment, eliminating x. The function inner calculates the value of the inner integral over y as a function of z. Then the function outer computes the outer integral over z. I avoid the pole at z = 0 by letting the integration run from eps instead of 0. The result is
4.00000013663955
inner has to be implemented using a for loop because a function given to quad needs to be able to return its value simultaneously for several argument values.