Сохраняющий тип (комплексный, действительный) квадратный корень в 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), которая сохранит реалистичность / сложность своих элементов. По сути, я хочу это:

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

Что я сделал:
Я нашел следующие инструменты:
1.

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

Автоматическое принуждение к комплексу можно обойти с помощью списков.

Любая идея?


person Erdogan CEVHER    schedule 31.08.2017    source источник
comment
Я не думаю, что это возможно. Все элементы в векторе имеют одинаковый режим.   -  person mt1022    schedule 31.08.2017
comment
@ mt1022, есть способ различать типы элементов вектора, тем самым разделяя их моды. См. Рассматриваемое изменение.   -  person Erdogan CEVHER    schedule 31.08.2017
comment
Они не находятся в одном векторе. Элементы в одном и том же векторе всегда будут принудительно переведены в один и тот же режим. x <- c(2, 0+2i); typeof(x[1]): "complex"   -  person mt1022    schedule 31.08.2017
comment
@ mt1022, поэтому нам, возможно, придется использовать два разных вектора, содержащих разные типизированные элементы. Я нашел smt и добавил в вопрос.   -  person Erdogan CEVHER    schedule 31.08.2017


Ответы (1)


(плохое псевдорешение)

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)
person Erdogan CEVHER    schedule 31.08.2017