Sunday, September 13, 2015

Masaccio o "memoria corta"

Chi siamo dipende anche da chi eravamo e questo dipende da quel che sai o vuoi o puoi ricordare. Per carattere sarei generalmente un magna-e-desmentega perfetto: mi dimentico tonnellate di roba senza remore e senza paura, e lo faccio pure con malcelato orgoglio: mi dico che dimentico le monate per fare spazio alle cose importanti, così resto a fuoco su quelle. Mah, a volte mi pare che mi dimentico e basta. Certo, ci sono anche cose, eventi, persone che ricordo a ferro e fuoco per decenni ma sono eccezioni, specie di simboli, memento mori e milestones simbolici da usare nei momenti di bisogno, per ispirarmi o ispirare. Cose simpatiche come ``quello è una carogna sempre e comunque, in secula seculorum'' o successi privati o pubblici che uso come antidoto a puntate per i veleni che t'intossicano di tanto in tanto. Ma sto divagando, non che sia una novità in questo blog...

C'è anche una memoria più profonda e che sento più veneta, quella che ci consente di tenere traccia di quello che siamo perché sappiamo quello che abbiamo fatto.  Ecco, di questa memoria ne vedo poca. Lo vedo su di me: fra poco arrivo al mezzo secolo di vita e so poco e forse ricordo ancora meno di quel che è accaduto qualche decennio fa nel lembo di terra che mi circonda, di quando il tempo e la storia si devono essere attorcigliati in una smorfia di disumanità e ferocia senza eguali. Mi rendo conto che so poco o nulla di pagine della resistenza che, forse, dovrei conoscere per capire quello che sono e quanta strada il mio piccolo mondo veneto abbia fatto da allora.

Questa storia è un cerchio di 20 km, in linea d'aria non mi sono allontanato mai più di 5-6 km da casa. È un viaggio in macchina con papà, il mio usb di riserva per quel che riguarda la memoria, in un pomeriggio di mezzo agosto.

A Castello di Godego in località Cacciatora c'è un monumento che ricorda le 73 persone massacrate il 29 aprile 1945 da un reparto di nazisti che affannosamente remavano verso nord per scappare ad americani ed inglesi che li braccavano. Questi 73, ho pensato, sono le Fosse Ardeatine de noantri e io, che potrei sembrare uno di cultura, quasi nemmeno sapevo dov'era la Cacciatora. 73 persone, fra cui bambini e donne, sparati alla nuca e abbandonati in un campo non si sa bene perché (ammesso e non concesso che una ``provocazione'' di qualche mona potesse giustificare alcunché).
Stele con nomi ed età degli assassinati.
Guardando la lapide sono rimasto sbigottito a diversi livelli ma ciò su cui mi soffermo ora è la domanda ``Ma come facevo a non sapere?'' Ok, forse semplicemente non ricordavo ma cambia poco: come czzrla fai/facciamo a non ``ricordare'' cose così? Ma dai, che ce le ricordiamo: ogni 29 aprile c'è la commemorazione...  Sarà, ma mi sembrano quelle commemorazioni che a noi giovani cinquantenni scarsi (notate l'ossimoro, please) sembrano cose vecchie e ininfluenti.

Stele della Cacciatora, in memorie delle 73 vittime, e attività produttive sullo sfondo.

Luogo dove stava prima il monumento, ora spostato più in là su via XXIX aprile. È ancora ben visibile lo spiazzo guarnito dai cipressi.
Mi fa anche effetto constatare che abbiano spostato la stele da dov'era, in prossimità di un incrocio, per evitare ``problemi al traffico'' sulla Statale che va a Bassano. Poco male, mica è una mancanza di rispetto spostare il ricordo di 73 morti di 50 metri per far scorrere il traffico senza intoppi e senza pericoli. Ma perché mi rimbomba in testa un ``O no?'' impietoso e ghignante? È stranamente evocativa anche la nuova posizione, appunto solo 50 metri più in là su Via XXIX aprile. Faccio qualche foto e per quanto ci provi non riesco a togliere dall'inquadratura un capannone e una villetta. Forse non serve che lo espliciti ma, mentre riempivo la card d'immagini, questo capannone e villetta si trasfiguravano in simboli della nostra memoria corta e di quanto siamo cambiati dal '45 ad oggi. Villette, capannoni, traffico fluido, capannoni, villette... Non so se era quello il mondo che volevano nel '45 anche se mi guardo seriamente dal pensare che schiene rotte, ignoranza e pellagra siano meglio di capannoni e villette.

