Failing to use interpolation instead of integration in chuncks with ODE45 - matlab
I have written this code to integrate voltage V and gating conductances m, n and h in 30ms with injection of current from ms 10 to 20. So basically Current I is a vector that has 0 values until 10ms, 1 values until 20ms and 0 values until 30ms. The code works well and it shows the behaviour I want to see.
I'm trying to implement the same code with interpolation instead of integration in chunks. However, I'm failing to do so.
This is the integration with interpolation, which is giving the incorrect result:
myode = #(T,y0) [((1/Cm)*interp1(t, I, T, 'linear','extrap')-(INa+IK+Il)); % Normal case
alpham(y0(1,1))*(1-y0(2,1))-betam(y0(1,1))*y0(2,1);
alphan(y0(1,1))*(1-y0(3,1))-betan(y0(1,1))*y0(3,1);
alphah(y0(1,1))*(1-y0(4,1))-betah(y0(1,1))*y0(4,1)];
[time,V] = ode45(myode, t, y0, I);
This is the correct one, in chunks:
[time,V] = ode45(#ODEMAT, [t(chunk), t(chunk+1)], y);
%%% Calls ODEMAT, in which theres' the integration (extensive code posted below):
dydt = [((1/Cm)*(I(chunk)-(INa+IK+Il))); % Normal case
alpham(V)*(1-m)-betam(V)*m;
alphan(V)*(1-n)-betan(V)*n;
alphah(V)*(1-h)-betah(V)*h];
This is the code with the integration in chunks:
function Z2_chunks ()
%% Initial values
V=-60; % Initial Membrane voltage
m1=alpham(V)/(alpham(V)+betam(V)); % Initial m-value
n1=alphan(V)/(alphan(V)+betan(V)); % Initial n-value
h1=alphah(V)/(alphah(V)+betah(V)); % Initial h-value
y0=[V;m1;n1;h1];
t = [1:30];
I = [zeros(1,10),ones(1,10),zeros(1,10)];
% Plotting purposes (set I(idx) equal to last value of I)
idx = numel(t);
I(idx) = 0.1;
chunks = numel(t) - 1;
for chunk = 1:chunks
if chunk == 1
V=-60; % Initial Membrane voltage
m=alpham(V)/(alpham(V)+betam(V)); % Initial m-value
n=alphan(V)/(alphan(V)+betan(V)); % Initial n-value
h=alphah(V)/(alphah(V)+betah(V)); % Initial h-value
y=[V;m;n;h];
else
y = V(end, :); % Final position is initial value for next interval
end
[time,V] = ode45(#ODEMAT, [t(chunk), t(chunk+1)], y);
if chunk == 1
def_time = time;
def_v = V;
else
def_time = [def_time; time];
def_v = [def_v; V];
end
end
OD = def_v(:,1);
ODm = def_v(:,2);
ODn = def_v(:,3);
ODh = def_v(:,4);
time = def_time;
%% Plots
%% Voltage
figure
subplot(3,1,1)
plot(time,OD);
legend('ODE45 solver');
xlabel('Time (ms)');
ylabel('Voltage (mV)');
title('Voltage Change for Hodgkin-Huxley Model');
%% Current
subplot(3,1,2)
stairs(t,I)
ylim([0 5*max(I)])
legend('Current injected')
xlabel('Time (ms)')
ylabel('Ampere')
title('Current')
%% Gating variables
subplot(3,1,3)
plot(time,[ODm,ODn,ODh]);
legend('ODm','ODn','ODh');
xlabel('Time (ms)')
ylabel('Value')
title('Gating variables')
function [dydt] = ODEMAT(t,y)
%% Constants
ENa=55; % mv Na reversal potential
EK=-72; % mv K reversal potential
El=-49; % mv Leakage reversal potential
%% Values of conductances
gbarl=0.003; % mS/cm^2 Leakage conductance
gbarNa=1.2; % mS/cm^2 Na conductance
gbarK=0.36; % mS/cm^2 K conductancence
Cm = 0.01; % Capacitance
% Values set to equal input values
V = y(1);
m = y(2);
n = y(3);
h = y(4);
gNa = gbarNa*m^3*h;
gK = gbarK*n^4;
gL = gbarl;
INa=gNa*(V-ENa);
IK=gK*(V-EK);
Il=gL*(V-El);
dydt = [((1/Cm)*(I(chunk)-(INa+IK+Il))); % Normal case
alpham(V)*(1-m)-betam(V)*m;
alphan(V)*(1-n)-betan(V)*n;
alphah(V)*(1-h)-betah(V)*h];
end
end
This is the code with the integration with interpolation. As you can see, the plots are really different:
function Z1_interpol ()
%% Initial values
V=-60; % Initial Membrane voltage
m1=alpham(V)/(alpham(V)+betam(V)); % Initial m-value
n1=alphan(V)/(alphan(V)+betan(V)); % Initial n-value
h1=alphah(V)/(alphah(V)+betah(V)); % Initial h-value
y0=[V;m1;n1;h1];
t = [1:30];
I = [zeros(1,10),ones(1,10),zeros(1,10)];
% Plotting purposes (set I(idx) equal to last value of I)
idx = numel(t);
I(idx) = 0.1;
V=-60; % Initial Membrane voltage
m=alpham(V)/(alpham(V)+betam(V)); % Initial m-value
n=alphan(V)/(alphan(V)+betan(V)); % Initial n-value
h=alphah(V)/(alphah(V)+betah(V)); % Initial h-value
y=[V;m;n;h];
%% Constants
ENa=55; % mv Na reversal potential
EK=-72; % mv K reversal potential
El=-49; % mv Leakage reversal potential
%% Values of conductances
gbarl=0.003; % mS/cm^2 Leakage conductance
gbarNa=1.2; % mS/cm^2 Na conductance
gbarK=0.36; % mS/cm^2 K conductancence
Cm = 0.01; % Capacitance
%% Initial values
V=-60; % Initial Membrane voltage
m=alpham(V)/(alpham(V)+betam(V)); % Initial m-value
n=alphan(V)/(alphan(V)+betan(V)); % Initial n-value
h=alphah(V)/(alphah(V)+betah(V)); % Initial h-value
y0=[V;m;n;h];
gNa = gbarNa*m^3*h;
gK = gbarK*n^4;
gL = gbarl;
INa=gNa*(V-ENa);
IK=gK*(V-EK);
Il=gL*(V-El);
myode = #(T,y0) [((1/Cm)*interp1(t, I, T, 'linear','extrap')-(INa+IK+Il)); % Normal case
alpham(y0(1,1))*(1-y0(2,1))-betam(y0(1,1))*y0(2,1);
alphan(y0(1,1))*(1-y0(3,1))-betan(y0(1,1))*y0(3,1);
alphah(y0(1,1))*(1-y0(4,1))-betah(y0(1,1))*y0(4,1)];
[time,V] = ode45(myode, t, y0, I);
OD=V(:,1);
ODm=V(:,2);
ODn=V(:,3);
ODh=V(:,4);
time = time;
%% Plots
%% Voltage
figure
subplot(3,1,1)
plot(time,OD);
legend('ODE45 solver');
xlabel('Time (ms)');
ylabel('Voltage (mV)');
title('Voltage Change for Hodgkin-Huxley Model');
%% Current
subplot(3,1,2)
stairs(t,I)
ylim([0 5*max(I)])
legend('Current injected')
xlabel('Time (ms)')
ylabel('Ampere')
title('Current')
%% Gating variables
subplot(3,1,3)
plot(time,[ODm,ODn,ODh]);
legend('ODm','ODn','ODh');
xlabel('Time (ms)')
ylabel('Value')
title('Gating variables')
end
Related
I would like to run the calculating of the following piece of code 30 times in MATLAB
I am trying to calculate the received optical power for an optical communication system for 30 times. When I run the code, I get a 41 x 41 double matrix of H0_LoS and power (P_r_LOS & P_rec_dBm) as shown below The case above is only for one iteration. I would like to get a matrix or a cell with results up to 30 times that of the implemented code. Any assistance, please? My try below close all; clear variables; clc; %% Simulation Parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Main Simulation Parameters %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %-------------------------% % NUMBER OF LIGHT SOURCES % %-------------------------% N_t = 1; % Number of light sources %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% AP Parameters %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %------------------------% % LIGHT SOURCES GEOMETRY % %------------------------% L = 20; W = 20; H = 3; % Length, width and height of the room (m) theta_half = 60; m = -log(2)./log(cosd(theta_half)); % Lambertian order of emission coord_t = [0 0 0]; % Positions of the light sources n_t_LED = [0, 0, -1]; n_t_LED = n_t_LED/norm(n_t_LED); % Normalized normal vector of each light source n_t = repmat(n_t_LED, N_t, 1); % Normalized normal vectors of the light sources %-------------------------------------% % LIGHT SOURCES ELECTRICAL PARAMETERS % %-------------------------------------% P_LED = 2.84; % Average electrical power consummed by each light source (W) % P_LED = 1; param_t = {coord_t, n_t, P_LED, m}; %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Rx Parameters %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %--------------------------% % PHOTODETECTOR PARAMETERS % %--------------------------% A_det = 1e-4; % Photoreceiver sensitive area (m²) FOV = 60*pi/180; % Fielf-of-view of the photoreceiver T_s = 1; % Gain of the optical filter (ignore if not used) index = 1.5; % Refractive index of the Rx concentrator/lens (ignore if not used) G_Con = (index^2)/sin(FOV); % Gain of an optical concentrator; ignore if no lens is used n_r = [0, 0, 1]; % Normal vector of the photoreceiver n_r = n_r/norm(n_r); % Normal vector of the photoreceiver (normalized) %---------------------------% % RECEIVER PLANE PARAMETERS % %---------------------------% step = 0.5; % Distance between each receiving point (m) X_r = -L/2:step:L/2; % Range of Rx points along x axis Y_r = -W/2:step:W/2; % Range of Rx points along y axis N_rx = length(X_r); N_ry = length(Y_r); % Number of reception points simulated along the x and y axis z_ref = 0.85; % Height of the receiver plane from the ground (m) z = z_ref-H; % z = -1.65; % Height of the Rx points ("-" because coordinates system origin at the center of the ceiling) if( abs(z) > H ) fprintf('ERROR: The receiver plane is out of the room.\n'); return end param_r = {A_det, n_r, FOV}; % Vector of the Rx parameters used for channel simulation %% LOS received optical power calculation H0_LOS = zeros(N_rx,N_ry,N_t); T = param_t{1}(1,:); P_t = param_t{3}; for iter = 1:30 for r_x = 1:N_rx for r_y = 1:N_ry for i_t = 1:N_t x = X_r(r_x); y = Y_r(r_y); R = [x,y,z]; v_tr = (R-T)./norm(R-T); d_tr = sqrt(dot(R-T,R-T)); phi = -5 + (5+5)*rand(1); psi = -5 + (5+5)*rand(1); H0_LOS(r_x,r_y,i_t) = (m+1)*A_det/(2*pi*d_tr^2)*cosd(phi)^m*cosd(psi); end end end end P_r_LOS = P_t.*H0_LOS.*T_s.*G_Con; P_rec_dBm = 10*log10(P_r_LOS*1000);
SeDuMi Matlab Code for Optimization problem
have this optimization Problem and need to implement this problem using SeDuMi Technique in MATLAB. Here, Q_i = h_i * h_i^(H). and h_i are randomly generated vector. I would like someone to help me with the matlab code for the implementation of this optimization problem in SeDuMi: Matlab code, which i have been working on: % % % % % % % % % % % % % % % % % % % % % % % % % % % % % clear all; clc N = 10; % Number of antennas # BS M = 5; % Number of single antenna User H = (randn(N,M) + 1j*randn(N,M)) *sqrt(0.5); Q = zeros(N,N,M); vecQs= []; for k = 1:M Q(:,:,k) =H(:,k)'*H(:,k); vecQs = [vecQs,vec(Q(k).')]; end A=[-eye(M),vecQs.']; b=ones(M,1); c=[zeros(M,1);vec(eye(N))]; K.l=M; K.s=N; K.scomplex=1; [x_opt,y_opt,info]=sedumi(A,b,c,K); Xopt=mat(x_opt(M+1:end));
How to plot very low negative values in Matlab
I want to plot the following - see below. The reason that I want to use semilogy - or something else, maybe you have suggestions? - is that the data goes so low that the scale is such that all the positive data appears to be zero. Of course semilogy doesn't work with negative data. But what can I do? The goal is that positive and negative data are somehow visible in the plot as different from zero. I saw this question (Positive & Negitive Log10 Scale Y axis in Matlab), but is there a simpler way? Another issue I have with the semilogy command is that the data are plotted as if they go from November to April, whereas they really go from January to June! %% Date vector Y = []; for year = 2008:2016 Y = vertcat(Y,[year;year]); end M = repmat([01;07],9,1); D = [01]; vector = datetime(Y,M,D); %% Data operatingValue=... 1.0e+05 *... [0.020080000000000, 0.000010000000000, 0.000430446606112, 0.000286376498540, 0.000013493575572, 0.000008797774209;... 0.020080000000000, 0.000020000000000, 0.000586846360023, 0.000445575962649, 0.000118642085670, 0.000105982759202;... 0.020090000000000, 0.000010000000000, 0.000304503221392, 0.000168068072591, -0.000004277640797, 0.000006977580173;... 0.020090000000000, 0.000020000000000, 0.000471819542315, 0.000318827321824, 0.000165018495621, 0.000188500216550;... 0.020100000000000, 0.000010000000000, 0.000366527395452, 0.000218539902929, 0.000032265798656, 0.000038839492621;... 0.020100000000000, 0.000020000000000, 0.000318807172600, 0.000170892065948, -0.000093830970932, -0.000096575559444;... 0.020110000000000, 0.000010000000000, 0.000341114962826, 0.000187311222835, -0.000118595282218, -0.000135188693035;... 0.020110000000000, 0.000020000000000, 0.000266317725166, 0.000128625220303, -0.000314547081599, -0.000392868178754;... 0.020120000000000, 0.000010000000000, 0.000104302824558, -0.000000079359646, -0.001817533087893, -0.002027417507676;... 0.020120000000000, 0.000020000000000, 0.000093484465168, -0.000019260661622, -0.002180826237198, -0.001955577709102;... 0.020130000000000, 0.000010000000000, 0.000052921606827, -0.000175185193313, -4.034665389612666, -4.573270848282296;... 0.020130000000000, 0.000020000000000, 0.000027218083520, -0.000167098897097, 0, 0;... 0.020140000000000, 0.000010000000000, 0.000044907412504, -0.000106127286095, -0.012248660549809, -0.010693498138601;... 0.020140000000000, 0.000020000000000, 0.000061663936450, -0.000070280400096, -0.015180683545658, -0.008942771925367;... 0.020150000000000, 0.000010000000000, 0.000029214681162, -0.000190870890021, 0, 0;... 0.020150000000000, 0.000020000000000, 0.000082672707169, -0.000031566292849, -0.003226048850797, -0.003527284081616;... 0.020160000000000, 0.000010000000000, 0.000084562787728, -0.000024916156477, -0.001438488940835, -0.000954872893879;... 0.020160000000000, 0.000020000000000, 0.000178181932848, 0.000054988621755, -0.000172520970578, -0.000139835312255] figure; semilogy( datenum(vector), operatingValue(:,3), '-+', datenum(vector), operatingValue(:,4), '-o',... datenum(vector), operatingValue(:,5), '-*', datenum(vector), operatingValue(:,6), '-x',... 'LineWidth',1.2 ), grid on; dateaxis('x', 12);
Save the function symlog in your directory. function symlog(varargin) % SYMLOG bi-symmetric logarithmic axes scaling % SYMLOG applies a modified logarithm scale to the specified or current % axes that handles negative values while maintaining continuity across % zero. The transformation is defined in an article from the journal % Measurement Science and Technology (Webber, 2012): % % y = sign(x)*(log10(1+abs(x)/(10^C))) % % where the scaling constant C determines the resolution of the data % around zero. The smallest order of magnitude shown on either side of % zero will be 10^ceil(C). % % SYMLOG(ax=gca, var='xyz', C=0) applies this scaling to the axes named % by letter in the specified axes using the default C of zero. Any of the % inputs can be ommitted in which case the default values will be used. % % SYMLOG uses the UserData attribute of the specified axes to record the % current transformation applied so that subsequent calls to symlog % operate on the original data rather than the newly transformed data. % % Example: % x = linspace(-50,50,1e4+1); % y1 = x; % y2 = sin(x); % % subplot(2,4,1) % plot(x,y1,x,y2) % % subplot(2,4,2) % plot(x,y1,x,y2) % set(gca,'XScale','log') % throws warning % % subplot(2,4,3) % plot(x,y1,x,y2) % set(gca,'YScale','log') % throws warning % % subplot(2,4,4) % plot(x,y1,x,y2) % set(gca,'XScale','log','YScale','log') % throws warning % % subplot(2,4,6) % plot(x,y1,x,y2) % symlog('x') % % s = subplot(2,4,7); % plot(x,y1,x,y2) % symlog(s,'y') % can but don't have to provide s. % % subplot(2,4,8) % plot(x,y1,x,y2) % symlog() % no harm in letting symlog operate in z axis, too. % % Created by: % Robert Perrotta % % Referencing: % Webber, J. Beau W. "A Bi-Symmetric Log Transformation for Wide-Range % Data." Measurement Science and Technology 24.2 (2012): 027001. % Retrieved 6/28/2016 from % https://kar.kent.ac.uk/32810/2/2012_Bi-symmetric-log-transformation_v5.pdf % default values ax = []; % don't call gca unless needed var = 'xyz'; C = 0; % user-specified values for ii = 1:length(varargin) switch class(varargin{ii}) case 'matlab.graphics.axis.Axes' ax = varargin{ii}; case 'char' var = varargin{ii}; case {'double','single'} C = varargin{ii}; otherwise error('Don''t know what to do with input %d (type %s)!',ii,class(varargin{ii})) end end if isempty(ax) % user did not specify a value ax = gca; end % execute once per axis if length(var) > 1 for ii = 1:length(var) symlog(ax,var(ii),C); end return end % From here on we redefine C to be 10^C C = 10^C; % Axes must be in linear scaling set(ax,[var,'Scale'],'linear') % Check for existing transformation userdata = get(ax,'UserData'); if isfield(userdata,'symlog') && isfield(userdata.symlog,lower(var)) lastC = userdata.symlog.(lower(var)); else lastC = []; end userdata.symlog.(lower(var)) = C; % update with new value set(ax,'UserData',userdata) if strcmpi(get(ax,[var,'LimMode']),'manual') lim = get(ax,[var,'Lim']); lim = sign(lim).*log10(1+abs(lim)/C); set(ax,[var,'Lim'],lim) end % transform all objects in this plot into logarithmic coordiates transform_graph_objects(ax, var, C, lastC); % transform axes labels to match t0 = max(abs(get(ax,[var,'Lim']))); % MATLAB's automatically-chosen limits t0 = sign(t0)*C*(10.^(abs(t0))-1); t0 = sign(t0).*log10(abs(t0)); t0 = ceil(log10(C)):ceil(t0); % use C to determine lowest resolution t1 = 10.^t0; mt1 = nan(1,8*(length(t1))); % 8 minor ticks between each tick for ii = 1:length(t0) scale = t1(ii)/10; mt1(8*(ii-1)+(1:8)) = t1(ii) - (8:-1:1)*scale; end % mirror over zero to get the negative ticks t0 = [fliplr(t0),-inf,t0]; t1 = [-fliplr(t1),0,t1]; mt1 = [-fliplr(mt1),mt1]; % the location of our ticks in the transformed space t1 = sign(t1).*log10(1+abs(t1)/C); mt1 = sign(mt1).*log10(1+abs(mt1)/C); lbl = cell(size(t0)); for ii = 1:length(t0) if t1(ii) == 0 lbl{ii} = '0'; % uncomment to display +/- 10^0 as +/- 1 % elseif t0(ii) == 0 % if t1(ii) < 0 % lbl{ii} = '-1'; % else % lbl{ii} = '1'; % end elseif t1(ii) < 0 lbl{ii} = ['-10^{',num2str(t0(ii)),'}']; elseif t1(ii) > 0 lbl{ii} = ['10^{',num2str(t0(ii)),'}']; else lbl{ii} = '0'; end end set(ax,[var,'Tick'],t1,[var,'TickLabel'],lbl) set(ax,[var,'MinorTick'],'on',[var,'MinorGrid'],'on') rl = get(ax,[var,'Ruler']); try set(rl,'MinorTick',mt1) catch err if strcmp(err.identifier,'MATLAB:datatypes:onoffboolean:IncorrectValue') set(rl,'MinorTickValues',mt1) else rethrow(err) end end function transform_graph_objects(ax, var, C, lastC) % transform all lines in this plot lines = findobj(ax,'Type','line'); for ii = 1:length(lines) x = get(lines(ii),[var,'Data']); if ~isempty(lastC) % undo previous transformation x = sign(x).*lastC.*(10.^abs(x)-1); end x = sign(x).*log10(1+abs(x)/C); set(lines(ii),[var,'Data'],x) end % transform all Patches in this plot patches = findobj(ax,'Type','Patch'); for ii = 1:length(patches) x = get(patches(ii),[var,'Data']); if ~isempty(lastC) % undo previous transformation x = sign(x).*lastC.*(10.^abs(x)-1); end x = sign(x).*log10(1+abs(x)/C); set(patches(ii),[var,'Data'],x) end % transform all Retangles in this plot rectangles = findobj(ax,'Type','Rectangle'); for ii = 1:length(rectangles) q = get(rectangles(ii),'Position'); % [x y w h] switch var case 'x' x = [q(1) q(1)+q(3)]; % [x x+w] case 'y' x = [q(2) q(2)+q(4)]; % [y y+h] end if ~isempty(lastC) % undo previous transformation x = sign(x).*lastC.*(10.^abs(x)-1); end x = sign(x).*log10(1+abs(x)/C); switch var case 'x' q(1) = x(1); q(3) = x(2)-x(1); case 'y' q(2) = x(1); q(4) = x(2)-x(1); end set(rectangles(ii),'Position',q) end Plot your functions including symlog(gca,'y',-1.7) in the end: plot( datenum(vector), operatingValue(:,3), '-+', datenum(vector), operatingValue(:,4), '-o',... datenum(vector), operatingValue(:,5), '-*', datenum(vector), operatingValue(:,6), '-x',... 'LineWidth',1.2 ), grid on; symlog(gca,'y',-1.7) Here is your plot with positive and negative values: Hope this solves your problem.
phase assignment in an OFDM signal
I have an OFDM signal which is giving me half the power spectrum (half the bandwidth) I am meant to have. I am been told the phase assignment is what is causing it but I have been twitching on it for days.... still not having the right answer prp=1e-6; fstep=1/prp; M = 4; % QPSK signal constellation k = log2(M); % bits per symbol fs=4e9; Ns=floor(prp*fs); no_of_data_points = (Ns/2); no_of_points=no_of_data_points; no_of_ifft_points = (Ns); % 256 points for the FFT/IFFT no_of_fft_points = (Ns); nsamp = 1; % Oversampling rate fl = 0.5e9; fu = 1.5e9; Nf=(fu-fl)/fstep; phin=zeros(Nf,1); dataIn = randint(no_of_data_points*k*2,1,2); % Generate vector of binary data_source = randsrc(1, no_of_data_points*k*2, 0:M-1); qpsk_modulated_data= modulate(modem.qammod(M),data_source); modu_data= qpsk_modulated_data(:)/sqrt(2); [theta, rho] = cart2pol(real(modu_data), imag(modu_data)); A=angle(modu_data); theta=radtodeg(theta); figure(3); plot(modu_data,'o');%plot constellation without noise axis([-2 2 -2 2]); grid on; xlabel('real'); ylabel('imag'); %% E:GENERTION phin = zeros(Nf,1); phin(1:Nf,1)=theta(1:Nf); No = fl/fstep; Vn = zeros(Ns,1); for r = 1:Nf Vn(r+No,1) = 1*phin(r,1); % Vn(r+No,2) = 1*phin(r,2); end %% %------------------------------------------------------ %E. Serial to parallel conversion %------------------------------------------------------ par_data = reshape(Vn,2,no_of_data_points); %% % F. IFFT Transform each period's spectrum (represented by a row of % time domain via IFFT time_domain_matrix =ifft(par_data.',Ns);
You are only considering the real part of the signal.
Finite difference - wave equation - boundary conditions and setting things up
I am working on a project that has to do with solving the wave equation in 2D (x, y, t) numericaly using the central difference approximation in MATLAB with the following boundary conditions: The general assembly formula is: I understand some of the boundary conditions (BC), like du/dy=0 at j=m, , but I am not sure how to implement these boundary conditions in MATLAB. A friend has given me these equations: Here is my try with the MATLAB code, but I am not able to progress any further: % The wave function % Explicit % Universal boundary conditions for all 3 cases: % u=0 at t=0 % du/dt=0 at t=0 % Case 1 boundary conditions % At x=0, u=2sin(2*pi*t/5); % At y=0, du/dy=0; % At y=2, du/dy=0; % At x=5, du/dx=0; % u=0 and du/dt=0 at t=0; %-------------------------------------------------------------------------% % Setting up clc; clear all; close all; % length, time, height L = 5; % [m] h = 2; % [m] T = 10; % [s] % Constants c_x = 1; % arbitrary c_y = 1; % arbitrary dx = 0.1; % <x> increment dy = 0.1; % <y> increment dt = 0.1; % time increment nx = L/dx + 1; % number of <x> samples ny = h/dy + 1; % number of <y> samples nt = T/dt + 1; % number of time samples t(:,1) = linspace(0, T, nt); theta_x = c_x*(dt^2)/(dx^2); theta_y = c_y*(dt^2)/(dy^2); % theta_x = theta_y theta = theta_x; %-------------------------------------------------------------------------% % The matrix U = zeros(nt, nx, ny); % Setting up the <U> matrix with the boundary conditions - case 1 U(1, :, :) = 0; % U=0 at t=0 for tt=1:nt % U=2sin(2pi/5*t) at x=0 for jj=1:ny U(tt, 1, jj)=2*sin(2*pi/5.*t(tt)); end end for it=2:t for ix=2:nx-1 for iy=2:ny-1 % Boundary conditions % General case (internal): U1 = -U(it-1, ix, iy); U2 = 2*(1-2*theta)*u(it, ix, iy); U3 = theta*U(it, ix-1, iy); U4 = theta*U(it, ix+1, iy); U5 = theta*U(it, ix, iy-1); U6 = theta*U(it, ix, iy+1); end end end
The general assembly formula you have kind of applies to the boundaries as well. The complication is that when you apply the formula when j = 1 and j = m, you have j = 0 and j = m+1 term that are off of your grid. To ameliorate this problem, boundary conditions give you a relationship between the points off the grid and on the grid. As you have indicated, the dudy = 0 condition has given you the relation that u(i,m-1) == u(u,m+1) on the boundary. So you use the general assembly formula and replace all of the m+1 terms with m-1 on the boundary. You'll have a similar relation for the lower boundary as well.