How to plot the function 4(x)^2 = ((y)^2/(1-y))? - scilab

I want to plot the function
4(x)^2 = ((y)^2/(1-y));
how can I plot this?
--> 4*(x) = ((y^2)*(1-y)^-1)^0.5;
4*(x) = ((y^2)*(1-y)^-1)^0.5;
^^
Error: syntax error, unexpected =, expecting end of file

Since Scilab 6.1.0, plotimplicit() does it:
plotimplicit "4*x^2 = y^2/(1-y)"
xgrid()
Can't do more simple. Result:

Well, you have to first create a function and for that you have to express one variable in terms of the other.
function x = f(y)
x = (((y^2)*(1-y)^-1)^0.5)/4;
endfunciton
Then you need to generate the input data (i.e, the points at which you want to evaluate the function)
ydata = linspace(1, 10)
Now you push your input point through the function to get your output points
xdata = f(ydata)
Then, you can plot the pairs of x and y using:
plot(xdata, ydata)
Or even easier, without the intermediate step of generating the output data, you can simply do:
plot(f(ydata), ydata)
BTW. I find it strange that the function you are trying to plot is x in terms of y, usually, x is the input variable, but I hope you know what you are trying to accomplish.
Reference: https://www.scilab.org/tutorials/getting-started/plotting

