2017-08-31 78 views
0

(增加重复的例子)R中的类型保留(复数,实数)平方根?

sqrt(as.complex(c(4,9,-4,-9,16))) # 2+0i 3+0i 0+2i 0+3i 4+0i 
class(sqrt(as.complex(c(4,9,-4,-9,16)))) # complex 
sqrt(as.complex(c(4,9,-4,-9,16)))[1] # 2+0i 
class(sqrt(as.complex(c(4,9,-4,-9,16)))[1]) # complex 

所以,我想定义一个特定的平方根函数(sqrtT),将保持其元素的真实性/ complexness。因此,实际上,我想这一点:

sqrtT(as.complex(c(4,9,-4,-9,16))) # 2 3 0+2i 0+3i 4 
class(sqrtT(as.complex(c(4,9,-4,-9,16)))) # complex 
sqrtT(as.complex(c(4,9,-4,-9,16)))[1] # 2 
class(sqrtT(as.complex(c(4,9,-4,-9,16)))[1]) # numeric 
class(sqrtT(as.complex(c(4,9,-4,-9,16)))[3]) # complex 

我所做的:
我发现这些工具:

Re(sqrt(as.complex(c(4,9,-4,-9,16)))) # 2 3 0 0 4 
Im(sqrt(as.complex(c(4,9,-4,-9,16)))) # 0 0 2 3 0 

顺便说一句,它必须持有型本身,也就是说,当我说,sqrtT(as.complex(c(4,9,-4,-9,16))) #= 2 3 0+2i 0+3i 4,显示这个输出(2 3 0+2i 0+3i 4),虽然实质上所有这些都不是我想要的。我的问题不仅仅是显示目的。

2.有区分载体中的元素的含量的方式:

is.numeric(0+2i) # FALSE 
is.numeric(2) # TRUE 

3.与该指数虚部非等于0且等于0:

让向量是v。

v <- c(-1,4,9,-4,-9,0,16) 
# The indices with imaginary part non-equal to 0 (IM<>0): 
IMneq0 <- setdiff(which(as.numeric(sqrt(as.complex(v))) %in% 0),which(sqrt(as.complex(v))==0)) 
IMneq0 # 1,4,5 

# The indices with imaginary part equal to 0 (IM=0): 
IMeq0 <- setdiff(1:length(sqrt(as.complex(v))),IMneq0) 
IMeq0 # 2 3 6 7 

自动强制到复杂的可以通过通通过使用列表编辑。

有什么想法?

+0

我不认为这是可能的。矢量中的所有元素都具有相同的模式。 – mt1022

+0

@ mt1022,有一种方法可以区分矢量元素的类型,从而将它们的模式分开。请参阅相关修改。 –

+3

它们不在同一个向量中。相同矢量中的元素将始终被强制为相同的模式。 'x < - c(2,0 + 2i); typeof(x [1]):“complex”' – mt1022

回答

0

(坏的伪解决方案)

v <- c(-1,4,9,-4,-9,0,16) 

sqrtTP <- function(v) { # Type preserving square root 
IMne0 <- setdiff(which(as.numeric(sqrt(as.complex(v))) %in% 0),which(sqrt(as.complex(v))==0)) #indices with imaginary part <> 0 
IM0 <- setdiff(1:length(sqrt(as.complex(v))),IMne0) #indices with imaginary part =0 
ValuesIM0 <- as.numeric(sqrt(as.complex(v[IM0]))) # values where IM=0 
ValuesIMne0 <- sqrt(as.complex(v[IMne0])) # values where IM<>0 
out <- list() 
CounterIM0 <- 1 # counter where IM=0 coincided 
CounterIMne0 <- 1 # counter where IM<>0 coincided 

for (i in as.integer(1:length(v))) { 

if (i %in% IM0) { 
out[[i]] <- ValuesIM0[CounterIM0] 
CounterIM0 <- CounterIM0 +1 
} else { 
out[[i]] <- ValuesIMne0[CounterIMne0] 
CounterIMne0 <- CounterIMne0 +1 
} 
} 
out 
} 

sqrtTP(v) 
# 0+1i 2 3 0+2i 0+3i 0 4 (given as list elements)