I am trying to solve for x in the following equation:
Where I am trying to solve for x but the integral is too big to do by hand.
This is my attempt in MatLab
clc
clear all
close all
syms x t
eqn = (1-(1/(1.3*10^12))*int((t*15)*exp(-t),0,16*x)) == 10^(-4)
sol = solve(eqn,x)
this is the result that I got . The correct number should be approximately 2.2. I am very thankful for your help.
I made this code for ODE solutions using Runge-Kutta4:
function y=myODE(f,y0,x0,h,x_final)
x=x0;
y=y0;
while x<x_final
h=min(h,x_final-x);
k1=f(x,y);
k2=f(x+h/2,y+h*k1/2);
k3=f(x+h/2,y+h*k2/2);
k4=f(x+h,y+h*k3);
y=y+(h/6)*(k1+2*k2+2*k3+k4)
x=x+h;
end
f is the function y' = f(x,y), y0 is initial value, x0 is where the function starts, h subinterval and x_final is where the function stops.
I tried my code and it solves ODEs for me correctly, but I also want to plot my function over a xy-axis on the interval x0 to x_final with h subintervals. When I try to plot it using plot(x0:h:x_final,y) I only get an empty graph. I understand (guessing) that I have to bind my y to several x in order to plot, but how can I do that without changing my code too much?
How can I plot the graph for y given y0, interval x0 to x_final and given h?
New to MATLAB, appreciate all help I can get!
Edit: To make clear what my code is for;
I need this ODE solver both for solution and graphing. I'm supposed to study the truncation error by looking at values of y on h compared to 2*h and the stability of Runge-Kutta4 by looking at graphs of y with different h.
This is not a very smart refactoring of your code (because it will slow down the solving, also will kill you graphics depending on how many steps you have in your ODE) but I'm sleepy so I go for the hack:
function y=myODE(f,y0,x0,h,x_final)
hold(axes('Parent',figure),'on');
x=x0;
y=y0;
plot(x,y, 'o');
while x<x_final
h=min(h,x_final-x);
k1=f(x,y);
k2=f(x+h/2,y+h*k1/2);
k3=f(x+h/2,y+h*k2/2);
k4=f(x+h,y+h*k3);
y=y+(h/6)*(k1+2*k2+2*k3+k4);
x=x+h;
plot(x,y,'o');
end;
end
Maybe tomorrow I'll re-write this answer to something proper, but—for now—good-night! :-)
function y=myode(f,y0,x0,h,x_final)
x=x0;
y=y0;
plot(x0,y0,'.')
hold on
while x<x_final
h=min(h,x_final-x);
k1=f(x,y);
k2=f(x+h/2,y+h*k1/2);
k3=f(x+h/2,y+h*k2/2);
k4=f(x+h,y+h*k3);
y=y+(h/6)*(k1+2*k2+2*k3+k4);
x=x+h;
plot(x,y,'.')
disp([x,y])
end
The comment box didn't let me to put my fixed-code in "code-format" so post it as an answer.
I would suggest you store the x and y values to vectors and plot them outside the loop. You may want to also output bigX and bigY in order to compare with the exact solution.
function y=myODE(f,y0,x0,h,x_final)
% Example:
% f = #(x,y) (x.^2+cos(y));
% y_final = myODE(f,0,0,0.1,2);
x=x0;
y=y0;
bigX = x0:h:x_final;
if bigX(end)<x_final
% Doesn't occur when x_final = n*h for some integer n
bigX = [bigX,x_final];
end
bigY = zeros(size(bigX));
count = 1;
bigY(1) = y0;
while x<x_final
h=min(h,x_final-x);
k1=f(x,y);
k2=f(x+h/2,y+h*k1/2);
k3=f(x+h/2,y+h*k2/2);
k4=f(x+h,y+h*k3);
y=y+(h/6)*(k1+2*k2+2*k3+k4);
x=x+h;
count = count+1;
bigY(count) = y;
end
plot(bigX,bigY,'b-o')
xlabel('x')
ylabel('y')
I want to model memristor using its equation in exponential mode using Matlab . My aim is to just get the hysteresis plot(i-v plot) in Matlab. the equation is like
i=x^n*b*sinh(av)+m(exp(gv)-1)
x'=Af(x)h(v)
where f(x) is window function and h(v) is polynomial function, A is constant.
f(x)=1-(2x-1)^2
h(v)=cv+dv^3;
c and d are constant c<0 & d>0
a=2; b=0.01; g=4; n=4; A=25; m=0.001;
x is internal state of device..is it possible to get plot in matlab?
I have tried in matlab it is showing errors
This script I found on google after a very brief search:
http://webee.technion.ac.il/people/skva/Memristor%20Models/MATLAB/memristor.m
You can choose there what kind of model do you want to use (Nonlinear Ion Drift model in your case), the type of window function (yours is Jogelkar's I assume) and nonlinear voltage-current relation.
After modifying a bit their script you should get something like this:
b=0.01; g=4; n=4; a=2;A=25; m=0.001;
c=-1;d=4;%your constants
numOfPoints = 10000;
t = linspace(-1, 1,numOfPoints);
dt = t(2) - t(1);
volt = .003*sin(2*pi*t);
x = zeros(size(t));
curr = x;
for i=2:numOfPoints
x(i) = x(i-1) + A*(c*volt(i)+d*(volt(i))^3)*(1-(2*x(i-1)-1)^2)*dt;
curr(i)=x(i)^n*b*sinh(a*volt(i))+m*(exp(g*volt(i))-1);
end;
fig = figure(1);
plot(volt,curr);
xlabel('Voltage');ylabel('Current');
figure(fig);
Good luck!
I'm using fzero function to solve a non-linear equation depending on one parameter
and I'm not satisfied with my method. I have these issues:
1) Can for loop for the parameter be avoided ?
2) In order to avoid complex solutions I first have to pre-compute valid interval for fzero.
Is there is a better solution here ?
If I reduce the parameter step size the execution time becomes slow. If I don’t pre-compute
the interval I get an error "Function values at interval endpoints must be finite and real."
in Matlab and "fzero: not a valid initial bracketing" in Octave.
Here is the code
% solve y = 90-asind(n*(sind(90-asind(sind(a0)/n)-y)))
% set the equation paramaters
n=1.48; a0=0:0.1:60;
% loop over a0
for i = 1:size(a0,2)
% for each a0 find where the argument of outer asind()
% will not give complex solutions, i.e. argument is between 1 and -1
fun1 = #(y) n*(sind(90-asind(sind(a0(i))/n)-y))-0.999;
y1 = fzero(fun1,[0 90]);
fun2 = #(y) n*(sind(90-asind(sind(a0(i))/n)-y))+0.999;
y2 = fzero(fun2,[0 90]);
% use y1, y2 as limits in fzero interval
fun3 = #(y) 90-asind(n*(sind(90-asind(sind(a0(i))/n)-y)))-y;
y(i) = fzero(fun3, [y1 y2]);
end
% plot the result
figure; plot(y); grid minor;
xlabel('Incident ray angle [Deg]');
ylabel('Lens surface tangent angle');
With Matlab, I obtained the plot below with the following simplified loop.
for i = 1:size(a0,2)
fun3 = #(y) sind(90-y) - n*(sind(90-asind(sind(a0(i))/n)-y));
y(i) = fzero(fun3, [0,90]);
end
The difference is in the form of equation: I replaced 90-y = asind(something) with sin(90-y) = something. When "something" is greater than 1 in absolute value, the former version throws an error due to complex value of asind. The latter proceeds normally, recognizing that this is not a solution (sin(90-y) can't be equal to something that is greater than 1).
No precomputing of the bracket was necessary, [0,90] simply worked. Another change I made was in the plot: plot(a0,y) instead of plot(y), to get the correct horizontal axis.
And you can't avoid for loop here, nor should you worry about it. Vectorization means eliminating loops where the content is a low-level operation that can be done en masse by operating on some C array. But fzero is totally not that. If the code takes long to run, it's because solving a bunch of equations takes long, not because there's a for loop.
I have a problem when calculate discrete Fourier transform in MATLAB, apparently get the right result but when plot the amplitude of the frequencies obtained you can see values very close to zero which should be exactly zero. I use my own implementation:
function [y] = Discrete_Fourier_Transform(x)
N=length(x);
y=zeros(1,N);
for k = 1:N
for n = 1:N
y(k) = y(k) + x(n)*exp( -1j*2*pi*(n-1)*(k-1)/N );
end;
end;
end
I know it's better to use fft of MATLAB, but I need to use my own implementation as it is for college.
The code I used to generate the square wave:
x = [ones(1,8), -ones(1,8)];
for i=1:63
x = [x, ones(1,8), -ones(1,8)];
end
MATLAB version: R2013a(8.1.0.604) 64 bits
I have tried everything that has happened to me but I do not have much experience using MATLAB and I have not found information relevant to this issue in forums. I hope someone can help me.
Thanks in advance.
This will be a numerical problem. The values are in the range of 1e-15, while the DFT of your signal has values in the range of 1e+02. Most likely this won't lead to any errors when doing further processing. You can calculate the total squared error between your DFT and the MATLAB fft function by
y = fft(x);
yh = Discrete_Fourier_Transform(x);
sum(abs(yh - y).^2)
ans =
3.1327e-20
which is basically zero. I would therefore conclude: your DFT function works just fine.
Just one small remark: You can easily vectorize the DFT.
n = 0:1:N-1;
k = 0:1:N-1;
y = exp(-1j*2*pi/N * n'*k) * x(:);
With n'*k you create a matrix with all combinations of n and k. You then take the exp(...) of each of those matrix elements. With x(:) you make sure x is a column vector, so you can do the matrix multiplication (...)*x which automatically sums over all k's. Actually, I just notice, this is exactly the well-known matrix form of the DFT.