Solving a non-linear equation in Mathematica with many variables - wolfram-mathematica

I have a beautiful equation, where I am trying to compute for R2. I am using Mathematica. So far every single time that I have tried to use Solve[] or Reduce [] the computation takes forever. I hope You can help me what to do with this beauty in order to get a solution. Thank you! Below is my equation.
eq1 = (R2 + ((((p2x - R2*(vac2y + voby)) - (k1x +
vox ((vobx ((p2y + R2*(vac2x + vobx)) - k1y) +
voby (k1x - (p2x - R2*(vac2y + voby))))/(-voby*
vox + vobx*voy))))^2 + ((p2y +
R2*(vac2x + vobx)) - ((p2y + R2*(vac2x + vobx)) -
voby ((vox (k1y - (p2y + R2*(vac2x + vobx))) +
voy ((p2x - R2*(vac2y + voby)) - k1x))/(-voby*vox +
vobx*voy))))^2)^0.5))/
v2 == (R1 + (((k1x - (k1x +
vox ((vobx ((p2y + R2*(vac2x + vobx)) - k1y) +
voby (k1x - (p2x - R2*(vac2y + voby))))/(-voby*
vox + vobx*voy))))^2 + (k1y - ((p2y +
R2*(vac2x + vobx)) -
voby ((vox (k1y - (p2y + R2*(vac2x + vobx))) +
voy ((p2x - R2*(vac2y + voby)) - k1x))/(-voby*vox +
vobx*voy))))^2)^0.5))/v1

One thing I would note is that it is better to use ^(1/2) or Sqrt[] than ^0.5: Mathematica is very careful to distinguish between real numbers (with decimal points) and integers or rationals.
Even if you make that change, though, I fear the probability of getting a nice analytical solution is small. If you think about the ways you would rearrange the equation to get rid of the square roots, you would end up having to square twice so you will end up with a quartic equation. In principle that is analytically soluble, but only in special cases is the solution compact enough to be useful.

Your expression is of this form:
a + Sqrt[b + c R2 + d R2^2] == e R2 + Sqrt[f + g R2 + h R2^2]
Solve readily returns four solutions.
Now just work out those parameters (a,b,c..) in terms of your original parameters (vox,voy,..,etc) and substitute into the Solve result. (I suspect the result is too unwieldy to be of practical use though.)

Related

Is there a general term formula for 3 queens problem?

