Yacas

Calcolo numerico e simbolico

Yacas (Yet Another Computer Algebra System) è un computer algebra system (CAS) multipiattaforma, sviluppato a partire dall’inizio del 1999 in LISP da Ayal Pinkus, per il calcolo simbolico, algebrico e numerico con precisione arbitraria. Yacas è dotato di un linguaggio di scripting piuttosto evoluto con una ricca libreria di funzioni  ed aperto alle implementazioni.

Yacas è primariamente un sistema per il calcolo simbolic0, la risposta al comando ArcTan(1) è Pi/4, per avere il valore numerico, occorre usare la funzione N:  N(ArcTan(1)) oppure N(%) dove % indica il risultato dell’ultima operazione effettuata. Le formule immesse sono semplificate raggruppando i fattori uguali: si immette x*x^2 e si ottiene x^3, esistono diverse funzioni per semplificazioni più spinte come ad esempio:

In> Simplify((x+1)*(x-1))

Out> x^2-1

L’assegnazione è attuata con := o Set(variable, espressione), sono accettati gli operatori ++ e -- ma solamente postfissi; le istruzioni di controllo sono if come funzione ternaria, while e repeat.

Yacas  gestisce una struttura polimorfa, le liste, che di volta in volta possono essere vettori, stack, o insiemi; naturalmente per ognuno di questi aspetti sono disponibili opportune (molte) funzioni.

Limiti

Limit(x,0)Sin(x)/x

1

Semplificazione

Sin(ArcSin(x))

x

Manipolazione

Expand((1+x)^5);

x^5+5*x^4+10*x^3+10*x^2+5*x+1

Integrazione

Integrate(x,a,b)x^2

b^3/3-a^3/3

 

Integrate(x,0,5) x^2

125/3

 

N(Integrate(x,0,5) x^2)

41.6666666666

Risoluzione

Solve(x^2-2*x+1 == 0,x)

{x==1,x==1}

Calcolo proposizionale

CanProve((piove => bagnato) And piove)

bagnato And piove

Yacas ha, fra l'altro,  funzioni per il calcolo combinatorio, il trattamento delle Serie numeriche, per provare teoremi di logica proposizionale, funzioni per le matrici (algebra lineare), risoluzioni di equazioni differenziali. I legami del linguaggio con il LISP sono testimoniati da alcune funzioni, quali LispRead() per acquisire espressioni nel formato LISP o FullForm(espressione) per trasformare espressione in un formato LISP. Yacas accetta formule in OpenMath, un protocollo basato su XML.

Yacas ha aspetti di linguaggio funzionale, quale la possibilità di scrivere funzioni sotto forma di regole o casi con una sintassi meno elegante di altri linguaggi (ad esempio di Haskell)  :

RuleBase("funzione",{parametri});

Rule("funzione", numero_param, priorità, condizione) corpo {valori restituiti};

RuleBase definisce la funzione ed il nome dei parametri, Rule contiene contiene le istruzioni da eseguire quando la condizione è verificata. Le Rules sono applicate in ordine di priorità crescente, numero_param indica quanti parametri la Rule utilizza, di fatto funzione può essere polimorfica.

Le  funzioni possono anche essere scritte con  differenti forme sintattiche alternative:

AreaCerchio(_r) <-- r*r*Pi;

AreaSfera(r) := 4*r^2*Pi;

Function ("VolumeSfera",{r}) (4/3)*Pi*r^3;

Function("Sigma",{a, ...}) [s:=0;ForEach(i, a) s:=s+i;s;];

Si noti l’utilizzo di ... per indicare un numero di parametri variabile e la restituzione dell’ultimo valore calcolato nel corpo della funzione.

Le possibilità di input output sono complete e comprendono anche la creazione di grafici delle funzioni, visualizzabili, tuttavia, con strumenti esterni. Yacas è utilizzato da Euler per estenderne le capacità di calcolo e può operare come server FTP per eseguire elaborazioni in remoto.

Nell’esempio che segue la verifica della congettura di GoldBach[1] e il Bubbole sort di un vectore.

// This is Yacas version '1.0.55'.
// verify Goldbach's conjecture
RuleBase("GoldBach",{n}); 
Rule("GoldBach", 1, 10, n=4) {n, 2,2};
Rule("GoldBach", 1, 20, n<4 Or IsOdd(n)) {n,Undefined};
Rule("GoldBach", 1, 30, n>=4) 
  [For (i:= 3, Not IsPrime(i) Or Not IsPrime(n-i), i:=i+2)[]; {n,i,n-i};]; 
// (semi) recursive (semi) functional Bubble Sort
BubbleSort(_lst)<--[For (i:=Length(lst),i>1,i--) 
                        [lst:=Concat(BS(Take(lst,i)),Take(lst,-Length(lst)+i));]; 
                        lst;];                                       
RuleBase("BS",{vect});
Rule("BS", 1, 10, Length(vect) < 2) {Head(vect)};
Rule("BS", 1, 20, Length(vect) > 1)
    [If (Head(vect) > Head(Tail(vect)),
                 Head(Tail(vect)):BS(Head(vect):Tail(Tail(vect))),
                 Head(vect):BS(Tail(vect)));];                      
Echo (GoldBach(7));
Echo (GoldBach(4));
Echo (GoldBach(68));
Echo (GoldBach(1000));
// Bubble Sort
Echo (BubbleSort({2}));
Echo (BubbleSort({42, 33}));
Echo (BubbleSort({33, 42, 11}));
lst := RandomIntegerVector(20,1,100);
Echo ("Bubble Sort of ", lst);
Echo (BubbleSort(lst));
        
  7 Undefined
  4 2 2        
  1000 3 997       
  2
  33 42
  11 33 42        
  Bubble Sort of {73,94,80,37,56,94,40,21,7,24,15,14,82,93,32,74,100,68,65,52}      
  7 14 15 21 24 32 37 40 52 56 65 68 73 74 80 82 93 94 94 100


[1] Ogni numero pari maggiore di 2 può essere scritto come somma di due numeri primi.