I have these four equations:
eq1:= 1.6*10^(-7)*R*sin(t)-4.4*10^(-14)*R^2*cos(t)*sin(t)-1.6*10^(-14)*R^2*cos(t)^2+4.2*10^(-14)*R^2-1.3+2.1*10^(-9)*R*cos(t)=0;
eq2 := 8.3*10^(-8)*R*sin(t)-1.2*10^(-13)*R^2*cos(t)*sin(t)-2.9*10^(-44)*R^2*cos(t)^2+7.1*10^(-14)*R^2-1.3+8.3*10^(-8)*R*cos(t)=0;
eq3 := 8.3*10^(-8)*R*sin(t)-1.2*10^(-13)*R^2*cos(t)*sin(t)-2.2*10^(-44)*R^2*cos(t)^2+7.1*10^(-14)*R^2-1.3+8.3*10^(-8)*R*cos(t)=0;
eq4 := 2.1*10^(-9)*R*sin(t)-4.4*10^(-14)*R^2*cos(t)*sin(t)+1.6*10^(-14)*R^2*cos(t)^2+2.6*10^(-14)*R^2-1.3+1.6*10^(-7)*R*cos(t)=0;
I want to solve each equation for R, each obviously yielding two roots and I'm always assured that one root is above the horizontal axis while the other is below it, and pick only the four non-negative roots without doing it manually i.e. for instance, write something like res:=solve(eq1,R), plotting each one as a function of t and only then taking the positive root. I want the code to do it.
After obtaining the positive roots, say {r1,r2,r3,r4}, I want to plot on the same figure, the following 4 graphs
plot([r1*cos(t),r1*sin(t),t=0..2*Pi]);
plot([r2*cos(t),r2*sin(t),t=0..2*Pi]);
plot([r3*cos(t),r3*sin(t),t=0..2*Pi]);
plot([r4*cos(t),r4*sin(t),t=0..2*Pi]);
Finally, I need to outline the intersection area with some color and shade it.
I would appreciate your help.
Here is how to pick the positive root and how to iterate through your equations. From here I think you should be able to make the plots yourself. Just beware that your roots are "heavy" expressions.
restart:
with(plots):
# Number of equations
n := 4;
# Empty solution vector
solutions := Vector(n):
# List of equations
eq := [
1.6*10^(-7)*R*sin(t)-4.4*10^(-14)*R^2*cos(t)*sin(t)-1.6*10^(-14)*R^2*cos(t)^2+4.2*10^(-14)*R^2-1.3+2.1*10^(-9)*R*cos(t)=0 ,
8.3*10^(-8)*R*sin(t)-1.2*10^(-13)*R^2*cos(t)*sin(t)-2.9*10^(-44)*R^2*cos(t)^2+7.1*10^(-14)*R^2-1.3+8.3*10^(-8)*R*cos(t)=0 ,
8.3*10^(-8)*R*sin(t)-1.2*10^(-13)*R^2*cos(t)*sin(t)-2.2*10^(-44)*R^2*cos(t)^2+7.1*10^(-14)*R^2-1.3+8.3*10^(-8)*R*cos(t)=0 ,
2.1*10^(-9)*R*sin(t)-4.4*10^(-14)*R^2*cos(t)*sin(t)+1.6*10^(-14)*R^2*cos(t)^2+2.6*10^(-14)*R^2-1.3+1.6*10^(-7)*R*cos(t)=0
]:
# Iterate through all equations
for i from 1 to n do:
# Find and store positive root
solutions[i] := solve(eq[i], R, useassumptions) assuming R>0:
end do:
solutions;
Related
I want to plot in Maple the solutions to the equation (x-y)^2+(1-z)^2=0.
However, implicitplot3d is not able to plot them, at least using the default arguments. Any recommendations?
I know a priori that the set of solutions is going to be a curve contained in a plane, because I want to plot solutions of equations of the form 'f(x,y)^2+(z-1)^2=0'. Where 'f(x,y)' is a polynomial.
If x, y, and z are all real then those two squares must both equal zero, and thus z=1.
In that case you can simply utilize the implicitplot command for a 2-D plot of f(x,y)=0, and if you wish you can transform that to a 3-D plot with z=1.
restart;
with(plots,display): with(plots,implicitplot):
with(plottools,transform):
eqn := (x-y)^2+(1-z)^2 = 0:
P2D := implicitplot(eval(eqn,z=1)):
display(transform((x,y)->[x,y,1])(P2D),
labels=[x,y,z]);
eqn := (x^2-y)^2+(1-z)^2 = 0:
P2D := plots:-implicitplot(eval(eqn,z=1)):
display(transform((x,y)->[x,y,1])(P2D),
labels=[x,y,z]);
I am trying to calculate two volumes which are related to each other. In this case as one volume increases it means more of the other volume is possible.
My code is as follows:
Plot[{(6.78966*10^22)(b)},{((9.0226522*10^22)(x))}, {(b, 0, 5.5*10^6),(x, 0, 5.5*10^6)}]
I want this to be plotted on one graph, so it can show the relationship of increasing one volume while the other decreases. However, I can't get this to display in wolfram alpha, a graphing calculator, or mathematica. It seems extremely simple and I am probably just making a dumb error.
The error that is being thrown by mathematica is: ( " cannot be followed by " b,0,5.5*10^6)
But when I try it without the parenthesis it says I do not have enough rules to define my function. Is there a better way to do this?
What I am trying to do is find how many cm^3 of plutonium is needed to convert cm^3 of cadmium. I have done the relationships, but now I am trying to plot it. The maximum volume that can be utilized is 5.5*10^6. So I want one line to end when all of the cm^3 of the volume are cadmium and the other to end when all of the cm^3 is plutonium. This will allow me to find the point in which they intersect optimizing my problem.
Taking the maximum volume, m
m = 5.5*10^6;
Plot[{6.78966*10^22 (m - x), 9.0226522*10^22 x}, {x, 0, m}]
Solve[6.78966*10^22 (m - x) == 9.0226522*10^22 x, x]
{{x -> 2.36165*10^6}}
I have a similar line graph plotted using R plot function (plot(df))
I want to get distance of the whole line between two points in the graph (e.g., between x(1) and x(3)). How can I do this?
If your function is defined over a fine grid of points, you can compute the length of the line segment between each pair of points and add them. Pythagoras is your friend here:
To the extent that the points are not close enough together that the function is essentially linear between the points, it will tend to (generally only slightly) underestimate the arc length.
Note that if your x-values are stored in increasing order, these ẟx and ẟy values can be obtained directly by differencing (in R that's diff)
If you have a functional form for y as a function of x you can apply the integral for the arc length -- i.e. integrate
∫ √[1+(dy/dx)²] dx
between a and b. This is essentially just the calculation in 1 taken to the limit.
If both x and y are parametric functions of another variable (t, say) you can simplify the parametric form of the above integral (if we don't forget the Jacobian) to integrating
∫ √[(dx/dt)²+(dy/dt)²] dt
between a and b
(Note the direct parallel to 1.)
if you don't have a convenient-to-integrate functional form in 2. or 3. you can use numerical quadrature; this can be quite efficient (which can be handy when the derivative function is expensive to evaluate).
This should be simple for those with experience.
I want to solve an equation using R. I know you can solve
different linear/quadratic equations using Solve().
But I have something like this:
1/20 = 1/8 * (1/(12+x)) + 1/4*(1/(40+x)) + 3/4*(1/(50+x))
How can I solve x in this case? It can't be done by hand.
It gotta be some numeric methods involved to solve this like in TI83.
Is there a simple and quick way to do this in R without writing lines of codes?
Thank you!
As you say, there are indeed roots. First thing is to plot the function:
f <- function(x) {1/20 - 1/8 * (1/(12+x)) + 1/4*(1/(40+x)) + 3/4*(1/(50+x))}
x <- seq(-100,100)
par(mar=c(2,2,1,2)) # this just minimizes plot margins
plot(x,f(x), type="l")
abline(0,0,col="blue",lty=2)
So obviously, f(x) does cross 0, several times.
Next step is to estimate the crossings. One way to do this is to look for changes in sign:
x <- seq(-75,0,0.001)
y <- sign(f(x)) # vector of +1 or -1
plus.to.minus <- which(diff(y)<0) # diff(y)<0 when f crosses from (+) to (-)
minus.to.plus <- which(diff(y)>0) # diff(y)>0 when f crosses from (-) to (+)
# first two roots are (+) to (-); third is (-) to (+)
lower <- c(plus.to.minus[1:2],minus.to.plus[3])
roots <- sapply(lower,function(i)uniroot(f,interval=c(x[i],x[i+1]))$root)
lapply(roots,function(x) points(roots,c(0,0,0),col="red",pch=16))
roots
# [1] -67.38961 -41.72593 -10.38446
This code attempts to find x where f(x) changes sign. There are actually two reasons that f(x) could change sign: a root, or an asymptote. In your case there are three roots, and three asymptotes. Success here depends on having a small enough increment in x so that you don't completely miss a crossing. Based in the graph above it looks like 0.001 is small enough.
Here, y is a vector which contains the sign of f (as +1 or -1) at x between -75 and 0, in increments of 0.001. The limits (-75,0) were chosen by inspecting the plot above. We can see visually that there are three roots. The first two cross from (+) to (-), and the third crosses from (-) to (+). So we identify the index of x where the crossings occur (using which(...)), and then create a vector that contains the first two elements of plus.to.minus and the third element of minus.to.plus. Then we call uniroot(...) using increment=c(x[i],x[i+1]) where i is the index of the appropriate crossing.
Finally, we plot the results to confirm that we have in fact found the roots. This is really important - always, always plot the results. It turns out that uniroot(...) will find a "root" where there is an asymptote, so you have to make sure you've found actual roots.
Use uniroot() to solve equations in one variable:
f <- function(x){
1/8 * (1/(12+x)) + 1/4*(1/(40+x)) + 3/4*(1/(50+x)) - 1/20
}
uniroot(f, interval = c(-1e+08, 1e+08))
Notice that in the function, f, I subtract 1/20. This is because uniroot() finds the zero of the function.
In this case, you will get the error:
Error in uniroot(f, interval = c(-1e+08, 1e+08)) :
f() values at end points not of opposite sign
To correct this, you need to make sure the zero exists and if it does, move the interval, (a, b) so that f(a) == -f(b)
I am trying to plot large amounts of points using some library. The points are ordered by time and their values can be considered unpredictable.
My problem at the moment is that the sheer number of points makes the library take too long to render. Many of the points are redundant (that is - they are "on" the same line as defined by a function y = ax + b). Is there a way to detect and remove redundant points in order to speed rendering ?
Thank you for your time.
The following is a variation on the Ramer-Douglas-Peucker algorithm for 1.5d graphs:
Compute the line equation between first and last point
Check all other points to find what is the most distant from the line
If the worst point is below the tolerance you want then output a single segment
Otherwise call recursively considering two sub-arrays, using the worst point as splitter
In python this could be
def simplify(pts, eps):
if len(pts) < 3:
return pts
x0, y0 = pts[0]
x1, y1 = pts[-1]
m = float(y1 - y0) / float(x1 - x0)
q = y0 - m*x0
worst_err = -1
worst_index = -1
for i in xrange(1, len(pts) - 1):
x, y = pts[i]
err = abs(m*x + q - y)
if err > worst_err:
worst_err = err
worst_index = i
if worst_err < eps:
return [(x0, y0), (x1, y1)]
else:
first = simplify(pts[:worst_index+1], eps)
second = simplify(pts[worst_index:], eps)
return first + second[1:]
print simplify([(0,0), (10,10), (20,20), (30,30), (50,0)], 0.1)
The output is [(0, 0), (30, 30), (50, 0)].
About python syntax for arrays that may be non obvious:
x[a:b] is the part of array from index a up to index b (excluded)
x[n:] is the array made using elements of x from index n to the end
x[:n] is the array made using first n elements of x
a+b when a and b are arrays means concatenation
x[-1] is the last element of an array
An example of the results of running this implementation on a graph with 100,000 points with increasing values of eps can be seen here.
I came across this question after I had this very idea. Skip redundant points on plots. I believe I came up with a far better and simpler solution and I'm happy to share as my first proposed solution on SO. I've coded it and it works well for me. It also takes into account the screen scale. There may be 100 points in value between those plot points, but if the user has a chart sized small, they won't see them.
So, iterating through your data/plot loop, before you draw/add your next data point, look at the next value ahead and calculate the change in screen scale (or value, but I think screen scale for the above-mentioned reason is better). Now do the same for the next value ahead (getting these values is just a matter of peeking ahead in your array/collection/list/etc adding the for next step increment (probably 1/2) to the current for value whilst in the loop). If the 2 values are the same (or perhaps very minor change, per your own preference), you can skip this one point in your chart by simply adding 'continue' in the loop, skipping adding the data point as the point lies exactly on the slope between the point before and after it.
Using this method, I reduce a chart from 963 points to 427 for example, with absolutely zero visual change.
I think you might need to perhaps read this a couple of times to understand, but it's far simpler than the other best solution mentioned here, much lighter weight, and has zero visual effect on your plot.
I would probably apply a "least squares" algorithm to obtain a line of best fit. You can then go through your points and downfilter consecutive points that lie close to the line. You only need to plot the outliers, and the points that take the curve back to the line of best fit.
Edit: You may not need to employ "least squares"; if your input is expected to hover around "y=ax+b" as you say, then that's already your line of best fit and you can just use that. :)