I want to solve det(A)=0 for a large matrix A with each element a function of w.
One way to solve these (simple) problems is using a symbolic approach, e.g.:
A = sym('[w, 1; 2, 4*w^2 + 2]');
answer = solve(det(A),'w');
However, I want solve a much larger problem where the equation of each element is defined as a function handle (e.g. A4 = #(w) 4*w^2 + 2;), and may need to be solved numerically with fsolve().
The problem is that I cannot directly put the function handles in matrix A - they need to be put in a cell array, but then solve(det(A)) is incompatible with cell arrays and returns "Undefined function 'det' for input arguments of type 'cell'."
How do I solve the problem?
I have tried to following approach using you minimal example.
% Defining all functions as cells:
f{1,1} = #(w)w;
f{1,2} = #(w)1;
f{2,1} = #(w)2;
f{2,2} = #(w)4*w.^2+2;
% Function to solve
fsol = #(w)det(cellfun(#(x)x(w),f));
% Using fsolve
fsolve(fsol,0)
The result is
0.5898
which is equal to the (real) solution using symbolic math.
Related
To solve one dimensional advection equation denoted by
u_t+u_x = 0, u=u(x,t), and i.c. u(x,0)= 1+H(x+1)+H(x-1)
using Lax Wanderoff method,
I need to write a Heaviside step function H(x) and it needs to be zero when x <= 0, 1 when x>0 . The problem is I also need to use that function writing H(x-t+1), H(x-t-1) as I will compare what I find by the exact solution:
u(x,t) =1 + H(x-t+1) -H(x-t-1)
Here, the "x" and "t" are vectors such that;
x=-5:0.05:5
t=0:0.05:1
I wrote the Heaviside step function as the following; however, I need it without the for loop.
L=length(x)
function H_X= heavisidefunc(x,L)
H_X=zeros(1,L);
for i= 1:L
if x(i)<= 0
H_X(i)=0;
else
H_X(i)=1;
end
end
end
I get "Dimensions must agree." error if I write
H_X3 = heavisidefunc(x-t+1,L);
H_X4 = heavisidefunc(x-t-1,L);
The Heavyside function is really easy to program in Matlab
Heavyside=#(x) x>= 0;
The easiest way to get rid of the dimensions must agree error is to transpose one of the vectors. This will cause Matlab to construct a matrix of length(x1) by length(x2)
Heavyside(x-t'+1);
I came up with a solution. My new Heaviside function is;
function H_X= heavisidefunc(x)
if x<= 0
H_X=0;
else
H_X=1;
end
end
The problem I had was because I was storing the output as a vector and it just complicated things.
Now,writing H(x-t+1), H(x-t-1) is easier. Just put "heavisidefunc(x(i)-t(j)-1)" and loop from 1 to the length of x and l in two loops. Thanks to everyone!
I am trying to solve a particular system of ODE's dF/dt = A*F, F_initial = eye(9). Being a Matlab novice, I am trying to somehow use the implemented ode45 function, and I found useful advises online. However, all of them assume A to be constant, while in my case the matrix A is a function of t, in other words, A changes with each time step.
I have solved A separately and stored it in a 9x9xN array (because my grid is t = 0:dt:2, N=2/dt is the number of time-steps, and A(:,:,i) corresponds to it's value at the i-th time step). But I can't implement this array in ode45 to eventually solve my ODE.
Any help is welcomed, and please tell me if I have missed anything important while explaining my problem. Thank you
First of all, F must be a column vector when using ode45. You won't ever get a result by setting F_initial = eye(9), you'd need F = ones(9,1).
Also, ode45 (documentation here, check tspan section) doesn't necessarily evaluate your function at the timesteps that you give it, so you can't pre-compute the A matrix. Here I'm going to assume that F is a column vector and A is a matrix which acts on it, which can be computed each timestep. If this is the case, then we can just include A in the function passed to ode45, like so:
F_initial = ones(9,1);
dt = 0.01;
tspan = 0:2/dt:2;
[t, F] = ode45(#(t,F) foo(t, F, Ainput), tspan, F_initial);
function f = foo(t, F, Ainput)
A = calculate_A(t, Ainput);
f = A*F;
end
function A = calculate_A(t, Ainput)
%some logic, calculate A based on inputs and timestep
A = ones(9,9)*sqrt(t)*Ainput;
end
The #(x) f(x,y) basically creates a new anonymous function which allows you to treat y as a constant in the calculation.
Hope this is helpful, let me know if I've misunderstood something or if you have other questions.
I'm trying to solve for t trigonometric equations in Matlab, as i.e. 7*cos(t) + 5*sin(t) = 0. I would solve it as: sin(t)/cos(t) = -7/5 and I would find it as arctan(-7/5) = -0.9505.
I have tried to do it on matlab using solve function:
syms t
theta = solve(7*cos(t) + 5*sin(t)==0, t);
disp(theta);
But I get -(log(- 12/37 - (35*i)/37)*i)/2 instead of -0.9505. Could someone explain me why I get this answer from solve and how to get -0.9505?
The expression is the exact result, expressed symbolically (due to the use of syms).
To make Matlab display the result in the format your looking for use double(theta)
which should give you:
double(theta)
ans =
-0.9505
I'm trying to write code that will optimize a multivariate function using sklearn's optimize function, but it keeps returning an IndexError, and I'm not sure where to go from here.
The code is this:
revcoeff = coefficients[::-1]
xdot = np.zeros(0)
normfeat1 = normfeat1.reshape(-1,1)
xdot = np.append(normfeat1, normfeat2.reshape(-1,1), axis=1)
a = revcoeff[1:3]
b = xdot[0, :]
seed = np.zeros(5) #does seed need to be the coefficients? not sure
fun = lambda x: np.multiply((1/666), np.power(np.sum(np.dot(a, xdot[x, :])-medianv[x]),2)) #costfunction
optsol = optimize.minimize(fun, seed)
where there are two features I'm using in my nearest neighbors algorithm. Coefficients for the fitted regression model are given into the array "coefficients".
What I'm having trouble understanding is 1) why my code is throwing a "IndexError: arrays used as indicies must be of integer or boolean type"....and also partially I'm confused by the optimize.minimize function itself. It takes in two input values, the function and x0 (an ndarray with initial guesses). What should x0 be, the coefficients values? Or do I pick random values, and how many are necessary?
np.zeros() does not return integers by default. Try, for example, np.zeros(5, dtype=int) instead. It won't solve all of the problems with your code, though. You'll see some other error message.
Also, notice, that 1/666 returns 0 instead of 0.00150150. You probably want 1/666.0.
It would be helpful if you could clean up your code as half of it is of no use.
I have an existing function of two variables (x,y) called discriminant defined in the following way:
discriminant = xSecondPart * ySecondPart - xySecondPart.^2;
Where xSecondPart and ySecondPart are the second partial derivatives of a function f. xySecondPart is the partial derivative with respect to x of the partial derivative with respect to y of the same function f.
I need to print out the values of discriminant at each value of x in the matrix xAns.
The below code is not working...
for idx = 1:numel(xAns)
disp(discriminant(xAns(idx)));
end
Hopefully someone can provide a solution. Thank you
Best...SL
If you define the function discriminant anonymously, like so:
descriminant = #(x) 24*x.^2 - 32;
Then all you have to do is type the following statement in the command line or function you're running:
D = discriminant(xAns)
If your function has been defined using the elementwise operator '.' wherever necessary, then the statement above will print out the discriminant function evaluated at every element of the matrix xAns, regardless of its size or shape. The values returned will be in the same shape as the matrix xAns. I think that would be the easiest way to solve your problem.