The specific question description is:
Put 3 queens on a chessboard of M columns and N rows, how to determine the number of ways that no two of them are in attacking positions?
Note that M is not equals to N, and M/N are larger than a Integer in C language so that there is no way to solve this question using classical computer algorithm like DFS/BFS(for time and memory complexity considerations).
I guess this problem can be calculated by the mathematical method of permutation or combination, but I am not good at math, so, please help me.
Yes.
Searching for keyword "3 queens" in OEIS gives us A047659, and in the Formula section, Vaclav Kotesovec wrote that:
In general, for m <= n, n >= 3, the number of ways to place 3 nonattacking queens on an m X n board is n^3/6*(m^3 - 3m^2 + 2m) - n^2/2*(3m^3 - 9m^2 + 6m) + n/6(2m^4 + 20m^3 - 77m^2 + 58m) - 1/24*(39m^4 - 82m^3 - 36m^2 + 88m) + 1/16*(2m - 4n + 1)(1 + (-1)^(m+1)) + 1/2(1 + abs(n - 2m + 3) - abs(n - 2m + 4))(1/24((n - 2m + 11)^4 - 42(n - 2m + 11)^3 + 656(n - 2m + 11)^2 - 4518(n - 2m + 11) + 11583) - 1/16(4m - 2n - 1)*(1 + (-1)^(n+1))) [Panos Louridas, idee & form 93/2007, pp. 2936-2938].
This formula can be manually confirmed on small Ns and Ms. A simple Python script for this purpose is shown below:
import fractions # to avoid floating error
m = fractions.Fraction(4)
n = fractions.Fraction(4)
assert m<=n
one = fractions.Fraction(1)
ans = n**3/6*(m**3 - 3*m**2 + 2*m) - n**2/2*(3*m**3 - 9*m**2 + 6*m) + n/6*(2*m**4 + 20*m**3 - 77*m**2 + 58*m) - one/24*(39*m**4 - 82*m**3 - 36*m**2 + 88*m) + one/16*(2*m - 4*n + 1)*(1 + (-1)**(m+1)) + one/2*(1 + abs(n - 2*m + 3) - abs(n - 2*m + 4))*(one/24*((n - 2*m + 11)**4 - 42*(n - 2*m + 11)**3 + 656*(n - 2*m + 11)**2 - 4518*(n - 2*m + 11) + 11583) - one/16*(4*m - 2*n - 1)*(1 + (-1)**(n+1)))
print(ans)
Unfortunately, I failed to find the proof of this formula ([Panos Louridas, idee & form 93/2007, pp. 2936-2938], as Vaclav Kotesovec cited). The journal idee & form does not seem to be freely accessible. But due to the reputation of Vaclav Kotesovec (the author of Non-attacking chess pieces), I think we should trust this result.
The simple answer is inclusion/exclusion.
We start by counting the number of ways to place 3 queens in order. Which is just (n*m) * (n*m - 1) * (n*m - 2).
Now we have overcounted, because we don't want the count of the number of ways to place 3 queens with queens 1,2 attacking. Or queens 1,3. Or queens 2,3. But that is just the sum over rows, columns and diagonals of length l of l * (l-1) * (m*n-2).
But now we have undercounted, because if all 3 queens attack each other then we added them in the first step, subtracted 3x in the second step, and now we need to add them back 2x to get to counting those 0 times. Which is the sum over rows, columns and diagonals of length l of l * (l-1) * (l-2).
But this is the count of ways to place all of the queens in order. But given 3 queens on the board, there are 6 orders we could place them. So divide the whole answer by 6.
This can be turned into a program that is O(n+m) to run. Which should be fast enough for your purposes. If you were willing to do a bunch more analysis, we could actually produce a O(1) formula.
The field with coordinates (i, j) is vulnerable for the queen locаted at (qi , qj) if
i == qi || j == qj || abs(i - j) == abs(qi - qj)
This boolean expression should be false for feasible coordinates of each queen. Finding three such fields should not be hard. One cаn try Monte Carlo method which has complexity o(M * N) in worst case.

How to replace a Exponential function with a series in a complex expression using sympy or MMA?

I have a function like this :
The Funtion in MMA
the express for MMA code:
1/(-0.00001 + accT)^11 3.03226 (3.7499 - 8.57119 accT +
4.99983 accT^2 + 0.600048 accT^3 - 1.50004 accT^4 +
1. accT^5) (0.285697 + 0.0000119995 accT - 0.599976 accT^2 -
2.*10^-14 accT^3 + 1.5*10^-9 accT^4 - 0.00006 accT^5 +
1. accT^6) (-1. + E^(
3/2 (1 - (1.56078 (-0.00001 + accT))/phVel)^2)) phVel^2
I want to integrate accT in (0,1).
I have try lots of ways to integrate the function. Fox example,set the Lower limit of integration in 0.0000001 or split integral interval to every 0.01 then Multiply by the express,i.e,Rectangular method, loop i in [0.01,100]:
express1+=0.01*express(i)
but all fail.
so I try to using series to expand E^(3/2 (1 - (1.56078 ( -0.00001 + accT))/phVel)^2),and use the result replace Exponential function.
import sympy as sy
#like picture
express = .....
expressionSeries = sy.exp( 3/2 (1 - (1.56078 (-0.00001 +accT))/phVel)**2),
expressionSeries = sy.series(expressionSeries,accT,0,5)
expression = expression.subs(sy.exp( 3/2 (1 - (1.56078 (-0.00001 +accT))/phVel)**2),expressionSeries)
the code dosen't work.
The integrate result should integrate(express)~phVel^7
You have a factor of 1/(-0.00001 + accT)^11 and so when accT==0.00001 it looks like you will have infinity.
You might try to find
Simplify[
Limit[Integrate[yourfunction,{accT,0,a}],a->0.00001,Direction->"FromBelow"]+
Limit[Integrate[yourfunction,{accT,a,1}],a->0.00001,Direction->"FromAbove"]
]
but that looks like it might be adding -infinity and infinity and the result of that can be anything.
Lots of things about this question and this response really worry me.

