Операция логического вектора в стиле R в Nim - PullRequest
0 голосов
/ 31 октября 2018

Кто-нибудь знает, есть ли в Nim функция типа ifelse в R, которая позволяет применять условные вычисления к векторам, эквивалентные:

a<-c(1,2,3,4)
b<-c(7,2,7,4)
c<-ifelse(a==b,a*b,a+b)

использование цикла и оператора if, else будет слишком медленным для больших векторов.

1 Ответ

0 голосов
/ 04 ноября 2018

Хорошо, так. В Nim Tuple использует ту же идею, что и вектор в R: структурная типизация . Надеюсь, я на правильном пути. Nim имеет возможность делать вещи во время компиляции, а не во время выполнения, поэтому функции, встроенные для Tuples, такие как ==, имеют цикл в своем исходном коде, но на самом деле цикл разворачивается во время компиляции, и на поля ссылаются непосредственно во время выполнения. Так что для скорости Tuple == Tuple будет настолько быстрым, насколько это возможно, независимо от количества полей в Tuple. Это можно проверить с помощью исходного кода .

Я уверен, что вы можете сделать именно то, что вы просите, проверив, что эта маленькая функция, которую я написал, работает, поскольку * не была встроена для кортежей:

let
  v1 = (1,2,3,4)
  v2 = (7,2,7,4)

proc `*`[T:tuple](x, y: T): T =
  for a,b in fields(x, result):
    b = a
  for a,b in fields(y, result):
    b = b * a

echo $(v1 * v2) #prints (Field0: 7, Field1: 4, Field2: 21, Field3: 16)

Мы могли бы написать ту же функцию для сложения:

let
  v1 = (1,2,3,4)
  v2 = (7,2,7,4)

proc `+`[T:tuple](x, y: T): T =
  for a,b in fields(x, result):
    b = a
  for a,b in fields(y, result):
    b = b + a

echo $(v1 + v2)

Вот полный пример, который представляет собой комбинацию forum convo и функций выше:

proc `+`[T:tuple](x, y: T): T =
  for a,b in fields(x, result):
    b = a
  for a,b in fields(y, result):
    b = b + a

proc `*`[T:tuple](x, y: T): T =
  for a,b in fields(x, result):
    b = a
  for a,b in fields(y, result):
    b = b * a

let
  a = (1,2,3,4)
  b = (7,2,7,4)
  c = if v1 == v2: v1 * v2 else: v1 + v2

Надеюсь, это поможет!

...