R plot of a matrix of complex numbers - r

I have a matrix of complex values.
If I issue the command:
plot(myMatrix)
then it shows on the graphics device a kind of scatterplot, with X-axis labeled Re(myMatrix) and Y-axis with Im(myMatrix). This shows the information I'm looking for, as I can see distinct clusters, that I cannot see with only one column.
My questions are :
I assume there is one point per matrix row. Is it right ?
How is calculated Re(myMatrix) for each row vector ?
It is not Re(myMatrix[1,row]), but seems to be a mix of all values of row vector. I would like to be able to get these values, so to know how to compute them with R.

No, there is one point for each matrix element.
set.seed(42)
mat <- matrix(complex(real = rnorm(16), imaginary = rlnorm(16)), 4)
plot(mat)
points(Re(mat[1,1]), Im(mat[1,1]), col = "red", pch = ".", cex = 5)
Look for the red dot:
You'd get the same plot, if you plotted a vector instead of a matrix, i.e., plot(c(mat)).
This happens because plot.default calls xy.coords and that function contains the following code:
else if (is.complex(x)) {
y <- Im(x)
x <- Re(x)
xlab <- paste0("Re(", ylab, ")")
ylab <- paste0("Im(", ylab, ")")
}
else if (is.matrix(x) || is.data.frame(x)) {
This means, that the fact that input is complex takes priority over it being a matrix.

Related

non-linear 2d object transformation by horizontal axis

How can such a non-linear transformation be done?
here is the code to draw it
my.sin <- function(ve,a,f,p) a*sin(f*ve+p)
s1 <- my.sin(1:100, 15, 0.1, 0.5)
s2 <- my.sin(1:100, 21, 0.2, 1)
s <- s1+s2+10+1:100
par(mfrow=c(1,2),mar=rep(2,4))
plot(s,t="l",main = "input") ; abline(h=seq(10,120,by = 5),col=8)
plot(s*7,t="l",main = "output")
abline(h=cumsum(s)/10*2,col=8)
don't look at the vector, don't look at the values, only look at the horizontal grid, only the grid matters
####UPDATE####
I see that my question is not clear to many people, I apologize for that...
Here are examples of transformations only along the vertical axis, maybe now it will be more clear to you what I want
link Source
#### UPDATE 2 ####
Thanks for your answer, this looks like what I need, but I have a few more questions if I may.
To clarify, I want to explain why I need this, I want to compare vectors with each other that are non-linearly distorted along the horizontal axis .. Maybe there are already ready-made tools for this?
You mentioned that there are many ways to do such non-linear transformations, can you name a few of the best ones in my case?
how to make the function f() more non-linear, so that it consists, for example, not of one sinusoid, but of 10 or more. Тhe figure shows that the distortion is quite simple, it corresponds to one sinusoid
and how to make the function f can be changed with different combinations of sinusoids.
set.seed(126)
par(mar = rep(2, 4),mfrow=c(1,3))
s <- cumsum(rnorm(100))
r <- range(s)
gridlines <- seq(r[1]*2, r[2]*2, by = 0.2)
plot(s, t = "l", main = "input")
abline(h = gridlines, col = 8)
f <- function(x) 2 * sin(x)/2 + x
plot(s, t = "l", main = "input+new greed")
abline(h = f(gridlines), col = 8)
plot(f(s), t = "l", main = "output")
abline(h = f(gridlines), col = 8)
If I understand you correctly, you wish to map the vector s from the regular spacing defined in the first image to the irregular spacing implied by the second plot.
Unfortunately, your mapping is not well-defined, since there is no clear correspondence between the horizontal lines in the first image and the second image. There are in fact an infinite number of ways to map the first space to the second.
We can alter your example a bit to make it a bit more rigorous.
If we start with your function and your data:
my.sin <- function(ve, a, f, p) a * sin(f * ve + p)
s1 <- my.sin(1:100, 15, 0.1, 0.5)
s2 <- my.sin(1:100, 21, 0.2, 1)
s <- s1 + s2 + 10 + 1:100
Let us also create a vector of gridlines that we will draw on the first plot:
gridlines <- seq(10, 120, by = 2.5)
Now we can recreate your first plot:
par(mar = rep(2, 4))
plot(s, t = "l", main = "input")
abline(h = gridlines, col = 8)
Now, suppose we have a function that maps our y axis values to a different value:
f <- function(x) 2 * sin(x/5) + x
If we apply this to our gridlines, we have something similar to your second image:
plot(s, t = "l", main = "input")
abline(h = f(gridlines), col = 8)
Now, what we want to do here is effectively transform our curve so that it is stretched or compressed in such a way that it crosses the gridlines at the same points as the gridlines in the original image. To do this, we simply apply our mapping function to s. We can check the correspondence to the original gridlines by plotting our new curves with a transformed axis :
plot(f(s), t = "l", main = "output", yaxt = "n")
axis(2, at = f(20 * 1:6), labels = 20 * 1:6)
abline(h = f(gridlines), col = 8)
It may be possible to create a mapping function using the cumsum(s)/10 * 2 that you have in your original example, but it is not clear how you want this to correspond to the original y axis values.
Response to edits
It's not clear what you mean by comparing two vectors. If one is a non-linear deformation of the other, then presumably you want to find the underlying function that produces the deformation. It is possible to create a function that applies the deformation empirically simply by doing f <- approxfun(untransformed_vector, transformed_vector).
I didn't say there were many ways of doing non-linear transformations. What I meant is that in your original example, there is no correspondence between the grid lines in the original picture and the second picture, so there is an infinite choice for which gridines in the first picture correspond to which gridlines in the second picture. There is therefore an infinite choice of mapping functions that could be specified.
The function f can be as complicated as you like, but in this scenario it should at least be everywhere non-decreasing, such that any value of the function's output can be mapped back to a single value of its input. For example, function(x) x + sin(x)/4 + cos(3*(x + 2))/5 would be a complex but ever-increasing sinusoidal function.

Understanding l_ply from plyr

From the documentation:
All output is discarded. This is useful for functions that you are calling purely for their side effects like displaying plots or saving output.
I've spent some time playing around and trying to find a suitable use case but haven't(yet).
Looking at the examples hasn't helped me better understand it.
Sample usage:
l_ply(iris[1:5,1], function(x) print(summary(x)))
This will work.
However, under what circumstances might one need to print and then discard these results?
Consider the following
X <- matrix (c (rnorm (50)), ncol = 5);
Assume each colmn of X indicates a series which you want to overplot.
You can do it as following, by first creating an empty plot and then plotting the series corresponding to each column, using lapply. Although lapply will return the values returned by the plot call that we do not want.
plot (NULL, ylim = range (X), xlim = c (1, nrow (X)));
lapply (1:ncol (X), function (i) points (X[,i], type = "o", col = i));
Instead you can use
plot (NULL, ylim = range (X), xlim = c (1, nrow (X)));
l_ply (1:ncol (X), function (i) points (X[,i], type = "o", col = i));
This has the same effect but does not return the values returned by plot. Here, the "side effect" is the plot function plotting on the device.

Plot a frame when encountering empty vectors in R?

Suppose I have three vectors, one empty (here x.y1) and others not empty (here x.y2 and x.y3). My goal is for empty vectors, an empty plot be plotted (just a frame with nothing in it).
Given my plotting plan detailed below, is it possible that before the final plotting by lapply I could have a function that would check if the vector is empty and then lpply just create a frame for plot (e.g., plot.new() ; box()) for the empty vectors to be plotted?
x.y1 = c()
x.y2 = c(2, 3)
x.y3 = c(6, 2)
m = matrix(1:3); layout(m)
plot.names = noquote(paste0("x.y", 1:3))
lapply(plot.names, plot)
# Error: need finite 'ylim' values # Right now I get this error due to the empty vector!
par(mfrow = c(1,3))
lapply(mget(plot.names), function(a)
if(is.null(a)){
plot(0,0, type = "n")
}else{
plot(a)
})

colorRamp returns 0

I'm trying to plot lines and color the lines based on the probability of that connection. Given a vector of probabilities, I use:
colfunc <- colorRamp(c("white", "red"))
colors <- colfunc(probs)
colors is then an nx3 matrix of rgb values. However, colfunc quite often returns a 0 value, so when i attempt to plot using these colors, R complains
Error in col2rgb(colors) : numerical color values must be positive
Is there an error in the way I am defining my color function?
Your function works fine, I think, but it doesn't return colors you can use with plot, because plot wants a color, not RGB values in a matrix.
There's probably a better way, but you can simply covert the matrix:
probs <- runif(10)
colors <- colfunc(probs)
my_col = apply(colors, MARGIN = 1, function(x) rgb(x[1]/255, x[2]/255, x[3]/255))
plot(1:10, 1:10, col = my_col) # should work fine
or you could just wrap your function
better_colfunc <- function(x, ramp = colorRamp(c("white", "red"))) {
colors <- ramp(x)
colors = apply(colors, MARGIN = 1, function(x) rgb(x[1]/255, x[2]/255, x[3]/255))
return(colors)
}
plot(1:10, 1:10, col = better_colfunc(probs, ramp = colfunc))
As for "colfunc quite often returns a 0 value", and other issues, you'll need to share both some data (what do your probs look like?) as well as perhaps the actual plotting code. See here for tips on making reproducible questions.
I am a bit confused what you are trying to do...the col2rgb function returns rgb values, so if you already have those then what do you want?
Or if you want rgb, why not use:
col2rgb(c("white", "red"))

Nested for loops in R - Issue with final result

I am in the midst of solving a problem in Reconstructing (or recovering) a probability distribution function when only the moments of the distribution are known. I have written codes in R for it and although the logic seems right to me, I am not getting the output that I want.
The equation I am trying to using as the approximated (or reconstructed or recovered) CDF is what you see in the image below. I am writing codes for the right hand side of the equation and equating that to a vector that I call F in my codes.
The link to paper that contains the original equation can be found here.
http://www.sciencedirect.com/science/article/pii/S0167715208000187
It is marked as equation (2) in the paper.
Here is the code I wrote.:
#R Codes:
alpha <- 50
T <- 1
x <- seq(0, T, by = 0.1)
# Original CDF equation
Ft <- (1-log(x^3))*(x^3)
plot(x, Ft, type = "l", ylab = "", xlab = "")
# Approximated CDF equation using Moment type reconstruction
k<- floor(alpha*y/T)
for(i in 1:length(k))
{
for(j in k[i]:alpha)
{
F[x+1] <- (factorial(alpha)/(factorial(alpha-j)*factorial(j-k)*factorial(k)))*(((-1)^(j-k))/(T^j))*((9/(j+3))^2)
}
}
plot(x[1:7], F, type = "l", ylab = "", xlab = "")
Any help will be appreciated here because the approximation and the graph obtained using my codes is grossly different from the original curve.
It seems clear that your problem is in here.
F[x+1] <- (factorial(alpha)/(factorial(alpha-j)*factorial(j-k)*factorial(k)))*(((-1)^(j-k))/(T^j))*((9/(j+3))^2)
You are trying to get something varying in x, yes? So how can you get that, if the right hand side of this equation has nothing varying in x, while the left hand side has an assignment using non-integer indices?
alpha <- 30 #In the exemple you try to reproduce, they use an alpha of 30 if i understood correctly (i'm a paleontologist not a mathematician so this paper's way beyond my area of expertise :) )
tau <- 1 #tau is your T (i changed it to avoid confusion with TRUE)
x <- seq(0, tau, by = 0.001)
f<-rep(0,length(x)) #This is your F (same reason as above for the change).
#It has to be created as a vector of 0 before your loop since the whole idea of the loop is that you want to proceed by incrementation.
#You want a value of f for each of your element of x so here is your first loop:
for(i in 1:length(x)){
#Then you want the sum for all k going from 1 to alpha*x[i]/tau:
for(k in 1:floor(alpha*x[i]/tau)){
#And inside that sum, the sum for all j going from k to alpha:
for(j in k:alpha){
#This sum needs to be incremented (hence f[i] on both side)
f[i]<-f[i]+(factorial(alpha)/(factorial(alpha-j)*factorial(j-k)*factorial(k)))*(((-1)^(j-k))/(tau^j))*(9/(j+3)^2)
}
}
}
plot(x, f, type = "l", ylab = "", xlab = "")

Resources