I am trying to plot a regression line which is modelled by p/(1-p) = -41.828+0.9864x, where p is the probability of an event, dependent on x. I only need to plot this using julia, so that the general trend is clear. I have rearranged the model to be p=1/(exp(41.828-0.9864x)+1), however, whenever I plot this using julia, it returns an error. I have attached my code below, and the subsequent error. Have tried all manner of things that I can think of to get around the error, but am unable to... Any help would be appreciated! Apologies for any formatting mistakes I've made, first time using this site, but I tried to do as asked.
using PyPlot , Distributions , StatsBase, DataFrames
xlin = float(linspace(-50.0,50,1000)); y=1.0/float(exp(41.828-0.9864*
(float(xlin)))+1.0)
PyPlot.plot(xlin, y, color="red", linewidth=2.0, linestyle="--")
title("Regression Line Plot");
PyPlot.grid(-25:7:125);
ylabel("Y");
xlabel("X");
This returns the error:
MethodError: no method matching /(::Float64, ::Array{Float64,1})
Closest candidates are:
/(::Float64, ::Float64) at float.jl:246
/(::PyCall.PyObject, ::Any) at
/home/juser/.julia/v0.5/PyCall/src/PyCall.jl:702
/(::Real, ::Complex{T<:Real}) at complex.jl:182
...
It has nothing to do with the plot command. The error is in this line:
y=1.0/float(exp(41.828-0.9864*(float(xlin)))+1.0)
You need ./ rather than /, as you are trying to do an element-wise operation. Also, no reason to call float all the time.
So just
y = 1.0 ./ exp(41.828 .- 0.9864 .* xlin) .+ 1.0
should do it. You don't need all the dots for those operations where one of the operands is a scalar, but you do for the initial division, and it makes it clearer IMHO what is going on.
Related
I'm trying to solve for the x-coordinates of the critical points of the function A(b) in WxMaxima (the GUI for Maxima), but it refuses to give a numerical solution. When I take the derivative, it leaves terms like d/db(1/2 * x) inside instead of evaluating them. How do I get Maxima to solve for all x-coordinates where the derivative of A(x) is equal to 0? Here is a minimal (pun intended) example of what I'm trying to do:
I'm trying to use the Isomap algorithm from the ManifoldLearning.jl package (https://github.com/wildart/ManifoldLearning.jl). However, following the usage example provided in the docs (http://manifoldlearningjl.readthedocs.org/en/latest/isomap.html), throws the below error:
ERROR: LoadError: ArgumentError: collection must be non-empty
in extrema at reduce.jl:337
in classical_mds at /Users/rprechelt/.julia/v0.4/MultivariateStats/src/cmds.jl:75
in transform at /Users/rprechelt/.julia/v0.4/ManifoldLearning/src/isomap.jl:75
in isomap at /Users/rprechelt/code/julia/subwoofer.jl:198
where line 198 is transform(Isomap, X; k=12, d=2) where X is a non-empty (verified using isempty) array where each column is a data sample.
I've tried to trace the error back from reduce.jl but I can't seem to locate where collection is becoming non-empty. The same array (X) works perfectly with LTSA, and other algorithms from the ManifoldLearning.jl package, just not Isomap.
Has anyone encountered this before? Any recommendations?
Isomap invokes classical multidimensional scaling on geodesic distance matrix constructed from an original data. Commonly, MDS algorithm performs an spectral decomposition to find a proper embedding. From the above error, it looks that the decomposition returns an empty spectrum of a geodesic distance matrix. In any case, it is better to open an error issue with the package project on GitHub for a further investigation.
One thing that sometimes happens is that if your points are, for example, exactly on a line, then a matrix created by MDS is rank 1, and depending on the implementation, this may cause errors if you are searching for an Isomap embedding of more than 1 direction.
Dirty hack fix: add a small amount of random noise to all your input points (i think to all the elements of your array X).
I have a function f(x,y) whose outcome is random (I take mean from 20 random numbers depending on x and y). I see no way to modify this function to make it symbolic.
And when I run
x,y = var('x,y')
d = plot_vector_field((f(x),x), (x,0,1), (y,0,1))
it says it can't cast symbolic expression to real or rationa number. In fact it stops when I write:
a=matrix(RR,1,N)
a[0]=x
What is the way to change this variable to real numbers in the beginning, compute f(x) and draw a vector field? Or just draw a lot of arrows with slope (f(x),x)?
I can create something sort of like yours, though with no errors. At least it doesn't do what you want.
def f(m,n):
return m*randint(100,200)-n*randint(100,200)
var('x,y')
plot_vector_field((f(x,y),f(y,x)),(x,0,1),(y,0,1))
The reason is because Python functions immediately evaluate - in this case, f(x,y) was 161*x - 114*y, though that will change with each invocation.
My suspicion is that your problem is similar, the immediate evaluation of the Python function once and for all. Instead, try lambda functions. They are annoying but very useful in this case.
var('x,y')
plot_vector_field((lambda x,y: f(x,y), lambda x,y: f(y,x)),(x,0,1),(y,0,1))
Wow, I now I have to find an excuse to show off this picture, cool stuff. I hope your error ends up being very similar.
I was trying to learn Scipy, using it for mixed integrations and differentiations, but at the very initial step I encountered the following problems.
For numerical differentiation, it seems that the only Scipy function that works for callable functions is scipy.derivative() if I'm right!? However, I couldn't work with it:
1st) when I am not going to specify the point at which the differentiation is to be taken, e.g. when the differentiation is under an integral so that it is the integral that should assign the numerical values to its integrand's variable, not me. As a simple example I tried this code in Sage's notebook:
import scipy as sp
from scipy import integrate, derivative
var('y')
f=lambda x: 10^10*sin(x)
g=lambda x,y: f(x+y^2)
I=integrate.quad( sp.derivative(f(y),y, dx=0.00001, n=1, order=7) , 0, pi)[0]; show(I)
show( integral(diff(f(y),y),y,0,1).n() )
also it gives the warning that "Warning: The occurrence of roundoff error is detected, which prevents the requested tolerance from being achieved. The error may be underestimated." and I don't know what does this warning stand for as it persists even with increasing "dx" and decreasing the "order".
2nd) when I want to find the derivative of a multivariable function like g(x,y) in the above example and something like sp.derivative(g(x,y),(x,0.5), dx=0.01, n=1, order=3) gives error, as is easily expected.
Looking forward to hearing from you about how to resolve the above cited problems with numerical differentiation.
Best Regards
There are some strange problems with your code that suggest you need to brush up on some python! I don't know how you even made these definitions in python since they are not legal syntax.
First, I think you are using an older version of scipy. In recent versions (at least from 0.12+) you need from scipy.misc import derivative. derivative is not in the scipy global namespace.
Second, var is not defined, although it is not necessary anyway (I think you meant to import sympy first and use sympy.var('y')). sin has also not been imported from math (or numpy, if you prefer). show is not a valid function in sympy or scipy.
^ is not the power operator in python. You meant **
You seem to be mixing up the idea of symbolic and numeric calculus operations here. scipy won't numerically differentiate an expression involving a symbolic object -- the second argument to derivative is supposed to be the point at which you wish to take the derivative (i.e. a number). As you say you are trying to do numeric differentiation, I'll resolve the issue for that purpose.
from scipy import integrate
from scipy.misc import derivative
from math import *
f = lambda x: 10**10*sin(x)
df = lambda x: derivative(f, x, dx=0.00001, n=1, order=7)
I = integrate.quad( df, 0, pi)[0]
Now, this last expression generates the warning you mentioned, and the value returned is not very close to zero at -0.0731642869874073 in absolute terms, although that's not bad relative to the scale of f. You have to appreciate the issues of roundoff error in finite differencing. Your function f varies on your interval between 0 and 10^10! It probably seems paradoxical, but making the dx value for differentiation too small can actually magnify roundoff error and cause numerical instability. See the second graph here ("Example showing the difficulty of choosing h due to both rounding error and formula error") for an explanation: http://en.wikipedia.org/wiki/Numerical_differentiation
In fact, in this case, you need to increase it, say to 0.001: df = lambda x: derivative(f, x, dx=0.001, n=1, order=7)
Then, you can integrate safely, with no terrible roundoff.
I=integrate.quad( df, 0, pi)[0]
I don't recommend throwing away the second return value from quad. It's an important verification of what happened, as it is "an estimate of the absolute error in the result". In this case, I == 0.0012846582250212652 and the abs error is ~ 0.00022, which is not bad (the interval that implies still does not include zero). Maybe some more fiddling with the dx and absolute tolerances for quad will get you an even better solution, but hopefully you get the idea.
For your second problem, you simply need to create a proper scalar function (call it gx) that represents g(x,y) along y=0.5 (this is called Currying in computer science).
g = lambda x, y: f(x+y**2)
gx = lambda x: g(x, 0.5)
derivative(gx, 0.2, dx=0.01, n=1, order=3)
gives you a value of the derivative at x=0.2. Naturally, the value is huge given the scale of f. You can integrate using quad like I showed you above.
If you want to be able to differentiate g itself, you need a different numerical differentiation functio. I don't think scipy or numpy support this, although you could hack together a central difference calculation by making a 2D fine mesh (size dx) and using numpy.gradient. There are probably other library solutions that I'm not aware of, but I know my PyDSTool software contains a function diff that will do that (if you rewrite g to take one array argument instead). It uses Ridder's method and is inspired from the Numerical Recipes pseudocode.
What is the usual method or algorithm used to plot implicit equations of 2 variables?
I am talking about equations such as,
sin(x*y)*y = 20
x*x - y*y = 1
Etc.
Does anyone know how Maple or Matlab do this? My target language is C#.
Many thanks!
One way to do this is to sample the function on a regular, 2D grid. Then you can run an algorithm like marching squares on the resulting 2D grid to draw iso-contours.
In a related question, someone also linked to the gnuplot source code. It's fairly complex, but might be worth going through. You can find it here: http://www.gnuplot.info/
Iterate the value of x across the range you want to plot. For each fixed value of x, solve the equation numerically using a method such as interval bisection or the Newton-Raphson method (for which you can calculate the derivative using implicit differentiation, or perhaps differentiate numerically). This will give you the corresponding value of y for a given x. In most cases, you won't need too many iterations to get a very precise result, and it's very efficient anyway.
Note that you will need to transform the equation into the form f(x) = 0, though this is always trivial. The nice thing about this method is that it works just as well the other way round (i.e. taking a fixed range of y and computing x per value).
There're multiple methods. The easiest algorithm I could find is descripted here:
https://homepages.warwick.ac.uk/staff/David.Tall/pdfs/dot1986b-implicit-fns.pdf and describes what Noldorin has described you.
The most complex one, and seems to be the one that can actually solve a lot of special cases is described here:
https://academic.oup.com/comjnl/article/33/5/402/480353
i think,
in matlab you give array as input for x.
then for every x, it calculates y.
then draws line from x0,y0 to x1, y1
then draws line from x1,y1 to x2, y2
...
...