This is the equation that I want to plot in MATLAB -
I want to sweep the variable Vbi from -5 to +5 and then plot the variable T for each individual value of Vbi (essentially T vs. Vbi) for Nd = Na =1015, 1016 and 1017.
I know Vbi can be swept by creating a vector:
Vbi = -5 : 0.001 : 5;
But I am not sure how to go about solving this problem, as I have never faced something like
this before. Can someone please advice on how to code this?
Simplest is to use a loop through all values you want, and use fzero to find all values for the non-linear implicit function:
% Values for Na/Nd you want
Na = [1e15 1e16 1e17];
Nd = Na;
% Vbi values you want to sweep
VbiValues = -5 : 0.001 : 5;
% Initialize outputs
Tout = zeros(numel(VbiValues), numel(Na));
% Solve equation for each value of Vbi
for ii = 1:numel(VbiValues)
for jj = 1:numel(Na)
% Re-define equation for new value of Vbi, Na, Nd
eq = #(T) -T + 11603.24*VbiValues(ii) ./ log(Na(jj)*Nd(jj)/2.798e39 * 300./T .* exp(13452./T));
% Solve it
Tout(ii,jj) = fzero(eq, 10);
end
end
% plot results
plot(...
VbiValues, Tout(:,1), 'r', ...
VbiValues, Tout(:,2), 'g', ...
VbiValues, Tout(:,3), 'b')
L = legend(...
'$N_A = N_D = 10^{15}$',...
'$N_A = N_D = 10^{16}$',...
'$N_A = N_D = 10^{17}$');
set(L, 'Interpreter', 'LaTeX');
Alternatively, if you have the optimization toolbox, you can use fsolve:
function topLevelFunction
% Values for Na/Nd you want
Na = [1e15 1e16 1e17];
Nd = Na;
% Vbi values you want to sweep
VbiValues = -5 : 0.01 : 5;
% Use fsolve() to solve the system in one go
Tout = fsolve(#(T)F(T, VbiValues, Nd), ones(numel(Nd),numel(VbiValues)));
% plot results
plot(...
VbiValues, Tout(1,:), 'r', ...
VbiValues, Tout(2,:), 'g', ...
VbiValues, Tout(3,:), 'b')
L = legend(...
'$N_A = N_D = 10^{15}$',...
'$N_A = N_D = 10^{16}$',...
'$N_A = N_D = 10^{17}$');
set(L, 'Interpreter', 'LaTeX');
end
function Fvals = F(Ttrials, Vbis, Nad)
% Output function values for
% - all Vbi (each column is a different Vbi)
% - all Na/Nd (each row is a different Na/Nd)
Fvals = -Ttrials + bsxfun(#rdivide, ...
11603.24*Vbis(:).', ...
log( bsxfun(#times, Nad(:).^2/2.798e39, 300./Ttrials .* exp(13452./Ttrials)) ));
end
Note that one of the two solutions (or both :) still contains an error, as the two plots are not the same, but I'm sure this will help you get started.
Actually it's simple to rearrange the formula to V. Why don't you reformulate and sweep over T?
That way you might also see if there are T for which there is no solution (log of negative vaules or so).
btw if these quantities are physical T (temperature) and V (volume) you might consider not to go over negative values...
Update
just did a bit of symbolic maths:
syms T V a b c reals
fun = a*V/(log(b/T*exp(c/T)))-T;
r =solve(fun==0,V);
and then on notepad:
V = (T*log((b*exp(c/T))/T))/a
V = ( T* [log(b) + log(exp(c/T)) -log(T)] )/a
V = ( T* [log(b) + c/T -log(T)] )/a
V = c/a - T/a*log(T/b)
at least the relation is monotonic. So the solution will be unique.
Isn't it a recursive function ? something like this ?
There is still a little difference between your first formula and the typed version. have (300/T) term an exponent ?
Related
I am trying to approximate and plot the solution to u"(x) = exp(x) in the interval 0-3, with boundary conditions x(0)=1,x(3)=3. I am able to plot the approximate solution vs the exact, but the plot looks a bit off:
% Interval
a=0;
b=3;
n=10;
% Boundary vals
alpha=1;
beta=3;
%grid size
h=(b-a)/(n+1);
%Matrix generation
m = -2;
u = 1;
l = 1;
% Obtained from (y(i-1) -2y(i) + y(i+1)) = h^2 exp(x(i)
M = (1/h^2).*(diag(m*ones(1,n)) + diag(u*ones(1,n-1),1) + diag(l*ones(1,n-1),-1));
B=[];
xjj=[];
for j=1:n
xjj=[xjj,j*h];
if j==1
B=[B,f(j*h)-(alpha/h^2)];
continue
end
if j==n
B=[B,f(j*h)-(beta/h^2)];
continue
else
B=[B,f(j*h)];
end
end
X=M\B';
x=linspace(0,3,101);
plot(xjj',X,'r*')
hold on
plot(x,exp(x),'b-')
I appreciate all the advice and explanation. This is the scheme I am following: http://web.mit.edu/10.001/Web/Course_Notes/Differential_Equations_Notes/node9.html
You could shorten the big loop to simply
x=linspace(a,b,n+2);
B = f(x(2:end-1));
B(1)-=alpha/h^2;
B(n)-=beta/h^2;
The exact solution is u(x)=C*x+D+exp(x), the boundary conditions give D=0 and 3*C+exp(3)=3 <=> C=1-exp(3)/3.
Plotting this exact solution against the numerical solution gives a quite good fit for this large step size:
f=#(x)exp(x)
a=0; b=3;
n=10;
% Boundary vals
alpha=1; beta=3;
%grid
x=linspace(a,b,n+2);
h=x(2)-x(1);
% M*u=B obtained from (u(i-1) -2u(i) + u(i+1)) = h^2 exp(x(i))
M = (1/h^2).*(diag(-2*ones(1,n)) + diag(1*ones(1,n-1),1) + diag(1*ones(1,n-1),-1));
B = f(x(2:end-1));
B(1)-=alpha/h^2; B(n)-=beta/h^2;
U=M\B';
U = [ alpha; U; beta ];
clf;
plot(x',U,'r*')
hold on
x=linspace(0,3,101);
C = 1-exp(3)/3
plot(x,exp(x)+C*x,'b-')
My friends and I have been struggling to generate a 2-D plot in MATLAB with
$\eta_1$ and $\eta_2$ both varying in $0:0.01:1$ and the z-axis given by color.
We have a system of 8 differential equations, with HIVinf representing the total new HIV infections in a population over 1 year (HIVinf is obtained by integrating a function of $\eta_1, \eta_2$).
We are looping through $\eta_1$ and $\eta_2$ (two 'for' loops) with the ode45 solver within the 'for' loops.
Based on our prior numerical results, we should be getting much color variation in the 2D-plot. There should be patterns of darkness (high concentration of HIVinfections) along the edges of the plot, and lightness along the diagonals (low concentrations).
However, the following snippet does not produce what we want (I have attached the figure below).
[X,Y] = meshgrid(eta_11,eta_22);
figure;
pcolor(X,Y,AA);
shading interp;
I have attached the code below, as concisely as possible. The function ydot works fine (it is required to run ode45).
We would greatly appreciate if you could help us fix the snippet.
function All()
global Lambda mu mu_A mu_T beta tau eta_1 eta_2 lambda_T rho_1 rho_2 gamma
alpha = 20;
TIME = 365;
eta_11 = zeros(1,alpha);
eta_22 = zeros(1,alpha);
AA = zeros(1,alpha);
BB = zeros(1,alpha);
CC = zeros(1,alpha);
for n = 1:1:alpha
for m = 1:1:alpha
Lambda = 531062;
mu = 1/25550;
mu_A = 1/1460;
mu_T = 1/1825;
beta = 187/365000;
tau = 4/365;
lambda_T = 1/10;
rho_1 = 1/180;
rho_2 = 1/90;
gamma = 1/1000;
eta_1 = (n-1)./(alpha-1);
eta_11(m) = (m-1)./(alpha-1);
eta_2 = (m-1)./(alpha-1);
eta_22(m) = (m-1)./(alpha-1);
y0 = [191564208, 131533276, 2405629, 1805024, 1000000, 1000000, 500000, 500000];
[t,y] = ode45('SimplifiedEqns',[0:1:TIME],y0);
N = y(:,1)+y(:,2)+y(:,3)+y(:,4)+y(:,5)+y(;,6)+y(:,7)+y(:,8);
HIVinf1=[0:1:TIME];
HIVinf2=[beta.*(S+T).*(C1+C2)./N];
HIVinf=trapz(HIVinf1,HIVinf2);
AA(n,m) = HIVinf;
end
end
[X,Y] = meshgrid(eta_11,eta_22);
figure;
pcolor(X,Y,AA);
shading interp;
function ydot = SimplifiedEqns(t,y)
global Lambda mu mu_A mu_T beta tau eta_1 eta_2 lambda_T rho_1 rho_2 gamma
S = y(1);
T = y(2);
H = y(3);
C = y(4);
C1 = y(5);
C2 = y(6);
CM1 = y(7);
CM2 = y(8);
N = S + T + H + C + C1 + C2 + CM1 + CM2;
ydot = zeros(8,1);
ydot(1)=Lambda-mu.*S-beta.*(H+C+C1+C2).*(S./N)-tau.*(T+C).*(S./N);
ydot(2)=tau.*(T+C).*(S./N)-beta.*(H+C+C1+C2).*(T./N)-(mu+mu_T).*T;
ydot(3)=beta.*(H+C+C1+C2).*(S./N)-tau.*(T+C).*(H./N)-(mu+mu_A).*H;
ydot(4)=beta.*(H+C+C1+C2).*(T./N)+tau.*(T+C).*(H./N)- (mu+mu_A+mu_T+lambda_T).*C;
ydot(5)=lambda_T.*C-(mu+mu_A+rho_1+eta_1).*C1;
ydot(6)=rho_1.*C1-(mu+mu_A+rho_2+eta_2).*C2;
ydot(7)=eta_1.*C1-(mu+rho_1+gamma).*CM1;
ydot(8)=eta_2.*C2-(mu+rho_2+gamma.*(rho_1)./(rho_1+rho_2)).*CM2+(rho_1).*CM1;
end
end
Ok, I don't really know much about how the plot should look like, but your eta_11 and eta_22 are variables which are indexed only on the inner loop. That means that when n=1, m=1,2,3,...,alpha your eta_11/eta_22 will be a vector whose elements 1,2,3,...,alpha will be overwritten for every n. Since your meshgrid is outside of the loop, that could be a problem. Usually if you are plotting functions of two variables and you have said variables in 2 nested loops you just ignore the meshgrid. Like this
Option 1:
x=[0:0.01:1];
[x1,x2]=meshgrid(x,x);
y=x1+cos(x2);
contour(x,x,y,30);
Option 2
x=[0:0.01:1];
for i=1:101 %length(x)
for j=1:101
y(i,j)=x1(i)+cos(x2(j)); % It is important to index y with both
% loop variables
end
end
contour(x,x,y,30)
I'm basicaly trying to find the product of an expression that goes like this:
(x-(N-1)/2).....(x+(N-1)/2) for even value of N
x is a value that I will set at the beginning that changes too but that is a different problem...
let's say for the sake of argument that for now x is a constant (ex x=1)
example for N=6
(x-5/2)(x-3/2)(x-1/2)(x+1/2)(x+3/2)*(x+5/2)
the idea was to create a row vector every element of which is each individual term (P(1)=x-5/2) (P(2)=x-3/2)...etc and then calculate its product
N=6;
x=1;
P=ones(1,N);
for k=(-N-1)/2:(N-1)/2
for n=1:N
P(n)=(x-k);
end
end
y=prod(P);
instead this creates a vector that takes only the first value of the epxression and then
repeats the same value at each cell.
there is obviously a fundamental problem with my loop but I just can't see it.
So if anyone can help with that OR suggest a better way to calculate the product I would be grateful.
Use vectorized commands
Why use a loop when you can use vectorized commands like prod?
y = prod(2 * x + [-N + 1 : 2 : N - 1]) / 2;
For convenience, you may want to define an anonymous function for it:
f = #(N,x) reshape(prod(bsxfun(#plus, 2 * x(:), -N + 1 : 2 : N - 1) / 2, 2), size(x));
Note that the function is compatible with a (row or column) vector input x.
Tests in MATLAB's Command Window
>> f(6, [2,2]')
ans =
-14.7656
4.9219
-3.5156
4.9219
-14.7656
>> f(6, [2,2])
ans =
-14.7656 4.9219 -3.5156 4.9219 -14.7656
Benchmark
Here is a comparison of rayreng's approach versus mine. The former emerges as the clear winner... :'( ...at least as N increases.
Varying N, fixed x
Fixed N (= 10), vector x of varying length
Fixed N (= 100), vector x of varying length
Benchmark code
function benchmark
% varying N, fixed x
clear all
n = logspace(2,4,20)';
x = rand(1000,1);
tr = zeros(size(n));
tj = tr;
for k = 1 : numel(n)
% rayreng's approach (poly/polyval)
fr = #() rayreng(n(k), x);
tr(k) = timeit(fr);
% Jubobs's approach (prod/reshape/bsxfun)
fj = #() jubobs(n(k), x);
tj(k) = timeit(fj);
end
figure
hold on
plot(n, tr, 'bo')
plot(n, tj, 'ro')
hold off
xlabel('N')
ylabel('time (s)')
legend('rayreng', 'jubobs')
end
function y = jubobs(N,x)
y = reshape(prod(bsxfun(#plus,...
2 * x(:),...
-N + 1 : 2 : N - 1) / 2,...
2),...
size(x));
end
function y = rayreng(N, x)
p = poly(linspace(-(N-1)/2, (N-1)/2, N));
y = polyval(p, x);
end
function benchmark2
% fixed N, varying x
clear all
n = 100;
nx = round(logspace(2,4,20));
tr = zeros(size(n));
tj = tr;
for k = 1 : numel(nx)
disp(k)
x = rand(nx(k), 1);
% rayreng's approach (poly/polyval)
fr = #() rayreng(n, x);
tr(k) = timeit(fr);
% Jubobs's approach (prod/reshape/bsxfun)
fj = #() jubobs(n, x);
tj(k) = timeit(fj);
end
figure
hold on
plot(nx, tr, 'bo')
plot(nx, tj, 'ro')
hold off
xlabel('number of elements in vector x')
ylabel('time (s)')
legend('rayreng', 'jubobs')
title(['n = ' num2str(n)])
end
function y = jubobs(N,x)
y = reshape(prod(bsxfun(#plus,...
2 * x(:),...
-N + 1 : 2 : N - 1) / 2,...
2),...
size(x));
end
function y = rayreng(N, x)
p = poly(linspace(-(N-1)/2, (N-1)/2, N));
y = polyval(p, x);
end
An alternative
Alternatively, because the terms in your product form an arithmetic progression (each term is greater than the previous one by 1/2), you can use the formula for the product of an arithmetic progression.
I agree with #Jubobs in that you should avoid using for loops for this kind of computation. There are cases where for loops perform fast, but for something as simple as this, avoid using loops if possible.
An alternative approach to what Jubobs has suggested is that you can consider that polynomial equation to be in factored form where each factor denotes a root located at that particular location. You can use poly to convert these factors into a polynomial equation, then use polyval to evaluate the expression at the point you want. First, generate your roots by linspace where the points vary from -(N-1)/2 to (N-1)/2 and there are N of them, then plug this into poly. Finally, for any values of x, put this into polyval with the output of poly. The advantage of this approach is that you can evaluate multiple points of x in a single sweep.
Going with what you have, you would simply do this:
p = poly(linspace(-(N-1)/2, (N-1)/2, N));
out = polyval(p, x);
With your example, supposing that N = 6, this would be the output of the first line:
p =
1.0000 0 -8.7500 0 16.1875 0 -3.5156
As such, this is saying that when we expand out (x-5/2)(x-3/2)(x-1/2)(x+1/2)(x+3/2)(x+5/2), we get:
x^6 - 8.75x^4 + 16.1875x^2 - 3.5156
If we take a look at the roots of this equation, this is what we get:
r = roots(p)
r =
-2.5000
2.5000
-1.5000
1.5000
-0.5000
0.5000
As you can see, each term corresponds to one factor in your polynomial equation, so we do have the right mindset here. Now, all you have to do is use p with your values of x into polyval to obtain your results. For example, if I wanted to evaluate that polynomial from -2 <= x <= 2 where x is an integer, this is the result I get:
polyval(p, -2:2)
ans =
-14.7656 4.9219 -3.5156 4.9219 -14.7656
Therefore, when x = -2, the result is -14.7656 and so on.
Though I would recommend the solution by #Jubobs, it is also good to check what the issue is with your loop.
The first indication that something is wrong, is that you have a nested loop over 2 variables, and only index with one of them to store the result. Probably you just need a single loop.
Here is a loop that you may be interested in that should do roughly what you need:
N=6;
x=1;
k=(-N-1)/2:(N-1)/2
P = ones(size(k));
for n=1:numel(k)
P(n)=(x-k(n));
end
y=prod(P);
I tried to keep the code close to the original, so hopefully it is easy to understand.
I am building a code to solve a diff. equation:
function dy = KIN1PARM(t,y,k)
%
% version : first order reaction
% A --> B
% dA/dt = -k*A
% integrated form A = A0*exp(-k*t)
%
dy = -k.*y;
end
I want this equation to be solved numerically and the results (y as a function of t, and k) to be used for minimization with respect to the experimental values to get the optimal value of parameter k.
function SSE = SSE_minimization_1parm(tspan_inp,val_exp,k_inp,y0_inp)
f = #(Tt,Ty) KIN1PARM(Tt,Ty,k_inp); %function to call ode45
size_limit = length(y0_inp);
options = odeset('NonNegative',1:size_limit,'RelTol',1e-4,'AbsTol', 1e-4);
[ts,val_theo] = ode45(f, tspan_inp, y0_inp,options); %Cexp is the state variable predicted by the model
err = val_exp - val_theo;
SSE = sum(err.^2); %sum squared-error
The main code to plot the experimental and calculated data is:
% Analyzing first order kinetics
clear all; clc;
figure_title = 'Experimental Data';
label_abscissa = 'Time [s]';
label_ordinatus = 'Concentration [mol/L]';
%
abscissa = [ 0;
240;
480;
720;
960;
1140;
1380;
1620;
1800;
2040;
2220;
2460;
2700;
2940];
ordinatus = [ 0;
19.6;
36.7;
49.0;
57.1;
64.5;
71.4;
75.2;
78.7;
81.3;
83.3;
85.5;
87.0;
87.7];
%
title_string = [' Time [s]', ' | ', ' Complex [mol/L] ', ' '];
disp(title_string);
for i=1:length(abscissa)
report_raw_data{i} = sprintf('%1.3E\t',abscissa(i),ordinatus(i));
disp([report_raw_data{i}]);
end;
%---------------------/plotting dot data/-------------------------------------
%
f = figure('Position', [100 100 700 500]);
title(figure_title,'FontName','arial','FontWeight','bold', 'FontSize', 12);
xlabel(label_abscissa, 'FontSize', 12);
ylabel(label_ordinatus, 'FontSize', 12);
%
grid on; hold on;
%
marker_style = { 's'};
%
plot(abscissa,ordinatus, marker_style{1},...
'MarkerFaceColor', 'black',...
'MarkerEdgeColor', 'black',...
'MarkerSize',4);
%---------------------/Analyzing/----------------------------------------
%
options = optimset('Display','iter','TolFun',1e-4,'TolX',1e-4);
%
CPUtime0 = cputime;
Time_M = abscissa;
Concentration_M = ordinatus;
tspan = Time_M;
y0 = 0;
k0 = rand(1);
[k, fval, exitflag, output] = fminsearch(#(k) SSE_minimization_1parm(tspan,Concentration_M,k,y0),k0,options);
CPUtimex = cputime;
CPUtime_delay = CPUtimex - CPUtime0;
%
%---------------------/plotting calculated data/-------------------------------------
%
xupperlimit = Time_M(length(Time_M));
xval = ([0:1:xupperlimit])';
%
yvector = data4plot_1parm(xval,k,y0);
plot(xval,yvector, 'r');
hold on;
%---------------------/printing calculated data/-------------------------------------
%
disp('RESULTS:');
disp(['CPU time: ',sprintf('%0.5f\t',CPUtime_delay),' sec']);
disp(['k: ',sprintf('%1.3E\t',k')]);
disp(['fval: ',sprintf('%1.3E\t',fval)]);
disp(['exitflag: ',sprintf('%1.3E\t',exitflag)]);
disp(output);
disp(['Output: ',output.message]);
The corresponding function, which uses the optimized parameter k to yield the calculated y = f(t) data :
function val = data4plot_1parm(tspan_inp,k_inp,y0_inp)
f = #(Tt,Ty) KIN1PARM(Tt,Ty,k_inp);
size_limit = length(y0_inp);
options = odeset('NonNegative',1:size_limit,'RelTol',1e-4,'AbsTol',1e-4);
[ts,val_theo] = ode45(f, tspan_inp, y0_inp, options);
The code runs optimization cycles always giving different values of parameter k, which are different from the value calculated using ln(y) vs t (should be around 7.0e-4 for that series of exp. data).
Looking at the outcome of the ode solver (SSE_minimization_1parm => val_theo) I found that the ode function gives me a vector of zeroes.
Could someone help me , please, to figure out what's going with the ode solver ?
Thanks much in advance !
So here comes the best which I can get right now. For my way I tread ordinatus values as time and the abscissa values as measured quantity which you try to model. Also, you seem to have set alot of options for the solver, which I all omitted. First comes your proposed solution using ode45(), but with a non-zero y0 = 100, which I just "guessed" from looking at the data (in a semilogarithmic plot).
function main
abscissa = [0;
240;
480;
720;
960;
1140;
1380;
1620;
1800;
2040;
2220;
2460;
2700;
2940];
ordinatus = [ 0;
19.6;
36.7;
49.0;
57.1;
64.5;
71.4;
75.2;
78.7;
81.3;
83.3;
85.5;
87.0;
87.7];
tspan = [min(ordinatus), max(ordinatus)]; % // assuming ordinatus is time
y0 = 100; % // <---- Probably the most important parameter to guess
k0 = -0.1; % // <--- second most important parameter to guess (negative for growth)
k_opt = fminsearch(#minimize, k0) % // optimization only over k
% nested minimization function
function e = minimize(k)
sol = ode45(#KIN1PARM, tspan, y0, [], k);
y_hat = deval(sol, ordinatus); % // evaluate solution at given times
e = sum((y_hat' - abscissa).^2); % // compute squarederror
end
% // plot with optimal parameter
[T,Y] = ode45(#KIN1PARM, tspan, y0, [], k_opt);
figure
plot(ordinatus, abscissa,'ko', 'markersize',10,'markerfacecolor','black')
hold on
plot(T,Y, 'r--', 'linewidth', 2)
% // Another attempt with fminsearch and the integral form
t = ordinatus;
t_fit = linspace(min(ordinatus), max(ordinatus))
y = abscissa;
% create model function with parameters A0 = p(1) and k = p(2)
model = #(p, t) p(1)*exp(-p(2)*t);
e = #(p) sum((y - model(p, t)).^2); % minimize squared errors
p0 = [100, -0.1]; % an initial guess (positive A0 and probably negative k for exp. growth)
p_fit = fminsearch(e, p0); % Optimize
% Add to plot
plot(t_fit, model(p_fit, t_fit), 'b-', 'linewidth', 2)
legend('location', 'best', 'data', 'ode45 with fixed y0', ...
sprintf ('integral form: %5.1f*exp(-%.4f)', p_fit))
end
function dy = KIN1PARM(t,y,k)
%
% version : first order reaction
% A --> B
% dA/dt = -k*A
% integrated form A = A0*exp(-k*t)
%
dy = -k.*y;
end
The result can be seen below. Quit surprisingly to me, the initial guess of y0 = 100 fits quite well with the optimal A0 found. The result can be seen below:
Was wondering how I could achieve this in Matlab:
T(s) = 1/(s+1) -> T(jw) = 1/(jw+1)
Setting s = jw doesn't help.
For better understanding:
R(s) = some transfer function
L(s) = some transfer function
T(s) = R(s) * L(s)
value_at_jw = T(jw)
You basically want to evaluate your transfer function at a certain frequency.
The result would be a complex number.
You can't just substitute s with a frequency, you would need to create a polynomial or an anonymous function out from your denominator and numerator. Which is one way, an interesting one. Another very simple way is to use the outputs of the bode function:
Imagine a transfer function G and a frequency value jw you want to insert for 's':
G = tf([2 1 ], [1 1 1])
jw = 1i*2000 % or easier without the complex "i"
G =
2 s + 1
-----------
s^2 + s + 1
Now you want to know magnitude and phase for the frequency s = jw
[mag,phase] = bode( G, imag(jw) ) % or just w
The rest is math, you now have magnitude and phase=angle of your complex result. A complex number of form z = a + bi can be created as follows:
z = mag*( cos(phase)+1i*sin(phase) )
returns:
z = -4.3522e-04 - 9.0032e-04i
If you have Matlab's control systems toolbox installed ($$$), you can do a sort of symbolic computations by defining transfer functions, either by giving the polynomial coefficients with tf or as a system factored in poles and zeros using zpk:
>> R = tf([1], [1, 1])
Transfer function:
1
-----
s + 1
>> L = zpk([1,2],[3,4,5], 6)
Zero/pole/gain:
6 (s-1) (s-2)
-----------------
(s-3) (s-4) (s-5)
You can convert between these two formats, and they can be used for simple math:
>> R * L
Zero/pole/gain:
6 (s-1) (s-2)
-----------------------
(s+1) (s-3) (s-4) (s-5)
A complex frequency response, finally, can be obtained using freqresp:
>> f = logspace(-2, 2, 200);
>> frequency_response = squeeze(freqresp(T, f, 'Hz'));
>> subplot(211)
>> loglog(f, abs(frequency_response))
>> subplot(212)
>> semilogx(f, angle(frequency_response))
Here are two ways.
wmax = 20;
dw = 0.1;
w = -wmax:dw:wmax;
T = 1./(1 + j*w);
subplot(2,1,1)
hold on
grid on
p = plot(w, abs(T))
title('Magnitude')
subplot(2,1,2)
hold on
grid on
p = plot(w, angle(T))
title('Phase')
// or
H = freqs(1, [1 1], w);
figure
subplot(2,1,1)
hold on
grid on
p = plot(w, abs(H))
title('Magnitude')
subplot(2,1,2)
hold on
grid on
p = plot(w, angle(H))
title('Phase')
The result is, of course, identical
Hope that helps.