Solve mixed equation in one variable - wolfram-mathematica

I have this equation and want to solve it for v. I tried Mathematica but it is not able to do it. Is there any software, language capable of solving it?
Equation:
Solve[1 + 0.0914642/v^5 - 1.87873/v^4 + 96.1878/v^2 - (
17.3914 E^(-(0.0296/v^2)) (1.398 + 0.0296/v^2))/v^2 - 0.947895/v -
1.37421 v == 0, v]
The text file/m-file is here.

Using Mathematica 9 :-
Clear[v]
expr = 1 + 0.0914642/v^5 - 1.87873/v^4 + 96.1878/v^2 - (
17.3914 E^(-(0.0296/v^2)) (1.398 + 0.0296/v^2))/v^2 - 0.947895/v -
1.37421 v;
sol = Solve[expr == 0, v, Reals]
{{v -> -0.172455}, {v -> 0.0594091}, {v -> 0.105179}, {v -> 3.93132}}
Checking solutions :-
roots = v /. sol;
(v = #; expr) & /# roots
{2.27374*10^-13, 2.32703*10^-12, -9.66338*10^-13, -1.77636*10^-15}
(v = #; Chop[expr]) & /# roots
{0, 0, 0, 0}

Try this in Matlab. You need to have the Symbolic Math Toolbox installed:
>> syms v %// declare symbolic variable, used in defining y
>> y = 1 + 0.0914642/v^5 - 1.87873/v^4 + 96.1878/v^2 - (17.3914*exp(-(0.0296/v^2)) * (1.398 + 0.0296/v^2))/v^2 - 0.947895/v - 1.37421*v;
>> solve(y,v) %// seeks zeros of y as a function of v
ans =
3.931322452560060553464772086259
>> subs(y,3.931322452560060553464772086259) %// check
ans =
-4.4409e-016 %// almost 0 (precision of floating point numbers): it is correct

Without the symbolic math toolbox, you can still do it numerically with fzero:
a1 = 8.99288497*10^(-2);
a2 = -4.94783127*10^(-1);
a3 = 4.77922245*10^(-2);
a4 = 1.03808883*10^(-2);
a5 = -2.82516861*10^(-2);
a6 = 9.49887563*10^(-2);
a7 = 5.20600880*10^(-4);
a8 = -2.93540971*10^(-4);
a9 = -1.77265112*10^(-3);
a10 = -2.51101973*10^(-5);
a11 = 8.93353441*10^(-5);
a12 = 7.88998563*10^(-5);
a13 = -1.66727022*10^(-2);
a14 = 1.39800000 * exp(0);
a15 = 2.96000000*10^(-2);
t = 30;
p = 10;
tr = t/(273.15 + 31.1);
pr = p/(73.8);
s1 = #(v) (a1 + (a2/tr^2) + (a3/tr^3))./v;
s2 = #(v) (a4 + (a5/tr^2) + (a6/tr^3))./v.^2;
s3 = #(v) (a7 + (a8/tr^2) + (a9/tr^3))./v.^4;
s4 = #(v) (a10 + (a11/tr^2) + (a12/tr^3))./v.^5;
s5 = #(v) (a13./(tr^3.*v.^2)).*(a14 + (a15./v.^2)).*exp(-a15./v.^2);
y = #(v) -(pr*v./tr) + 1 + s1(v) + s2(v) + s3(v) + s4(v) + s5(v);
root = fzero(y, [1 5]);
% Visualization
fplot(y, [1 5]); hold all; refline(0,0); line([root,root], [-10,30])

Related

Mathematica Code with Module and If statement

Can I simply ask the logical flow of the below Mathematica code? What are the variables arg and abs doing? I have been searching for answers online and used ToMatlab but still cannot get the answer. Thank you.
Code:
PositiveCubicRoot[p_, q_, r_] :=
Module[{po3 = p/3, a, b, det, abs, arg},
b = ( po3^3 - po3 q/2 + r/2);
a = (-po3^2 + q/3);
det = a^3 + b^2;
If[det >= 0,
det = Power[Sqrt[det] - b, 1/3];
-po3 - a/det + det
,
(* evaluate real part, imaginary parts cancel anyway *)
abs = Sqrt[-a^3];
arg = ArcCos[-b/abs];
abs = Power[abs, 1/3];
abs = (abs - a/abs);
arg = -po3 + abs*Cos[arg/3]
]
]
abs and arg are being reused multiple times in the algorithm.
In a case where det > 0 the steps are
po3 = p/3;
b = (po3^3 - po3 q/2 + r/2);
a = (-po3^2 + q/3);
abs1 = Sqrt[-a^3];
arg1 = ArcCos[-b/abs1];
abs2 = Power[abs1, 1/3];
abs3 = (abs2 - a/abs2);
arg2 = -po3 + abs3*Cos[arg1/3]
abs3 can be identified as A in this answer: Using trig identity to a solve cubic equation
That is the most salient point of this answer.
Evaluating symbolically and numerically may provide some other insights.
Using demo inputs
{p, q, r} = {-2.52111798, -71.424692, -129.51520};
Copyable version of trig identity notes - NB a, b, p & q are used differently in this post
Plot[x^3 - 2.52111798 x^2 - 71.424692 x - 129.51520, {x, 0, 15}]
a = 1;
b = -2.52111798;
c = -71.424692;
d = -129.51520;
p = (3 a c - b^2)/3 a^2;
q = (2 b^3 - 9 a b c + 27 a^2 d)/27 a^3;
A = 2 Sqrt[-p/3]
A == abs3
-(b/3) + A Cos[1/3 ArcCos[
-((b/3)^3 - (b/3) c/2 + d/2)/Sqrt[-(-(b^2/9) + c/3)^3]]]
Edit
There is also a solution shown here
TRIGONOMETRIC SOLUTION TO THE CUBIC EQUATION, by Alvaro H. Salas
Clear[a, b, c]
1/3 (-a + 2 Sqrt[a^2 - 3 b] Cos[1/3 ArcCos[
(-2 a^3 + 9 a b - 27 c)/(2 (a^2 - 3 b)^(3/2))]]) /.
{a -> -2.52111798, b -> -71.424692, c -> -129.51520}
10.499

Mathematica more input is needed

I'm not much familiar with this programming language and I just need to run one function to compute some coeficients.
f[x] = x^2 - 2 x + 2
g[x] = x^3 - 2 x^2 - 2 x - 2
f1 = Root[f[x], 1];
f2 = Root[f[x], 2];
g1 = Root[g[x], 1];
g2 = Root[g[x], 2];
g3 = Root[g[x], 3];
foo[rootList, alpha, beta] :=
(
res = {};
For[i = 1, i <= Length[rootList], i++, alphaI = rootList[[i]];
For[j = 1, j <= Length[rootList], j++, betaJ = rootList[[j]];
If[betaJ != beta,
(
kor = Simplify [(alphaI - alpha) / (beta - betaJ)];
res = Append[res, N[kor, 5]];
),
]
]
]
Return[res];
)
roots = [f1, f2, g1, g2, g3];
cs = foo[roots, f1, g1]
this piece of code gives me this error:
Syntax::tsntxi: "For[i=1,i<=Length[rootList],i++,alphaI=rootList[[i]];" is incomplete; more input is needed.
And don't see what is wrong. I'm using mathematica 10.4
Fixing the syntax errors.
f[x_] := x^2 - 2 x + 2
g[x_] := x^3 - 2 x^2 - 2 x - 2
f1 = Root[f[x], 1];
f2 = Root[f[x], 2];
g1 = Root[g[x], 1];
g2 = Root[g[x], 2];
g3 = Root[g[x], 3];
foo[rootList_, alpha_, beta_] :=
(
res = {};
For[i = 1, i <= Length[rootList], i++, alphaI = rootList[[i]];
For[j = 1, j <= Length[rootList], j++, betaJ = rootList[[j]];
If[betaJ != beta,
(
kor = Simplify[(alphaI - alpha)/(beta - betaJ)];
res = Append[res, N[kor, 5]];
)
]
]
];
res
)
roots = {f1, f2, g1, g2, g3};
cs = foo[roots, f1, g1]

Why doesn't my octave code run, No errors are shown

I'm new to octave and I wrote this code. But even the fprintf statement on the first line isn't getting printed. Someone please help
I typed
C = strassen(zeros(1024, 1024), zeros(1024, 1024)
But nothing is being printed and the word
octave 2:> does not show up on the next line after giving the command
function [C] = strassen(A, B)
fprintf('strassen called\n');
row = size(A, 1);%Incase zeros must be padded to make dimensions even
column = size(B, 2);
common = size(A, 2);
if row*common*column <= 1000000,%Base case when less than 10^6 multiplications needed
C = zeros( row, column );
for x = 1 : row,
for y = 1 : column,
for z = 1 : common,
C(x, y) += A(x, z)*B(z, y);
end;
end;
end;
else
%Padding zeros if needed
if rem(row, 2) == 1,
A = [A; zeros(1, common)];
end;
if rem(column, 2) == 1,
B = [B zeros(common, 1)];
end;
if rem(common, 2) == 1,
A = [A zeros(size(A, 1), 1)];
B = [B; zeros(1, size(B, 2))];
end;
m = size(A, 1);
n = size(A, 2);
o = size(B, 2);
A11 = A(1:m/2, 1:n/2 );
A12 = A(1:m/2, n/2+1: n);
A21 = A(m/2+1 :m, 1:n/2);
A22 = A(m/2+1 :m ,n/2+1: n);
B11 = A(1:n/2, 1:o/2 );
B12 = A(1:n/2, o/2+1: o);
B21 = A(n/2+1 :n, 1:o/2);
B22 = A(n/2+1 :n, o/2+1: o);
M1 = strassen(A11 + A22, B11 + B22);
M2 = strassen(A21 + A22, B11);
M3 = strassen(A11, B12 - B22);
M4 = strassen(A22, B21 - B11);
M5 = strassen(A11 + A12, B22);
M6 = strassen(A21 - A11, B11 + B12);
M7 = strassen(A12 - A22, B21 + B22);
%C11 = M1 + M4 - M5 + M7;
%C12 = M3 + M5;
%C21 = M2 + M4;
%C22 = M1 + M3 - M2 + M6;
%C = [C11 C12; C21 C22];
%C = C(1:row, 1:column);
C = [(M1 + M4 - M5 + M7) (M3 + M5);(M2 + M4) (M1 + M3 - M2 + M6)](1:row, 1:column);
end;
end;
As Dan said there is a ")" missing in your call. But this may be a copy&paste error. If you use
C = strassen(zeros(1024, 1024), zeros(1024, 1024));
You don't see "strassen called" because the calculation takes long. I haven't waited until it finished and aborted after 30s. If you want to see the recursive calls you can flush stdout:
...
fprintf('strassen called\n');
fflush (stdout);
...
or disable the pager with more off. In this case you'll see
>> C = strassen(zeros(1024, 1024), zeros(1024, 1024));
strassen called
strassen called
strassen called
strassen called
strassen called
what I think is what you would expect.

Finding the intersection of two lines

I have two lines:
y = -1/3x + 4
y = 3x + 85
The intersection is at [24.3, 12.1].
I have a set of coordinates prepared:
points = [[1, 3], [4, 8], [25, 10], ... ]
#y = -1/3x + b
m_regr = -1/3
b_regr = 4
m_perp = 3 #(1 / m_regr * -1)
distances = []
points.each do |pair|
x1 = pair.first
y2 = pair.last
x2 = ((b_perp - b_regr / (m_regr - m_perp))
y2 = ((m_regr * b_perp) / (m_perp * b_regr))/(m_regr - m_perp)
distance = Math.hypot((y2 - y1), (x2 - x1))
distances << distance
end
Is there a gem or some better method for this?
NOTE: THE ABOVE METHOD DOES NOT WORK. See my answer for a solution that works.
What's wrong with using a little math?
If you have:
y = m1 x + b1
y = m2 x + b2
It's a simple system of linear equations.
If you solve them, your intersection is:
x = (b2 - b1)/(m1 - m2)
y = (m1 b2 - m2 b1)/(m1 - m2)
After much suffering and many different tries, I found a simple algebraic method here that not only works but is dramatically simplified.
distance = ((y - mx - b).abs / Math.sqrt(m**2 + 1))
where x and y are the coordinates for the known point.
For Future Googlers:
def solution k, l, m, n, p, q, r, s
intrsc_x1 = m - k
intrsc_y1 = n - l
intrsc_x2 = r - p
intrsc_y2 = s - q
v1 = (-intrsc_y1 * (k - p) + intrsc_x1 * (l - q)) / (-intrsc_x2 * intrsc_y1 + intrsc_x1 * intrsc_y2);
v2 = ( intrsc_x2 * (l - q) - intrsc_y2 * (k - p)) / (-intrsc_x2 * intrsc_y1 + intrsc_x1 * intrsc_y2);
(v1 >= 0 && v1 <= 1 && v2 >= 0 && v2 <= 1) ? true : false
end
The simplest and cleanest way I've found on the internet.

NMinimize is very slow

You are my last hope.
In my university there are no people able to answer my question.
I've got a function quite complex depending on 6 paramethers a0,a1,a2,b0,b1,b2 that minimize the delta of pression, volume liquid and volume vapor calculated by a rather new equation of state.
NMinimize is very slow and I could not do any considerations about this equation because timing is very high.
In the code there are some explanations and some problems concerning my code.
On my knees I pray you to help me.
I'm sorry, but after 4 months on construction of these equation I could not test it. And frustration is increasing day after day!
Clear["Global`*"];
data = {{100., 34.376, 0.036554, 23.782}, {105., 56.377, 0.037143,
15.116}, {110., 88.13, 0.037768, 10.038}, {115., 132.21, 0.038431,
6.9171}, {120., 191.43, 0.039138, 4.9183}, {125., 268.76,
0.039896, 3.5915}, {130., 367.32, 0.040714, 2.6825}, {135.,
490.35, 0.0416, 2.0424}, {140., 641.18, 0.042569, 1.5803}, {145.,
823.22, 0.043636, 1.2393}, {150., 1040., 0.044825,
0.98256}, {155., 1295., 0.046165, 0.78568}, {160., 1592.1,
0.047702, 0.63206}, {165., 1935.1, 0.0495, 0.51014}, {170.,
2328.3, 0.051667, 0.41163}, {175., 2776.5, 0.054394,
0.33038}, {180., 3285.2, 0.058078, 0.26139}, {185., 3861.7,
0.063825, 0.19945}, {190., 4518.6, 0.079902, 0.12816}};
tvector = data[[All, 1]];(*K*)
pvector =
data[[All, 2]];(*KPa*)
vlvector = data[[All, 3]];(*L/mol*)
vvvector =
data[[All, 4]];
(*L/mol.*)
r = 8.314472;
tc = 190.56;
avvicinamento = Length[tvector] - 3;
trexp = Take[tvector, avvicinamento]/tc;
vlexp = Take[vlvector, avvicinamento];
vvexp = Take[vvvector, avvicinamento];
zeri = Table[i*0., {i, avvicinamento}];
pexp = Take[pvector, avvicinamento];
(*Function for calculation of Fugacity of CSD Equation*)
(*Function for calculation of Fugacity of CSD Equation*)
fug[v_, p_, t_, a_, b_] :=
Module[{y, z, vbv, vb, f1, f2, f3, f4, f}, y = b/(4 v);
z = (p v)/(r t);
vbv = Log[(v + b)/v];
vb = v + b;
f1 = (4*y - 3*y^2)/(1 - y)^2;
f2 = (4*y - 2*y^2)/(1 - y)^3;
f3 = (2*vbv)/(r t*b)*a;
f4 = (vbv/b - 1/vb)/(r t)*a;
f = f1 + f2 - f3 + f4 - Log[z];
Exp[f]]
(*g Minimize the equality of fugacity*)
g[p_?NumericQ, t_?NumericQ, a0_?NumericQ, a1_?NumericQ, a2_?NumericQ,
b0_?NumericQ, b1_?NumericQ, b2_?NumericQ] := Module[{},
a = a0*Exp[a1*t + a2*t^2];
b = b0 + b1*t + b2*t^2;
csd = a/(r*t*(b + v)) - (-(b^3/(64*v^3)) + b^2/(16*v^2) +
b/(4*v) + 1)/(1 - b/(4*v))^3 + (p*v)/(r*t);
vol = NSolve[csd == 0 && v > 0, v, Reals];
sol = v /. vol;
(*If[Length[sol]==1,Interrupt[];Print["Sol==1"]];*)
vliquid = Min[sol];
vvapor = Max[sol];
fl = fug[vliquid, p, t, a, b];
fv = fug[vvapor, p, t, a, b];
(*Print[{t,p,vol,Abs[fl-fv]}];*)
Abs[fl - fv]];
(*This function minimize the pcalc-pexp and vcalc-vexp *)
hope[a0_?NumericQ, a1_?NumericQ, a2_?NumericQ, b0_?NumericQ,
b1_?NumericQ, b2_?NumericQ] :=
Module[{},
pp[a0, a1, a2, b0, b1, b2] :=
Table[FindRoot[{g[p, tvector[[i]], a0, a1, a2, b0, b1, b2]},
{p,pvector[[i]]}],{i,avvicinamento}];
pressioni1 = pp[a0, a1, a2, b0, b1, b2];
pcalc = p /. pressioni1;
differenza = ((pcalc - pexp)/pexp)^2;
If[MemberQ[differenza, 0.],
differenza = zeri + RandomReal[{100000, 500000}];(*
First problem:
As I've FindRoot that finds the solutions equal to the starting \
point, I don't want these kind of solutions and with this method - \
+RandomReal[{100000,500000}] -
a keep away this solutions.Is it right? *)
deltap = Total[differenza],
differenzanonzero = Select[differenza, # > 0 &];
csd1[a_, b_, p_, t_] :=
a/(r*t*(b + v)) - (-(b^3/(64*v^3)) + b^2/(16*v^2) + b/(4*v) +
1)/(1 - b/(4*v))^3 + (p*v)/(r*t);(*Funzione CSD*)
volumi =
Table[NSolve[csd1[a, b, pcalc[[i]], tvector[[i]]], v, Reals], {i,
avvicinamento}];
soluzioni = v /. volumi;
vvcalc = Table[Max[soluzioni[[i]]], {i, avvicinamento}];
vlcalc = Table[Min[soluzioni[[i]]], {i, avvicinamento}];
deltavl = Total[((vlexp - vlcalc)/vlcalc)^2];
deltavv = Total[((vvexp - vvcalc)/vvcalc)^2];
deltap = Total[differenza];
Print[a0, " ", b0, " ", delta];
delta = 0.1*deltavl + 0.1*deltavv + deltap]];
NMinimize[{hope[a0, a1, a2, b0, b1, b2],
500 < a0 < 700 && -0.01 < a1 < -1.0*10^-5 && -10^-5 < a2 < -10^-7 &&
0.0010 < b0 < 0.1 && -0.0010 < b1 < -1.0*10^-5 &&
10^-9 < b2 < 10^-7}, {a0, a1, a2, b0, b1, b2}]
Thanks in advance!
Mariano Pierantozzi
PhD Student in chemical Engineering

Resources