2
votes

Itérer (/) une fonction multivalente

Comment itérez-vous une fonction de rang multivalent (> 1), par exemple f: {[x; y] ...} où les entrées de fonction dans la prochaine étape d'itération dépendent de la dernière étape d'itération? Les exemples du le manuel de référence n'itèrent que des fonctions unaires.

J'ai pu y parvenir indirectement (et verbalement) en passant un dictionnaire d'arguments (état) en fonction unaire:

f:{[arg] key[arg]!(min arg;arg[`y]-2)}                                                          
f/[{0<x`x};`x`y!6 3]

Notez que projection, par exemple f [x;] / [whilecond; y] ne fonctionnerait que dans le scénario où le x de l'étape d'itération suivante pas em > dépend du résultat de la dernière itération (c'est-à-dire lorsque x est indépendant du chemin).

kdb

0 commentaires

3 Réponses :


1
votes

La fonction qui est utilisée avec '/' et '\' ne peut accepter le résultat de la dernière itération que comme un élément unique, ce qui signifie qu'un seul paramètre de fonction est réservé pour le résultat. C'est unaire dans ce sens.

Pour les fonctions dont les multiples paramètres d'entrée dépendent du résultat de la dernière itération, une solution consiste à envelopper cette fonction dans une fonction unaire et à utiliser l'opérateur apply pour exécuter cette fonction sur le résultat de la dernière itération.

Ex:

      q) g:{(min x,y;y-2)}  / function with rank 2
      q) f:{x . y}[g;]   / function g wrapped inside unary function to iterate
      q) f/[{0<x 0};6 3]


0 commentaires

2
votes

En ce qui concerne la réponse de Rahul, vous pouvez utiliser l'une des méthodes suivantes (légèrement moins verbeuses) pour obtenir le même résultat:

q)g:{[x;y] x: min x,y; y:y-2; $[x<0; (x;y); .z.s[x;y]]}
q)g[6;3]
-1 -3

Vous pouvez également utiliser la fonction self .zs, qui appelle récursivement la fonction g et prend la sortie de la dernière itération comme arguments. Par exemple,

q)g:{(min x,y;y-2)}
q)(g .)/[{0<x 0};6 3]
-1 -3
q).[g]/[{0<x 0};6 3]
-1 -3


0 commentaires

0
votes

Au fil du temps, je suis tombé sur un chemin encore plus court qui ne nécessite pas de parenthèses ou de crochets:

q)(*) . 2 3
6
q)(*/) 2 3
6

Pourquoi double sur ( // code >) travailler? L'adverbe / peut parfois être utilisé à la place de l'opérateur . ( apply ):

q)g:{(min x,y;y-2)}
q){0<x 0} g//6 3
-1 -3


0 commentaires