Proseguiamo lungo la XXIX aprile prima e Via Montegrappa dopo, girando a Ramon per andare quasi lungo il Muson a Case Piotto a vedere il cippo che ricorda la morte di Primo Visentin ``Masaccio''. Era comandante della Brigata Martiri del Grappa, ucciso il 29 aprile del 1945 in circostanze che solo ora possiamo accettare: quasi certamente gli sparò alle spalle un tale Andreetta, partigiano discutibile e gran fiol di buona donna che ne aveva fatte di cotte e crude. Avete notato che la data è ancora 29 aprile? Beh, è una coincidenza, in quei giorni succedeva di tutto e il fatto che i luoghi distino 4-5 km è un caso. È forse meno casuale che un Masaccio morto fosse un ostacolo in meno alla transizione soft che alcune forze politiche desideravano alla fine del conflitto. Mica si può andare avanti con questo clima d'odio per sempre? Credo che ci sia anche saggezza nel lasciarsi alle spalle qualcosa: diciamo che si tratta di limitare scientificamente la memoria ma come corollario, mi dicono, c'è stato anche quello di rivedere troppa gentaglia compromessa col fascismo nelle istituzioni del dopoguerra.

Chi ne vuol sapere di più e di meglio (io faccio lo storico da osteria solo nelle domeniche nuvolose per scaricare l'ansia da prestazione accademica) può leggere Ceccato, ``La morte del comandante partigiano Masaccio: delitto senza castigo'' e anche questo articolo, scritto prima che io nascessi da uno che conosco.
Cippo in memoria di Masaccio a Case Piotto.
Il girotondo fra le strade di casa volge al termine, Da Loria scendiamo verso Riese ma in corrispondenza della zona industriale e della ex-FOVEN pieghiamo per Via Brigata Martiri del Grappa per andare a vedere la tomba di Masaccio nel cimitero di Poggiana di Riese, frazione natale di papà. Mentre per qualche strano caso il cippo lo avevo già visitato qualche anno fa, la tomba non l'avevo ancora mai vista (48 anni, 3 km da casa mia, il blog contiene Sydney nel nome: bizzarrie turistiche di noi polentoni). Sulla lapide leggo una poesia, custodita in una specie di scatola di plexigas per salvarla dalla pioggia, appoggiata a un masso perché resti verticale. E la smemoratezza di questi tempi incerti e arricchiti torna a farsi sentire:

Ma qua me vardo intòrno
e libero a me mente,
dei tosi del Vial nò ghe' nteressa gnente,
ai morti soto i rovi,
i ga cambia camixa,
comanda sempre lori

Ma caro comandante no i gò
desmentegai que attimi de gloria,
de miseria tanti, xa pasai,
quei giorni in cui se jera
imbriaghi sensa paura dea gaera,
de tanti sogni de strana libertà,
dell'illusion de far na nova era,
mentre se jera dentro
a storia vera

Te asso qua sto sasso
e so che nol fiorisse.
Ghe sarà sempre un osto,
un prete, un fiol de troia
pronto a mandarte in scena
e quando no te servi
spararte drio a schena
Parchè par tutto el mondo
chi che fa pì paura
xe quei coe scarpe grose
e anca a testa dura

Ma caro comandante
A cossa xe servio, na lapide sol muro,
o un gran eroe morto,
se no ghe xe futuro
Ma posso dir na roba,
a chi che passa e resta,
a chi serca na facia sincera,
a raixa xe ancora qua,
tra i crepi de sta tera.

Ho trascritto il testo così come sta e ho pensato che era giusto ricordarlo nel blog, sperando che internet sia eterna e che i dischi rigidi abbiano maggiore durata di quel che ci resta impresso dopo pochi decenni di tempo, preoccupazioni, lavoro, amori... Penso che sia una bella poesia, una cosa che più che capirla bisogna sentirla (grazie Marta): menziona il tradimento, il Viale dei Martiri a Bassano, la gaera in cui adesso ci tocca mettere quelli del MOSE che pure sono figli di quelli che morivano al posto loro nei rastrellamenti, e molto altro.
La poesia a Masaccio sulla sua lapide a Poggiana di Riese Pio X.

Papà e sullo sfondo la tomba di Primo Visentin, "Masaccio".
La Classe A percorre il pezzettino di strada che mi separa da casa e apprezzo il cambio automatico che mi consente di non muovermi nemmeno per scalare o accelerare, sono in una specie di (tranquilla) trance, vagamente stranito da quello che ho visto, rivisto o intuito in questa particola di pianura veneta.

Mi riprometto di ricordare di più, altro schema ricorrente e inutile del mio modo di pensare e chiudere i conti. So che non lo farò e so pure che abbiamo dei conti aperti con la memoria in famiglia, non me la prendo. Ma di colpo le targhe stradali mi soccorrono beffarde: ho girovagato in via XXIX aprile, Via Montegrappa, Via Masaccio e preso Via Brigata Martiri del Grappa. Finché non cambiamo i nomi alle vie, sono grato alla toponomastica che ricorda molto più di me!




Monday, September 07, 2015

Nonlinear constraints with a modified constrOptim

I often use constrOptim to quickly solve nonlinear optimization problems. constrOptim works well as a general tool to tackle constrained problems like
\[
\min_{Ax -b \geq0} f(x)
\] 
There are many other options and packages for specific problems but constrOptim is likely to be the first choice when little is known on the problem at hand or for exploratory/quick-and-dirty analysis.

The main problem I have with it is the nature of the constraints: they must be linear (written in matrix form as \(Ax-b≥ 0\)). Often I would like to compute (local) solutions of more general problems of the form
\[
\min_{g(x) -b \geq0} f(x)
\] 
where g(x) takes vector values, one component for each scalar constraint, and is in general nonlinear, i.e., \(g(x)\) cannot be written as \(Ax\).

Hence, I tweaked the code of constrOptim replacing all the occurrences of the linear constraints with my "new" non linear constraints. (In order to do that, I had to discard the chance to use "BFGS" as a solving method, for now...)  The result is a function, called constrOptimNL, see the code below, which can handle non linear constraints if a vector function g(x) and b are provided. All the drawbacks of the old function are inherited, that's life, but now non linear problems can be solved as shown by the following simple but non entirely trivial example in two dimensions.
 f <- function(x,y) x^2*y+x-x*y  
 fb <- function(x) f(x[1],x[2]) #vectorial version of f  
 x <- seq(0,3,length=31)  
 y <- seq(0,3,length=31)  
 z <- outer(x,y,f)  
 #draws a graph  
 image(x,y,z);contour(x,y,z,add=T)  
 polygon(c(0,0,3),c(0,3,0),col="white",density=20)  
Heatmap and contour lines of the objective function, the feasible domain is filled in white.

Consider the constraints \(x\geq0,y\geq 1, x+y\leq 3\), the feasible domain is a triangle with vertices (0,0), (0,3), (3,0): due to linearity, the problem can be solved with

 A <- matrix(c(1,0,-1,0,1,-1),3,2)  
 b <- c(0,1,-3)  
 res <- constrOptim(c(0.5,1.5),fb,NULL,A,b)  
 res
$par
[1] 0.2792393 2.7207607
$value
[1] -0.2683538
$counts
function gradient
246 NA 
...

The same problems can be solved with constrOptimNL, which trivially can handle linear constraints as well:
 g <- function(x,y) c(x,y,-x-y)  
 gb <- function(x) g(x[1],x[2])  
 source("constrOptimNL.R")  
 resNL <- constrOptimNL(c(0.5,1.5),fb,NULL,gb,b)  
 resNL
$par
[1] 0.2792393 2.7207607
$value
[1] -0.2683538
$counts
function gradient
246 NA
... 

Assume now that some non linear constraint is involved in the optimization problem: \(x\geq0,y\geq1,(x-1)^2+(y-1)^2\leq1\), the feasible domain is now the upper half-circle centered at (1,1) with unit radius. This problem has nonlinearities in the constraints and cannot be solved with the standard constrOptim.
 g <- function(x,y) c(x,y,-(x-1)^2-(y-1)^2)  
 b <- c(0,1,-1)  
 resNL <- constrOptimNL(c(0.5,1.5),fb,NULL,gb,b)  
 resNL$par  
[1] 0.2649931 1.6780596 

A graph shows that this is indeed the correct solution:
 alpha <- seq(0,pi,len=31)  
 image(x,y,z); contour(x,y,z,add=T)  
 polygon(cos(alpha)+1,sin(alpha)+1,col="white",density=20) #draws the half-circle  
 points(resNL$par[1],resNL$par[2])  
Contour levels and a nonlinear feasible domain in white (the solution is plotted with a filled circle).

You can check the solution more formally substituting the nonlinear constraint in polar coordinates, \(x=\cos\alpha+1,y=\sin\alpha+1\):
 f2 <- function(alpha) f(cos(alpha)+1,sin(alpha)+1)  
 curve(f2,0,pi)  
 sol <- optimize(f2,c(0,3))  
 points(sol$minimum,sol$objective)  
 c(cos(sol$minimum)+1,sin(sol$minimum)+1)  
 #"same" as resNL  

Objective function restricted to the half-circle

The code

The code for constrOptimNL is given below (in this version the parameter grad is kept for compatibility with constrOptim but will never be used: Nelder-Mead and SANN are derivatives free and invoking BFGS stops the function). Hope this helps.
 constrOptimNL <- function (theta, f, grad, g, ci, mu = 1e-04, control = list(),   
   method = if (is.null(grad)) "Nelder-Mead" else "BFGS", outer.iterations = 100,   
   outer.eps = 1e-05, ..., hessian = FALSE)   
 {  
   if(method=="BFGS") stop("method BFGS not available, use Nelder-Mead or SANN")  
   if(!is.null(control$fnscale) && control$fnscale < 0)   
     mu <- -mu  
   R <- function(theta, theta.old, ...) {  
     ui.theta <- g(theta,...)  
     gi <- ui.theta - ci  
     if (any(gi < 0))   
       return(NaN)  
     gi.old <- g(theta.old,...) - ci  
     bar <- sum(gi.old * log(gi) - ui.theta)  
     if (!is.finite(bar))   
       bar <- -Inf  
     f(theta, ...) - mu * bar  
   }  
   dR <- function(theta, theta.old, ...) {  
     ui.theta <- g(theta,...)  
     gi <- drop(ui.theta - ci)  
     gi.old <- drop(g(theta.old,...) - ci)  
     dbar <- colSums(ui * gi.old/gi - ui)  
     grad(theta, ...) - mu * dbar  
   }  
   if (any(g(theta,...) - ci <= 0))   
     stop("initial value is not in the interior of the feasible region")  
   obj <- f(theta, ...)  
   r <- R(theta, theta, ...)  
   fun <- function(theta, ...) R(theta, theta.old, ...)  
   gradient <- if (method == "SANN") {  
     if (missing(grad))   
       NULL  
     else grad  
   }  
   else function(theta,...) dR(theta, theta.old, ...)  
   totCounts <- 0  
   s.mu <- sign(mu)  
   for (i in seq_len(outer.iterations)) {  
     obj.old <- obj  
     r.old <- r  
     theta.old <- theta  
     a <- optim(theta.old, fun, gradient, control = control,   
       method = method, hessian = hessian, ...)  
     r <- a$value  
     if (is.finite(r) && is.finite(r.old) && abs(r - r.old) <   
       (0.001 + abs(r)) * outer.eps)   
       break  
     theta <- a$par  
     totCounts <- totCounts + a$counts  
     obj <- f(theta, ...)  
     if (s.mu * obj > s.mu * obj.old)   
       break  
   }  
   if (i == outer.iterations) {  
     a$convergence <- 7  
     a$message <- gettext("Barrier algorithm ran out of iterations and did not converge")  
   }  
   if (mu > 0 && obj > obj.old) {  
     a$convergence <- 11  
     a$message <- gettextf("Objective function increased at outer iteration %d",   
       i)  
   }  
   if (mu < 0 && obj < obj.old) {  
     a$convergence <- 11  
     a$message <- gettextf("Objective function decreased at outer iteration %d",   
       i)  
   }  
   a$outer.iterations <- i  
   a$counts <- totCounts  
   a$barrier.value <- a$value  
   a$value <- f(a$par, ...)  
   a$barrier.value <- a$barrier.value - a$value  
   a  
 }