Take care that y must be in [-inf 1[
y=linspace(-10 ,1.00001,1000);
x = sqrt(y^2./(1-y))/4;
clf; plot(y,x),plot(y,-x)
If x is a solution -x is also solution

Related

Error when using 'which' to find position in a vector in R

Update 2.0: Now with data such that the errors should be reproducible:
Data for the different functions:
z <- seq(0,2,length=1000)
t <- grid <- c(0.1,0.55,0.9)
parA <- c(0.21,-0.93)
parB <- c(0.21,1.008)
p <- c(1,2,1,2)
## for plotting ##
f_func <- function(x) exp(-x^3+x)
envARS1 <- function(x){ exp(parA[1]*x+parB[1])}
envARS2 <- function(x){ exp(parA[2]*x+parB[2])}
plot(x=z,y=envARS1(z), type = "l", col = "blue", ylim = c(0,2), xlim = c(0,2))
lines(x=z,y=envARS2(z), type = "l", col = "red")
lines(x = z,(f_func(z)), type = "l", col = "black")
I'm trying to implement an Adaptive rejection sampler using a derivative-free approach. Along the way of this implementation, I have to implement a dynamic envelope function, which is able to adjust depending on the values/number of some Zt's.
I have accomplished to write a dynamic envelope function which seems to work fine but when I try to integrate the envelope, with the final aim of drawing from this envelope, I get errors.
DynamicEnv <- function(x){
exp(parA[p[max(which(x>=grid))]]*x+
parB[p[max(which(x>=grid))]])
}
The envelope function is a exponential linear line and the parameters a and b depends on where the x, it's input, is located relatively to the Zt's.
The variable 'grid' contains the Zt's and is therefore a vector, p is a dynamic position variable, which essentially tells the function which parameters to use.
So the first problem I had was that, when I gave my dynamic envelope a vector as input, I get troubles with the 'which' function which only can handle numeric values as far as I understand.
Updated with the error I receive from 'which'
I get the below error with which:
Error in which(x > grid) :
dims [product 3] do not match the length of object [1000]
Which I believe occurs because 'which' tries to compare both vectors to each other, and not the n'th element in x with the entire vector of grid.
Then I try to incorporate a loop, to loop over all the values in the x-vector, and return a vector with the output values, but then I got the error message 'non-finite function values' when I tried to integrate my dynamic envelope.
The dynamic envelope with a loop inside is;
DynamicEnv1 <- function(x){
Draws <- matrix(0,length(x),1)
for (i in 1:length(x)) Draws[i,1] <-
exp(parA[p[max(which(x[i]>=grid))]]*x[i] + parB[p[max(which(x[i]>=grid))]])
return(Draws)
}
I have written this 'static' envelope function, which works fine with respect to making draws from it (thereby integrate).
envARSup <- function(x){ (ifelse((x <= t[1] | t[2] < x & x <= t[3]),
exp(parA[1]*x+parB[1]),exp(parA[2]*x+parB[2])))*1*(x>0)}
Here the t's are the Zt's mentioned above. The idea of the dynamic envelope should be clear from this function, since they ideally should be able to return the same for the same grid (Zt's/t's).
The above function checks which interval the value of x belongs to, and based on the interval it uses a specific exponential linear line.
I would really appreciate if someone could suggest an alternative to the 'which' function, in order to locate a position in a vector or help me understand why I get the error message with the loop-based dynamic envelope.

R data.table causes lines() to draw weird stuff

I want to draw a linear regression line y = m*x+b with x coming from a column in a data.table and m and b fixed. When I execute this program:
library(data.table)
dt = data.table(KEY_COLUMN = c("a","c","d","e","b"),
x = c(29.34224, 26.77573, 25.45568, 26.27839, 28.22389)
)
x = dt$x
m = -0.1211562
b = 63.09729
plot(c(25,30), c(58,61))
lines(x, m*x + b, col="red")
setkeyv(dt, "KEY_COLUMN")
then I get this weird picture:
which cannot be the true picture of the data because hey, I'm drawing a line y = mx+b!
Even more awkwardly, when removing the command setkeyv(dt, "KEY_COLUMN") which takes place BEHIND the line drawing, then everything wirks and I get a line. And if that is not enought: when leaving the 'bad' command setkeyv(dt, "KEY_COLUMN") there but inserting a browser() right after the lines command then everything works as expected and I get a line...
This is a 'quantum' error: whenever you want to see the error, it goes away... only in the situation where you cannot really observe the error, it is there. Am I stupid/overlooking something really simple here or what is going on?
Cheers,
FW
As you know, data.table modifies by reference. I can reproduce this when I source the code all at once. If I source it line by line I get the expected result. Thus, I assume that this happens:
The first parameter to lines is a reference (pointer) to x which is a reference to the x column of the data.table. Since it is never modified, it is never actually copied and stays a reference. The second parameter to lines is not a reference, since the expression gets evaluated and results in a new (independent) variable.
Now, plotting is slow and the last line of code is evaluated (and the key is set) before the C code for plotting has actually produced the plot. This orders the data.table in memory and x is still only a reference to it. The lines are produced based on the reordered x data.
I can get the expected result if I force a copy:
library(data.table)
dt = data.table(KEY_COLUMN = c("a","c","d","e","b"),
x = c(29.34224, 26.77573, 25.45568, 26.27839, 28.22389)
)
x = copy(dt$x)
#alternatively modifying x works: x[1] <- x[1]
m = -0.1211562
b = 63.09729
plot(c(25,30), c(58,61))
lines(x, m*x + b, col="red")
setkeyv(dt, "KEY_COLUMN")

How does the curve function in R work? - Example of curve function

How does the following code work? I got the example when I was reading the help line of R ?curve. But i have not understood this.
for(ll in c("", "x", "y", "xy"))
curve(log(1+x), 1, 100, log = ll,
sub = paste("log= '", ll, "'", sep = ""))
Particularly , I am accustomed to numeric values as arguments inside the for-loop as,
for(ll in 1:10)
But what is the following command saying:
for(ll in c("","x","y","xy"))
c("","x","y","xy") looks like a string vector? How does c("","x","y","xy") work inside curve
function as log(1+x)[what is x here? the string "x"? in c("","x","y","xy")] and log=ll ?
Apparently, there are no answers on stack overflow about how the curve function in R works and especially about the log argument so this might be a good chance to delve into it a bit more (I liked the question btw):
First of all the easy part:
c("","x","y","xy") is a string vector or more formally a character vector.
for(ll in c("","x","y","xy")) will start a loop of 4 iterations and each time ll will be '','x','y','xy' respectively. Unfortunately, the way this example is built you will only see the last one plotted which is for ll = 'xy'.
Let's dive into the source code of the curve function to answer the rest:
First of all the what does the x represent in log(1+x)?
log(1+x) is a function. x represents a vector of numbers that gets created inside the curve function in the following part (from source code):
x <- exp(seq.int(log(from), log(to), length.out = n)) #if the log argument is 'x' or
x <- seq.int(from, to, length.out = n) #if the log argument is not 'x'
#in our case from and to are 1 and 100 respectively
As long as the n argument is the default the x vector will contain 101 elements. Obviously the x in log(1+x) is totally different to the 'x' in the log argument.
as for y it is always created as (from source code):
y <- eval(expr, envir = ll, enclos = parent.frame()) #where expr is in this case log(1+x), the others are not important to analyse now.
#i.e. you get a y value for each x value on the x vector which was calculated just previously
Second, what is the purpose of the log argument?
The log argument decides which of the x or y axis will be logged. The x-axis if 'x' is the log argument, y-axis if 'y' is the log argument, both axis if 'xy' is the log argument and no log-scale if the log argument is ''.
It needs to be mentioned here that the log of either x or y axis is being calculated in the plot function in the curve function, that is the curve function is only a wrapper for the plot function.
Having said the above this is why if the log argument is 'x' (see above) the exponential of the log values of the vector x are calculated so that they will return to the logged ones inside the plot function.
P.S. the source code for the curve function can be seen with typing graphics::curve on the console.
I hope this makes a bit of sense now!

Graphing a polynomial output of calc.poly

I apologize first for bringing what I imagine to be a ridiculously simple problem here, but I have been unable to glean from the help file for package 'polynom' how to solve this problem. For one out of several years, I have two vectors of x (d for day of year) and y (e for an index of egg production) data:
d=c(169,176,183,190,197,204,211,218,225,232,239,246)
e=c(0,0,0.006839425,0.027323127,0.024666883,0.005603878,0.016599262,0.002810977,0.00560387 8,0,0.002810977,0.002810977)
I want to, for each year, use the poly.calc function to create a polynomial function that I can use to interpolate the timing of maximum egg production. I want then to superimpose the function on a plot of the data. To begin, I have no problem with the poly.calc function:
egg1996<-poly.calc(d,e)
egg1996
3216904000 - 173356400*x + 4239900*x^2 - 62124.17*x^3 + 605.9178*x^4 - 4.13053*x^5 +
0.02008226*x^6 - 6.963636e-05*x^7 + 1.687736e-07*x^8
I can then simply
plot(d,e)
But when I try to use the lines function to superimpose the function on the plot, I get confused. The help file states that the output of poly.calc is an object of class polynomial, and so I assume that "egg1996" will be the "x" in:
lines(x, len = 100, xlim = NULL, ylim = NULL, ...)
But I cannot seem to, based on the example listed:
lines (poly.calc( 2:4), lty = 2)
Or based on the arguments:
x an object of class "polynomial".
len size of vector at which evaluations are to be made.
xlim, ylim the range of x and y values with sensible defaults
Come up with a command that successfully graphs the polynomial "egg1996" onto the raw data.
I understand that this question is beneath you folks, but I would be very grateful for a little help. Many thanks.
I don't work with the polynom package, but the resultant data set is on a completely different scale (both X & Y axes) than the first plot() call. If you don't mind having it in two separate panels, this provides both plots for comparison:
library(polynom)
d <- c(169,176,183,190,197,204,211,218,225,232,239,246)
e <- c(0,0,0.006839425,0.027323127,0.024666883,0.005603878,
0.016599262,0.002810977,0.005603878,0,0.002810977,0.002810977)
egg1996 <- poly.calc(d,e)
par(mfrow=c(1,2))
plot(d, e)
plot(egg1996)

How to draw lines on a plot in R?

I need to draw lines from the data stored in a text file.
So far I am able only to draw points on a graph and i would like to have them as lines (line graph).
Here's the code:
pupil_data <- read.table("C:/a1t_left_test.dat", header=T, sep="\t")
max_y <- max(pupil_data$PupilLeft)
plot(NA,NA,xlim=c(0,length(pupil_data$PupilLeft)), ylim=c(2,max_y));
for (i in 1:(length(pupil_data$PupilLeft) - 1))
{
points(i, y = pupil_data$PupilLeft[i], type = "o", col = "red", cex = 0.5, lwd = 2.0)
}
Please help me change this line of code:
points(i, y = pupil_data$PupilLeft[i], type = "o", col = "red")
to draw lines from the data.
Here is the data in the file:
PupilLeft
3.553479
3.539469
3.527239
3.613131
3.649437
3.632779
3.614373
3.605981
3.595985
3.630766
3.590724
3.626535
3.62386
3.619688
3.595711
3.627841
3.623596
3.650569
3.64876
By default, R will plot a single vector as the y coordinates, and use a sequence for the x coordinates. So to make the plot you are after, all you need is:
plot(pupil_data$PupilLeft, type = "o")
You haven't provided any example data, but you can see this with the built-in iris data set:
plot(iris[,1], type = "o")
This does in fact plot the points as lines. If you are actually getting points without lines, you'll need to provide a working example with your data to figure out why.
EDIT:
Your original code doesn't work because of the loop. You are in effect asking R to plot a line connecting a single point to itself each time through the loop. The next time through the loop R doesn't know that there are other points that you want connected; if it did, this would break the intended use of points, which is to add points/lines to an existing plot.
Of course, the line connecting a point to itself doesn't really make sense, and so it isn't plotted (or is plotted too small to see, same result).
Your example is most easily done without a loop:
PupilLeft <- c(3.553479 ,3.539469 ,3.527239 ,3.613131 ,3.649437 ,3.632779 ,3.614373
,3.605981 ,3.595985 ,3.630766 ,3.590724 ,3.626535 ,3.62386 ,3.619688
,3.595711 ,3.627841 ,3.623596 ,3.650569 ,3.64876)
plot(PupilLeft, type = 'o')
If you really do need to use a loop, then the coding becomes more involved. One approach would be to use a closure:
makeaddpoint <- function(firstpoint){
## firstpoint is the y value of the first point in the series
lastpt <- firstpoint
lastptind <- 1
addpoint <- function(nextpt, ...){
pts <- rbind(c(lastptind, lastpt), c(lastptind + 1, nextpt))
points(pts, ... )
lastpt <<- nextpt
lastptind <<- lastptind + 1
}
return(addpoint)
}
myaddpoint <- makeaddpoint(PupilLeft[1])
plot(NA,NA,xlim=c(0,length(PupilLeft)), ylim=c(2,max(PupilLeft)))
for (i in 2:(length(PupilLeft)))
{
myaddpoint(PupilLeft[i], type = "o")
}
You can then wrap the myaddpoint call in the for loop with whatever testing you need to decide whether or not you will actually plot that point. The function returned by makeaddpoint will keep track of the plot indexing for you.
This is normal programming for Lisp-like languages. If you find it confusing you can do this without a closure, but you'll need to handle incrementing the index and storing the previous point value 'manually' in your loop.
There is a strong aversion among experienced R coders to using for-loops when not really needed. This is an example of a loop-less use of a vectorized function named segments that takes 4 vectors as arguments: x0,y0, x1,y1
npups <-length(pupil_data$PupilLeft)
segments(1:(npups-1), pupil_data$PupilLeft[-npups], # the starting points
2:npups, pupil_data$PupilLeft[-1] ) # the ending points

Resources