finding point on a line which is equidistant from 2 other points

I know I probably should have asked this question in math.stackexchange but answers there are mostly "pen-paper" type. I need an efficient approach to implement and that is why I am asking here.
Q: Given 2 points A & B and a line L. Points and line are 3D. How to find a point on the given line L which is equidistant from the given points A & B?
The approach I followed is:
finding plane, P, perpendicular to line AB and passing through the center of A & B.
point of intersection of P and L would be the answer.
I am working on large data-set (a 3d image) and doing the above calculations involves large no. of multiplications and divisions (on total).
So is there a better way of doing it.
A working code would be very helpful.
Thanks in advance.
If line L is described by parametric vector equation
P=C+t*D
(where C is some base point, D is direction vector, t is parameter)
then point P is equidistant from the given points A & B, when vector from P to the middle of A-B segment is perpendicular to AB vector. So scalar product of these vectors is zero.
(B-A)*(C+t*D-(A+B)/2)=0
Let's
F=B-A
G=C-(A+B)/2
then (in coordinate form)
Fx*(Gx+t*Dx)+Fy*(Gy+t*Dy)+Fz*(Gz+t*Dz)=0
t*(Dx*Fx+Fy*Dy+Fz*Dz)=-(Fx*Gx+Fy*Gy+Fz*Gz)
t=-(Fx*Gx+Fy*Gy+Fz*Gz)/(Dx*Fx+Fy*Dy+Fz*Dz)
case of (Dx*Fx+Fy*Dy+Fz*Dz)=0 corresponds to perpendicular lines AB and L. In this case there is no solution when nominator (Fx*Gx+Fy*Gy+Fz*Gz) is non-zero, and there is infinity of solutions, if nominator is zero (all the points on line are equidistant)
TL;DR. The solution is at the bottom.
Alright, so let's say these are our parameters:
x0 and x1, that describe the line.
a and b, the two points.
Where
x0 = [x0, y0, z0]
x1 = [x1, y1, z1]
a = [xa, ya, za]
b = [xb, yb, zb]
δ = [δx, δy, δz] = (x1 - x0)
Then our description of the line can be seen as a parametric function:
l(λ) = x0 + λ*(x1 - x0)
So we are trying to find a value for λ that satisfies the following equation:
(l(λ) - a)2 = (l(λ) - b)2
(Here I'm cheating with notation a bit, so x2 = x.x)
So expanding everything we get:
(λx1 + (1 - λ)x0 - xa)2 +
(λy1 + (1 - λ)y0 - ya)2 +
(λz1 + (1 - λ)z0 - za)2 =
(λx1 + (1 - λ)x0 - xb)2 +
(λy1 + (1 - λ)y0 - yb)2 +
(λz1 + (1 - λ)z0 - zb)2
Simplifying, we get:
(λδx + x0 - xa)2 +
(λδy + y0 - ya)2 +
(λδz + z0 - za)2 =
(λδx + x0 - xb)2 +
(λδy + y0 - yb)2 +
(λδz + z0 - zb)2
Expanding the brackets and cancelling, we get:
-2δxxaλ + (x0 - xa)2 +
-2δyyaλ + (y0 - ya)2 +
-2δzzaλ + (z0 - za)2 =
-2δxxbλ + (x0 - xb)2 +
-2δyybλ + (y0 - yb)2 +
-2δzzbλ + (z0 - zb)2
Which we can simplify further into some nice neat vector operations:
2λδ.(xb - xa) =
(x0 - xb)2 -
(x0 - xa)2
Which is pretty simple to rearrange to get a linear equation in λ with one unique solution.
You can solve a system of equations to get the answer. A line in 3D is something of the sort of:
x = x<sub>0</sub> + t * v<sub>x</sub>
y = y<sub>0</sub> + t * v<sub>y</sub>
z = z<sub>0</sub> + t * v<sub>z</sub>
Let's denote the point we are searching for P. Now we have:
(Px - Ax)2 + (Py - Ay)2 +(Pz - Az)2 = (Px - Bx)2 +
(Py - By)2 + (Pz - Bz)2
Note that although all these equations seem to be quadtratic, the square of Px we be scratched because it appears on both sides of the equation. Now use this system of equations and the ones above to find the three variables Px, Py and Pz.

Finding Smallest Number of Elements to make a Sum

I have a simple algorithmic question:
If I have certain elements that integer values like:
1 1 1 1 1 1 1 1 1 1 1 1 10 12 2
and I have to make the sum 12, the minimum number of elements needed would 1, I would just use 12.
Thus, my question is how would you:
find the minimum number of elements to make some sum, and if you can't output -1.
Please suggest an algorithm I can look into so I can solve this efficiently. I've already tried brute force but it is much to slow for my needs.
The problem is np-complete and can be reduced to subset sum or knapsack problem. There is pseudo polynomial time algorithm that can solve it using dynamic programming. Following is a solution similar to knapsack analogy:-
1. Knapsack capacity = Sum
2. Items have same weight and value
3. Maximize profit
4. if max_profit == Sum then there is a solution
5. else Sum cannot be made from the items given.
6. Evaluate the minimum items needed using matrix alongside the DP.
7. Can also reconstruct all solutions and get the minimum one.
Time Complexity : - O(Sum*Items)
Java Implementation :-
public class SubSetSum {
static int[][] costs;
static int[][] minItems;
public static void calSets(int target,int[] arr) {
costs = new int[arr.length][target+1];
minItems = new int[arr.length][target+1];
for(int j=0;j<=target;j++) {
if(arr[0]<=j) {
costs[0][j] = arr[0];
minItems[0][j] = 1;
}
}
for(int i=1;i<arr.length;i++) {
for(int j=0;j<=target;j++) {
costs[i][j] = costs[i-1][j];
minItems[i][j] = minItems[i-1][j];
if(arr[i]<=j) {
costs[i][j] = Math.max(costs[i][j],costs[i-1][j-arr[i]]+arr[i]);
if(costs[i-1][j]==costs[i-1][j-arr[i]]+arr[i]) {
minItems[i][j] = Math.min(minItems[i][j],minItems[i-1][j-arr[i]]+1);
}
else if(costs[i-1][j]<costs[i-1][j-arr[i]]+arr[i]) {
minItems[i][j] = minItems[i-1][j-arr[i]]+1;
}
}
}
}
// System.out.println(costs[arr.length-1][target]);
if(costs[arr.length-1][target]==target) {
System.out.println("Minimum items need : "+minItems[arr.length-1][target]);
}
else System.out.println("No such Set found");
}
public static void main(String[] args) {
int[] arr = {1,1,1,1, 1 ,1 ,1, 1 ,1, 1 ,1 ,1, 10 ,12, 2};
calSets(12, arr);
}
}
here is a recursive approach that should be rather fast:
1) if your input vector is of length 1, either return 1 if the value is equal the target, or return -1 if it doesn't. similarly, if your target is less than any of your items in your input vector, return -1.
2) otherwise, loop on (unique) values in your input vector (in descending order, for performance):
2a) remove the value for your vector, and substract it from your target.
2b) recursively call this function on the new vector and the new target
note: you can pass down the algorithm a max.step parameter, so that if you have already found a solution with length K, you would stop the recursive calls at that depth, but not beyond. remember to decrease your max.step value in each recursive call.
3) collect all the values from the recursive calls, take the minimum (which is not -1) and add 1 to it and return, or, if all values in the loop are -1, return -1.
Disclaimer: This is an advertisement for nice but relatively simple mathematics which leads to very clever and fast counting formulas and algorithms. I'm aware that you can find a much simpler and efficient solution using usual programming. I just like the fact that using properly a Computer Algebra System you can do it in a one liner: Lets get 19 with this list:
sage: l = [1,1,1,2,5,2,1,3,12,1,3]; goal = 19
sage: prod((1+t*x^i) for i in l).expand().collect(x).coefficient(x,goal).low_degree(t)
3
What about 25:
sage: goal=25
sage: prod((1+t*x^i) for i in l).expand().collect(x).coefficient(x,goal).low_degree(t)
5
36 is not feasible:
sage: goal=36
sage: prod((1+t*x^i) for i in l).expand().collect(x).coefficient(x,goal).low_degree(t)
0
Here are some details: Just expand the product
(1+t*x^l[0]) (1+t*x^l[1]) ... (1+t*x^l[n])
Where your list is l. Then to find the minimum number of element required to get the sum S, collect the coefficients of x^S and return the minimum degree of a term in t.
Here is how it could be done in sage:
sage: var("x t")
(x, t)
sage: l = [1,1,1,2,5,2,1,3,12,1,3]
sage: s = prod((1+t*x^i) for i in l)
sage: s = expand(s).collect(x)
Now
sage: print(s)
t^11*x^32 + 5*t^10*x^31 + 2*(t^10 + 5*t^9)*x^30 + 2*(t^10 + 5*t^9 + 5*t^8)*x^29 + (11*t^9 + 20*t^8 + 5*t^7)*x^28 + (t^10 + 4*t^9 + 25*t^8 + 20*t^7 + t^6)*x^27 + 2*(3*t^9 + 10*t^8 + 15*t^7 + 5*t^6)*x^26 + (2*t^9 + 17*t^8 + 40*t^7 + 20*t^6 + 2*t^5)*x^25 + (2*t^9 + 12*t^8 + 30*t^7 + 40*t^6 + 7*t^5)*x^24 + (11*t^8 + 30*t^7 + 35*t^6 + 20*t^5 + t^4)*x^23 + 2*(2*t^8 + 13*t^7 + 20*t^6 + 13*t^5 + 2*t^4)*x^22 + (t^8 + 20*t^7 + 35*t^6 + 30*t^5 + 11*t^4)*x^21 + (t^10 + 7*t^7 + 40*t^6 + 30*t^5 + 12*t^4 + 2*t^3)*x^20 + (5*t^9 + 2*t^7 + 20*t^6 + 40*t^5 + 17*t^4 + 2*t^3)*x^19 + 2*(t^9 + 5*t^8 + 5*t^6 + 15*t^5 + 10*t^4 + 3*t^3)*x^18 + (2*t^9 + 10*t^8 + 10*t^7 + t^6 + 20*t^5 + 25*t^4 + 4*t^3 + t^2)*x^17 + (11*t^8 + 20*t^7 + 5*t^6 + 5*t^5 + 20*t^4 + 11*t^3)*x^16 + (t^9 + 4*t^8 + 25*t^7 + 20*t^6 + t^5 + 10*t^4 + 10*t^3 + 2*t^2)*x^15 + 2*(3*t^8 + 10*t^7 + 15*t^6 + 5*t^5 + 5*t^3 + t^2)*x^14 + (2*t^8 + 17*t^7 + 40*t^6 + 20*t^5 + 2*t^4 + 5*t^2)*x^13 + (2*t^8 + 12*t^7 + 30*t^6 + 40*t^5 + 7*t^4 + t)*x^12 + (11*t^7 + 30*t^6 + 35*t^5 + 20*t^4 + t^3)*x^11 + 2*(2*t^7 + 13*t^6 + 20*t^5 + 13*t^4 + 2*t^3)*x^10 + (t^7 + 20*t^6 + 35*t^5 + 30*t^4 + 11*t^3)*x^9 + (7*t^6 + 40*t^5 + 30*t^4 + 12*t^3 + 2*t^2)*x^8 + (2*t^6 + 20*t^5 + 40*t^4 + 17*t^3 + 2*t^2)*x^7 + 2*(5*t^5 + 15*t^4 + 10*t^3 + 3*t^2)*x^6 + (t^5 + 20*t^4 + 25*t^3 + 4*t^2 + t)*x^5 + (5*t^4 + 20*t^3 + 11*t^2)*x^4 + 2*(5*t^3 + 5*t^2 + t)*x^3 + 2*(5*t^2 + t)*x^2 + 5*t*x + 1
Ok this is a huge expression. The nice feature here is that If I take the coefficient say of x^17 I get:
sage: s.coefficient(x, 17)
2*t^9 + 10*t^8 + 10*t^7 + t^6 + 20*t^5 + 25*t^4 + 4*t^3 + t^2
which says the following: the term 10*t^7 tells me that there are 10 different way to obtains the sum 17 using 7 number. Another example, there are 25 way to get 17 using 4 number (25*t^4).
Also since this expression ends with t^2 I learn that I only need two number to get 17. Unfortunately this doesn't tells which numbers.
If you want to understand the trick, look at Wikipedia article on generating functions and This Page.
Note 1: this is not the most efficient since I compute much more than what you need. The huge expression actually described and somehow computed all possible choices (that is 2^the length of the list). But it's a one liner:
sage: prod((1+t*x^i) for i in l).expand().collect(x).coefficient(x,17).low_degree(t)
2
And still relatively efficient:
sage: %timeit prod((1+t*x^i) for i in l).expand().collect(x).coefficient(x,17).low_degree(t)
10 loops, best of 3: 42.6 ms per loop
Note 2: After thinking carefully about it I also realized the following: Generating series is just a compact encoding of what you would have written if you tried to implement a dynamic programming solution.
I don't think this solution is optimal, but it's very easy to understand and use, you sort the elements in decreasing order, then you take each element and try to fit it in your number. If you have the sequence [5,6,2,7] and you need to make the 15 number, you'll reorder the sequence [7,6,5,2] and take 7, then you need to extract 8 so you'll take 6, then you'll need 2 more, check 5 but it's too big and you'll skip it and check the last number, 2, which it's perfect and finishes your number. So you'd print out 3. This is the worst case of the algorithm which is O(n). But in your example with 12, it'll be O(1), because you'll pick 12 from the first checkup of the ordered sequence. (running time applies only for the program of choosing items, not sorting)
resolve_sum(ordered_items[], number) {
count = 0;
aux = number;
i = 0;
while (aux - ordered_items[i] <= 0) {
count = count + 1;
aux = aux - ordered_items[i];
i = i + 1;
}
if (aux == 0) return count;
else return -1;
}
I haven't included an algorithm for sorting, you can choose one that you know best or try to learn a new efiecient one. Link with sorting algorithms and their running time. This is just a sample code you can use in C/C++ or Java or what you need. I hope it isn't way too much brute force.

mathematica simplify denominator

In this algebraic expression, how to force Mathematica to calculate first a common
denominator and then to simplify:
(32768 Sqrt[\[Pi]] Va)/((7/b^2 + 2/mua^2)^(3/2) mua^3) +
(32 Sqrt[\[Pi]] Va)/((b^2 + mua^2)^(3/2) (2/b^2 + 1/(b^2 + mua^2))^(3/2))
+ (6144 Sqrt[\[Pi]] Va)/((b^2 + mua^2)^( 3/2) (3/b^2 + 1/(b^2 + mua^2))^(3/2))
the expression is too long, this is only a part.
Use
Together[ (your expression here) ]
For this expression it works with Together[] and then Apart[]. But for a larger expression with 50 terms like these I used Expand[expression]//Factor, and then again Expand[expression] to separate the terms.

Resources