I have a function f which I am trying to take the symbolic limit of. So I start with the standard
R1 = 18;
h1 = 6.48528;
R2 = 1.8;
h2 = 0.060045431;
f1 = R1^2 / (4 * h1);
R3 = 1;
syms x
f1 =#(r) (h2/R2^2) * r.^2 + f1;
f2 =#(r) (h2/R2^2) * r.^2 + f1;
f1p = matlabFunction(diff(f1(x)));
f2p = matlabFunction(diff(f2(x)));
f =#(r1, t1, r2, t2) ...
-((r1.*r2.*(-f1(r1) + f2(r2) + (r1 - r2.*cos(t1 - t2)).*f1p(r1)).* ...
sqrt(((1 + abs(f1p(r1)).^2).*(1 + f1p(r1).^2))./(1 + abs(cos(t2).* ...
f2p(r2)).^2 + abs(sin(t2).*f2p(r2)).^2)).*(-f1(r1) + f2(r2) + ...
(-r2 + r1.*cos(t1 - t2)).*f2p(r2)).*sqrt(1 + f2p(r2).^2))./ ...
(pi.*(1 + abs(cos(t1).*f1p(r1)).^2 + abs(sin(t1).*f1p(r1)).^2).* ...
(r1.^2 + r2.^2 + abs(f1(r1) - f2(r2)).^2 - 2.*r1.*r2.*cos(t1 - t2)).^2))
then I try to take the limit of f
syms r1 r2 t1 t2
limit(f(r1, t1, r2, t2), r2, r1)
And I get piecewise([r1 == 0, 0], [r1 ~= 0, (limit( huge function of r1, r2, t1, t2 )])
So why does Matlab not want to do the limit and is it valid to just convert to a string remove the limit and replace r2 with r1 the return to a function handle? Is there a better way to do this?
And I want to do this so I can then convert the entire mess back into an anonymous function (using matlabFunction).
Related
The following is a snippet from a function I am defining:
function [V1, V2] = lambert(R1, R2, t, string)
r1 = norm(R1);
r2 = norm(R2);
z = -100;
while F(z,t) < 0
z = z + 0.1;
end
tol = 1.e-8;
nmax = 5000;
ratio = 1;
n = 0;
while (abs(ratio) > tol) & (n <= nmax)
n = n + 1;
ratio = F(z,t)/dFdz(z);
z = z - ratio;
end
f = 1 - y(z)/r1;
g = A*sqrt(y(z)/mu);
gdot = 1 - y(z)/r2;
V1 = (R2-f*R1)/g;
V2 = (gdot*R1-R1)/g;
function dum = y(z)
dum = r1 + r2 + A*(z*S(z) - 1)/sqrt(C(z));
end
When I run this code with some vectors R1, R2, I get:
Error using *.
Inner matrix dimensions must agree.
This occurs at these lines:
V1 = (R2-f*R1)/g;
V2 = (gdot*R1-R1)/g;
I think this is due to the fact that f and gdot and g are matrices whose dimensions are incompatible with R1 and R2. However, as I have defined them, they should simply be scalars. I do not understand what in the code causes them to be matrices.
I've tried using .* instead of * etc, but with no success.
I have a problem with the equation shown below. I want to enter a vector in t2 and find the roots of the equation from different values in t2.
t2=[10:10:100]
syms x
p = x^3 + 3*x - t2;
R = solve(p,x)
R1 = vpa(R)
Easy! Don't use syms and use the general formula:
t2 = [10:10:100];
%p = x^3 + 3*x - t2;
a = 1;
b = 0;
c = 3;
d = -t2;
D0 = b*b - 3*a*c;
D1 = 2*b^3 - 9*a*b*c + 27*a^2*d;
C = ((D1+sqrt(D1.^2 - 4*D0.^3))/2).^(1/3);
C1 = C*1;
C2 = C*(-1-sqrt(3)*1i)/2;
C3 = C*(-1+sqrt(3)*1i)/2;
f = -1/(3*a);
x1 = f*(b + C1 + D0./C1);
x2 = f*(b + C2 + D0./C2);
x3 = f*(b + C3 + D0./C3);
Since b = 0, you can simplify this a bit:
% ... polynomial is the same
D0 = -3*a*c;
D1 = 27*a^2*d;
% ... the different C's are the same
f = -1/(3*a);
x1 = f*(C1 + D0./C1);
x2 = f*(C2 + D0./C2);
x3 = f*(C3 + D0./C3);
Trial>> syms x p
Trial>> EQUS = p == x^3 + 3*x - t2
It is unknown that you want to solve an equation or a system.
Suppose that you want to solve a system.
Trial>> solx = solve(Eqns,x)
But, I do not think you can find roots.
You can solve one equation.
Trial>> solx = solve(Eqns(3),x)
As far as I know, Maple can do this batter.
In general, loops should be avoided, but this is the only solution that hit my brain right now.
t2=[10:10:100];
pp=repmat([1,0,3,0],[10,1]);
pp(:,4)=-t2;
for i=1:10
R(i,:) =roots(pp(i,:))';
end
I'm trying to solve a coupled non-linear system of 4 PDEs, here's the code:
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from odeintw import odeintw
# constants
global rH, L, q, p, Q, mu
rH = 1.0 ; L = 1.0 ; p = 2.0 ; q = 1.0 ; Q = 1.71 ; mu = Q*rH/L**2
def dfunc(G, kx, ky, w, r):
try:
z = 1.0/(rH - r)
except ZeroDivisionError:
print "Trying to divide zero"
phi = mu*( 1.0 - rH/r)
fr = 1.0 - (rH/r)**3
scale = L**2 * np.sqrt(fr) / r**2 + 0j
vp = (w + q*phi)/(np.sqrt(fr)) + p*mu*rH/r + 0j
vn = (w + q*phi)/(np.sqrt(fr)) - p*mu*rH/r + 0j
# G11 -> G1, G12 -> G2, G21 -> G3, G22 -> G4
G1, G2, G3, G4 = G
G11 = (vp - kx + (vn + kx)*G1**2 - ky*G1*G2 - ky*G1*G3
+ (vp-kx)*G2*G3 )
G12 = (ky + (vn + kx)*G1*G2 - ky*G2**2 - ky*G1*G4
+ (vp-kx)*G2*G4 )
G21 = (ky + (vn + kx)*G1*G3 - ky*G1*G4 - ky*G3**2
+ (vp-kx)*G3*G4 )
G22 = (vn + kx + (vn + kx)*G2*G3 - ky*G2*G4 - ky*G2*G3
+ (vp-kx)*G4**2 )
return np.multiply(scale, np.array([ G11, G12, G21, G22 ]))
# jaccobian
def jac(G, kx, ky, w, r):
G1, G2, G3, G4 = G
jac = np.array([
[2(vn+kx)*G1 - ky*(G2+G3), -ky*G1 + (vp-kx)*G3, -ky*G1+(vp-kx)*G2, 0 ],
[(vn+kx)*G2-ky*G4, (vn+kx)*G1-2*ky*G2+(vp-kx)*G4, 0, -ky*G1+(vp-kx)*G2 ],
[(vn+kx)*G3-ky*G4, 0, (vn+kx)*G1-2*ky*G3+(vp-kx)*G4, -ky*G1+(vp-kx)*G3 ],
[0, (vn+kx)*G3-ky*(G4+G3), (vn+kx)*G2-ky*G2, -ky*G2+2*(vp-kx)*G4 ]
])
return np.multiply(scale, jac)
# Initial value
Gir = np.array([ 1.0j, 0, 0, 1.0j ])
r = np.arange(rH + 0.1, 1000*rH, 1)
kx = 0
ky = 0
w = 0.0001 + 0.0000001j
G, infodict = odeintw(dfunc, Gir, r, args=(kx,ky,w), Dfun=jac, full_output=True )
print 'final', np.size(G), G
However it gives the following error and does not really move from the initial point:
lsoda-- warning..internal t (=r1) and h (=r2) are
such that in the machine, t + h = t on the next step
(h = step size). solver will continue anyway
In above, R1 = .1100000000000E+01 R2 = .3569471009368E-22
And the final solution G is an array of 3996 size, please help me understand this. Thanks!
In the functions dfunc and jac, the second argument must be the independent variable. In your case, the independent variable is r, so the definitions should begin
def dfunc(G, r, kx, ky, w):
and
def jac(G, r, kx, ky, w):
I have a system of two equations and I need Matlab to solve for a certain variable. The problem is the variable I need is inside an expression, and trig functions. I wrote the following code:
function [ V1, V2 ] = find_voltages( w1, l1, d, w2, G1, G2, m, v, e, h, a, x)
k1 = sqrt((2*V1*e)/(G1^2*m*v^2));
k2 = sqrt((2*V2*e)/(G2^2*m*v^2));
A = h + l1*a;
b = -A*k1*sin(k1*w1) + a*cos(k1*w1);
B = A*cos(k1*w1) + (a/k1)*sin(k1*w1);
C = B + a*b;
c = C*k2*sinh(k2*w2) + b*cosh(k2*w2);
D = C*cosh(k2*w2) + (b/k2)*sinh(k2*w2);
bd = A*k1*sinh(k1*w1) + a*cosh(k1*w1);
Bd = A*cosh(k1*w1) + (a/k1)*sinh(k1*w1);
Cd = Bd + a*bd;
cd = -Cd*k2*sin(k2*w2) + bd*cos(k2*w2);
Dd = Cd*cos(k2*w2) + (bd/k2)*sin(k2*w2);
fsolve([c*(x-(l1+w1+d+w2)) + D == 0, cd*(x-(l1+w1+d+w2)) + Dd == 0], [V1,V2])
end
and got an error because V1 and V2 are not defined. They are part of an expression, and need to be solved for. Is there a way to do this? Also, is it a problem that the functions I put as arguments to solve are conglomerates of the smaller equations above them?
Valid values:
Drift space 1 (l1): 0.11
Quad 1 length (w1): 0.11
Quad 2 length (w2): 0.048
Separation (d): 0.014
Radius of Separation 1 (G1): 0.016
Radius of Separation 2 (G2): 0.01
Voltage 1 (V1): -588.5
Voltage 2 (V2): 418
Kinetic Energy in eV: 15000
Mass (m) 9.109E-31
Kinetic Energy in Joules (K): 2.4E-15
Velocity (v): 72591415.94
Charge on an Electron (e): 1.602E-19
k1^2=(2*V1*e)/(G1^2*m*v^2): 153.4467773
k2^2=(2*V2*e)/(G2^2*m*v^2): 279.015
First start by re-writing your function as an expression which returns the extent to which your function(s) fail to hold for some valid guess for [V1,V2]. E.g.,
function gap = voltage_eqn(V, w1, l1, d, w2, G1, G2, m, v, e, h, a, x)
V1 = V(1) ;
V2 = V(2) ;
k1 = sqrt((2*V1*e)/(G1^2*m*v^2));
k2 = sqrt((2*V2*e)/(G2^2*m*v^2));
A = h + l1*a;
b = -A*k1*sin(k1*w1) + a*cos(k1*w1);
B = A*cos(k1*w1) + (a/k1)*sin(k1*w1);
C = B + a*b;
c = C*k2*sinh(k2*w2) + b*cosh(k2*w2);
D = C*cosh(k2*w2) + (b/k2)*sinh(k2*w2);
bd = A*k1*sinh(k1*w1) + a*cosh(k1*w1);
Bd = A*cosh(k1*w1) + (a/k1)*sinh(k1*w1);
Cd = Bd + a*bd;
cd = -Cd*k2*sin(k2*w2) + bd*cos(k2*w2);
Dd = Cd*cos(k2*w2) + (bd/k2)*sin(k2*w2);
gap(2) = c*(x-(l1+w1+d+w2)) + D ;
gap(1) = cd*(x-(l1+w1+d+w2)) + Dd ;
end
Then call fsolve from some initial V0:
Vf = fsolve(#(V) voltage_eqn(V, w1, l1, d, w2, G1, G2, q, m, v, e, h, a, x), V0) ;
I use function with multiple outputs farina4 that computes coefficients a, b, e, f and a vector out_p5tads_final (1 x n array) through a minimization of a system of equations using the data input set p5tads (1 x n array):
function [a b e f fval out_p5tads_final] = farina4(p5tads)
f = #(coeff)calculs_farina4(coeff,p5tads);
[ans,fval] = fminsearchcon(f,coeff0,[0 0 0 0],[1 1 1 1]);% fminsearch with constrains
a = ans(1);
b = ans(2);
e = ans(3);
f = ans(4);
out_p5tads_final = p5tads_farina4(a,b,e,f);
function out_coeff = calculs_farina4(coeff0,p5tads)
%bla-bla-bla
end
function out_p5tads = p5tads_farina4(a,b,e,f)
%bla-bla-bla
end
end
After calculating a, b, e, f and out_p5tads_final I need to calculate/minimize the RMS function with respect to out_p5tads_f4.
RMS = sqrt(mean((p5tads(:) - out_p5tads_f4(:)).^2))*100
and to repeat function farina4 in order to find the optimal set of the parameters a, b, e, f and out_p5tads_final.
I am trying to build up an algorithm of such optimization and do not see a way so far.
For instance, it seems to be not possible to introduce a function with multiple output inside the above RMS equation unless there is a way to index somehow the output of this function farina4.
If there can be an alternative optimization algorithm for RMS without fminsearch (or similar) ?
a b e and f are values between 0 and 1
out_p5tads_final is an (1 x 10) array
%
function out_coeff = calculs_farina4(coeff0,p5tads)
%
mmmm = p5tads(1);
mmmr = p5tads(2);
rmmr = p5tads(3);
mmrm = p5tads(4);
mmrr = p5tads(5);
rmrm = p5tads(6);
rmrr = p5tads(7);
mrrm = p5tads(8);
mrrr = p5tads(9);
rrrr = p5tads(10);
%
a = coeff0(1);
b = coeff0(2);
e = coeff0(3);
f = coeff0(4);
%
f_mmmm = mmmm - ((a^2*b^2*(a + b) + e^2*f^2*(e + f))/2);
f_mmmr = mmmr - (a^2*b^2*(e + f) + e^2*f^2*(a + b));
f_rmmr = rmmr - ((a^2*f^2*(b + e) + b^2*e^2*(a + f))/2);
f_mmrm = mmrm - 2*a*b*e*f;
f_mmrr = mmrr - b*f*(a^3 + e^3) + a*e*(a^3 + f^3);
f_rmrm = rmrm - 2*a*b*e*f;
f_rmrr = rmrr - 2*a*b*e*f;
f_mrrm = mrrm - ((a^2*b^2*(e + f) + e^2*f^2*(a + b))/2);
f_mrrr = mrrr - (a^2*f^2*(b + e) + b^2*e^2*(a + f));
f_rrrr = rrrr - ((a^2*f^2*(a + f) + b^2*e^2*(b + e))/2);
%
out_coeff = f_mmmm^2 + f_mmmr^2 + f_rmmr^2 + f_mmrm^2 + f_mmrr^2 + f_rmrm^2 + f_rmrr^2 + f_mrrm^2 + f_mrrr^2 + f_rrrr^2;
end
%
function out_p5tads = p5tads_farina4(a,b,e,f)
%
p_mmmm = ((a^2*b^2*(a + b) + e^2*f^2*(e + f))/2);
p_mmmr = (a^2*b^2*(e + f) + e^2*f^2*(a + b));
p_rmmr = ((a^2*f^2*(b + e) + b^2*e^2*(a + f))/2);
p_mmrm = 2*a*b*e*f;
p_mmrr = b*f*(a^3 + e^3) + a*e*(a^3 + f^3);
p_rmrm = 2*a*b*e*f;
p_rmrr = 2*a*b*e*f;
p_mrrm = ((a^2*b^2*(e + f) + e^2*f^2*(a + b))/2);
p_mrrr = (a^2*f^2*(b + e) + b^2*e^2*(a + f));
p_rrrr = ((a^2*f^2*(a + f) + b^2*e^2*(b + e))/2);
%
out_p5tads = [p_mmmm,p_mmmr,p_rmmr,p_mmrm,p_mmrr,p_rmrm,p_rmrr,p_mrrm,p_mrrr,p_rrrr];
end
end
Thanks much in advance !
19/08/2014 3:35 pm
I need to get an optimal set of coefficients a b e f that the RMS value , which is calculated from
RMS = sqrt(mean((p5tads(:) - out_p5tads_f4(:)).^2))*100
is minimal. Here, the vector p5tads is used to calculate/optimize the set of a b e f coefficients, which are in turn used to calculate the vector out_p5tads_f4. The code should run a desired number of optimizations cycles (e.g. by default 100) and then select the series of a b e f and out_p5tads_f4 afforded the minimal RMS error value (with respect to out_p5tads_f4).