Come rappresentare l'utilizzo di kWh per anno rispetto alla temperatura media?


9

Solo per divertimento, voglio tracciare un grafico del mio consumo mensile di energia domestica anno su anno. Tuttavia, desidero includere alcuni riferimenti alla temperatura mensile in modo da poter determinare se la mia casa o il mio comportamento sta migliorando, peggiorando o mantenendo costante per quanto riguarda l'utilizzo di kWh.

I dati con cui sto lavorando:

+----------+--------+-----------+----------------+----------+-----------+------------+
|  Month   | # Days | kWh Usage | Daily kWh Avg. | Avg. Low | Avg. High | Avg. Temp. |
+----------+--------+-----------+----------------+----------+-----------+------------+
| Mar 2015 |     32 |      1048 |             33 |       40 |        60 |         50 |
| Feb 2015 |     29 |      1156 |             40 |       32 |        54 |         43 |
| Jan 2015 |     33 |      1143 |             35 |       38 |        57 |         47 |
| Dec 2014 |     30 |       887 |             30 |       39 |        61 |         50 |
| Nov 2014 |     29 |       645 |             22 |       45 |        67 |         56 |
| Oct 2014 |     29 |       598 |             21 |       60 |        78 |         69 |
| Sep 2014 |     32 |       893 |             28 |       70 |        85 |         77 |
| Aug 2014 |     30 |       965 |             32 |       72 |        87 |         79 |
| Jul 2014 |     29 |       784 |             27 |       72 |        87 |         79 |
| Jun 2014 |     32 |      1018 |             32 |       69 |        87 |         78 |
| May 2014 |     30 |       702 |             23 |       63 |        82 |         72 |
| Apr 2014 |     33 |       722 |             22 |       50 |        71 |         60 |
| Mar 2014 |     29 |       830 |             29 |       41 |        62 |         52 |
| Feb 2014 |     28 |      1197 |             43 |       32 |        52 |         42 |
| Jan 2014 |     33 |      1100 |             33 |       38 |        59 |         49 |
| Dec 2013 |     30 |       856 |             29 |       40 |        63 |         51 |
| Nov 2013 |     33 |       686 |             21 |       48 |        70 |         59 |
| Oct 2013 |     30 |       527 |             18 |       61 |        77 |         69 |
| Sep 2013 |     30 |       817 |             27 |       69 |        86 |         77 |
| Aug 2013 |     28 |       991 |             35 |       72 |        86 |         79 |
| Jul 2013 |     31 |       993 |             32 |       73 |        86 |         79 |
| Jun 2013 |     30 |       847 |             28 |       66 |        83 |         74 |
| May 2013 |     29 |       605 |             21 |       59 |        76 |         67 |
| Apr 2013 |     34 |       791 |             23 |       47 |        66 |         57 |
+----------+--------+-----------+----------------+----------+-----------+------------+

Ho iniziato con un istogramma confrontando facilmente i valori mese per mese:

Grafico a colonne di utilizzo mese per mese

Ho immaginato una bella area di sfondo o un grafico a linee mappato su un asse verticale secondario (destro) che mostra gli intervalli alti / bassi, ma ho capito che sarebbe stato problematico con i raggruppamenti pluriennali.

Sarebbe facile con un solo anno:

2014 kWh Utilizzo con temperature

Sono curioso di sapere se qualcuno può consigliare un modo per combinare tutti i dati annuali in un singolo grafico con confronti di temperatura?

C'è un rapporto che potrei usare che potrebbe effettivamente correlare l'utilizzo di kWh alla temperatura media ... o qualche altra tecnica di visualizzazione che sto trascurando ... o sono bloccato con un grafico all'anno?

Risposte:


18

Vorrei suggerire che l'importante è sviluppare un modello di costo dell'energia fisicamente realistico e praticamente utile . Funzionerà meglio per rilevare le variazioni dei costi rispetto a qualsiasi visualizzazione dei dati non elaborati. Confrontando questo con la soluzione offerta su SO , abbiamo un caso di studio molto bello nella differenza tra l' adattamento di una curva ai dati e l' esecuzione di un'analisi statistica significativa.

(Questo suggerimento si basa sull'adattamento di un modello del genere al mio uso domestico dieci anni fa e sull'applicazione per tenere traccia delle modifiche durante quel periodo. Nota che una volta che il modello è idoneo, può essere facilmente calcolato in un foglio di calcolo allo scopo di tracciare modifiche, quindi non dovremmo sentirci limitati dalle funzionalità (in) del software per fogli di calcolo.)

Per questi dati, un tale modello fisicamente plausibile produce un quadro sostanzialmente diverso dei costi energetici e dei modelli di utilizzo rispetto a un semplice modello alternativo (un quadratico dei minimi quadrati di uso quotidiano rispetto alla temperatura media mensile). Di conseguenza, il modello più semplice non può essere considerato uno strumento affidabile per comprendere, prevedere o confrontare i modelli di utilizzo dell'energia.


Analisi

La legge di raffreddamento di Newton afferma che, in buona approssimazione, il costo del riscaldamento (durante un'unità di tempo) dovrebbe essere direttamente proporzionale alla differenza tra la temperatura esterna e la temperatura interna . Lascia che quella costante di proporzionalità sia . Anche il costo del raffreddamento dovrebbe essere proporzionale alla differenza di temperatura, con una costante simile - ma non necessariamente identica - di proporzionalità . (Ciascuno di questi è determinato dalla capacità isolante della casa e dall'efficienza dei sistemi di riscaldamento e raffreddamento.)tt0αβ

Stimare e (che sono espressi in kilowatt (o dollari) per grado per unità di tempo) sono tra le cose più importanti che possono essere realizzate,αβ perché ci consentono di prevedere i costi futuri, nonché di misurare l'efficienza del casa e suoi sistemi energetici.

Poiché questi dati rappresentano il consumo totale di elettricità, includono costi di non riscaldamento come illuminazione, cucina, informatica e intrattenimento. Interessante è anche una stima di questo consumo medio di energia base (per unità di tempo), che chiamerò : fornisce una base su quanta energia può essere risparmiata e consente previsioni di costi futuri quando vengono apportati miglioramenti dell'efficienza di grandezza nota . (Ad esempio, dopo quattro anni ho sostituito una fornace con una dichiarata più efficiente del 30% - e in effetti era esattamente così.)γ

Infine, come approssimazione (lorda) supporrò che la casa sia mantenuta a una temperatura quasi costante durante tutto l'anno. (Nel mio modello personale presumo due temperature, , rispettivamente per l'inverno e l'estate - ma in questo esempio non ci sono ancora abbastanza dati per stimare entrambi in modo affidabile e sarebbero comunque abbastanza vicini.) Sapendo questo il valore aiuta a valutare le conseguenze del mantenimento della casa a una temperatura leggermente diversa, che è un'importante opzione di risparmio energetico.t0t0t1

I dati presentano una complicazione singolarmente importante e interessante : riflettono i costi totali durante i periodi in cui le temperature esterne fluttuano - e fluttuano molto, di solito circa un quarto della loro gamma annuale ogni mese. Come vedremo, questo crea una differenza sostanziale tra il modello istantaneo sottostante corretto appena descritto e i valori dei totali mensili. L'effetto è particolarmente pronunciato nei mesi intermedi, in cui si verificano entrambi (o nessuno dei due) riscaldamento e raffreddamento. Qualsiasi modello che non tiene conto di questa variazione "erroneamente" penserebbe che i costi energetici dovrebbero essere al tasso base durante qualsiasi mese con una temperatura media di , ma la realtà è molto diversa.γt0

Non abbiamo (prontamente) informazioni dettagliate sulle fluttuazioni di temperatura mensili a parte le loro gamme. Propongo di gestirlo con un approccio pratico, ma un po 'incoerente. Tranne le temperature estreme, ogni mese di solito si verificano aumenti o diminuzioni graduali della temperatura. Ciò significa che possiamo considerare la distribuzione approssimativamente uniforme. Quando l'intervallo di una variabile uniforme ha lunghezza , quella variabile ha una deviazione standard di . Uso questa relazione per convertire gli intervalli (da a ) in deviazioni standard. Ma poi, essenzialmente per ottenere un modello ben comportato, ridimensionerò la variazione alle estremità di questi intervalli usando NormalLs=L/6Avg. LowAvg. Highdistribuzioni (con queste SD e mezzi stimati fornite da Avg. Temp).

Infine, dobbiamo standardizzare i dati in un tempo unitario comune. Sebbene sia già presente nella Daily kWh Avg.variabile, manca di precisione, quindi dividiamo invece il totale per il numero di giorni al fine di recuperare la precisione persa.

Pertanto, il modello di raffreddamento unit-time costa a una temperatura esterna di èYt

y(t)=γ+α(tt0)I(t<t0)+β(tt0)I(t>t0)+ε(t)

dove è la funzione indicatore e rappresenta tutto ciò che altrimenti non è stato esplicitamente catturato in questo modello. Ha quattro parametri da stimare: e . (Se sei davvero sicuro di potresti fissare il suo valore piuttosto che stimarlo.)Iεα,β,γt0t0

I costi totali riportati durante un periodo di tempo da a quando la temperatura varia con il tempo sarà quindix0x1t(x)x

Cost(x0,x1)=x0x1y(t)dt=x0x1(γ+α(t(x)t0)I(t(x)<t0)+β(t(x)t0)I(t(x)>t0)+ε(t(x)))t(x)dx.

Se il modello è del tutto buono, le fluttuazioni in dovrebbero raggiungere una media di un valore vicino a zero e sembreranno cambiare casualmente di mese in mese. Approssimazione delle fluttuazioni in con una distribuzione normale della media (la media mensile) e della deviazione standard (come precedentemente indicato dall'intervallo mensile) e facendo i rendimenti integraliε(t)ε¯t(x)t¯s(t¯)

y¯(t¯)=γ+(βα)s(t¯)2ϕs(t¯t0)+(t¯t0)(β+(αβ)Φs(t0t¯))+ε¯(t¯).

In questa formula, è la distribuzione cumulativa di una variabile normale di media zero e deviazione standard ; è la sua densità.Φss(t¯)ϕ


Raccordo modello

Questo modello, pur esprimendo una relazione non lineare tra costi e temperatura, è tuttavia lineare nelle variabili e . Tuttavia, poiché non è lineare in e non è noto, è necessaria una procedura di adattamento non lineare. Per illustrare, l'ho semplicemente scaricato in un massimizzatore di probabilità (usando per il calcolo), supponendo che i siano indipendenti e identicamente distribuiti, con distribuzioni normali di zero medio e deviazione standard comune .α,β,γt0t0Rε¯σ

Per questi dati, le stime sono

(α^,β^,γ^,t0^,σ^)=(1.489,1.371,10.2,63.4,1.80).

Questo significa:

  • Il costo per il riscaldamento è di circa kWh / giorno / grado F.1.49

  • Il costo per il raffreddamento è di circa kWh / giorno / grado F. Il raffreddamento è un po 'più efficiente.1.37

  • Il consumo di energia di base (senza riscaldamento / raffreddamento) è di kWh / giorno. (Questo numero è abbastanza incerto; dati aggiuntivi aiuteranno a fissarlo meglio.)10.2

  • La casa è mantenuta a una temperatura vicino a gradi F.63.4

  • Le altre variazioni non esplicitamente considerate nel modello hanno una deviazione standard di kWh / giorno.1.80

Gli intervalli di confidenza e altre espressioni quantitative di incertezza in queste stime possono essere ottenuti in modo standard con il meccanismo di massima verosimiglianza.


visualizzazione

Per illustrare questo modello, la figura seguente traccia i dati, il modello sottostante, l'adattamento alle medie mensili e un semplice adattamento quadratico dei minimi quadrati.

figura

I dati mensili sono mostrati come croci scure. Le linee grigie orizzontali su cui giacciono mostrano gli intervalli di temperatura mensili. Il nostro modello sottostante, che riflette la legge di Newton, è mostrato dai segmenti di linea rossa e blu che si incontrano a una temperatura di . Il nostro adattamento ai dati non è una curva , perché dipende dagli intervalli di temperatura. Viene quindi mostrato come singoli punti blu e rossi solidi. (Tuttavia, poiché gli intervalli mensili non variano molto, questi punti sembrano tracciare una curva - quasi uguale alla curva quadratica tratteggiata.) Infine, la curva tratteggiata corrisponde ai minimi quadrati quadratici adattati (alle croci scure ).t0

Notare quanto gli adattamenti si discostano dal modello sottostante (istantaneo), specialmente alle temperature medie! Questo è l'effetto della media mensile. (Pensa alle altezze delle linee rosse e blu che vengono "spalmate" su ogni segmento grigio orizzontale. A temperature estreme tutto è centrato sulle linee, ma a temperature medie i due lati della "V" vengono mediati insieme, riflettendo la necessità per il riscaldamento in alcune occasioni e il raffreddamento in altre occasioni durante il mese.)


Confronto tra modelli

I due accoppiamenti - quello accuratamente sviluppato qui e quello semplice, facile, quadratico - concordano strettamente sia tra loro sia con i punti dati. L'adattamento quadratico non è altrettanto buono, ma è comunque decente: il suo residuo medio aggiustato (per tre parametri) è kWh / giorno, mentre il residuo medio aggiustato del modello di legge di Newton (per quattro parametri) è kWh / giorno, circa il 5% in meno. Se tutto ciò che vuoi fare è tracciare una curva attraverso i punti dati, allora la semplicità e la relativa fedeltà dell'adattamento quadratico lo consiglierebbero.2.071.97

Tuttavia, l'adattamento quadratico è assolutamente inutile per imparare cosa sta succedendo! La sua formula,

y¯(t¯)=219.956.241t¯+0.04879(t¯)2,

non rivela nulla di utile direttamente. In tutta onestà, potremmo analizzarlo un po ':

  1. Questa è una parabola con vertice a gradi F. Potremmo prenderlo come una stima della temperatura costante della casa. Non differisce in modo significativo dalla nostra prima stima di gradi. Tuttavia, il costo previsto a questa temperatura è kWh / giorno. Questo è il doppio del consumo di energia di base adatto alla Legge di Newton.t^0=6.241/(2×0.04879)=64.063.4219.956.241(63.4)+0.04879(63.4)2=20.4

  2. Il costo marginale di riscaldamento o raffreddamento è ottenuto dal valore assoluto del derivato, . Ad esempio, usando questa formula il costo del riscaldamento di una casa quando la temperatura esterna è di gradi come kWh / giorno / grado F. Questo è il doppio del valore stimato con Newton legge . 90-6.241+2(0,04,879 mila)(90)=2.54y¯(t¯)=6.241+2(0.04879)t¯906.241+2(0.04879)(90)=2.54

    Analogamente, il costo per riscaldare la casa a una temperatura esterna di gradi sarebbe stimato a kWh / giorno / grado F. Questo è più del doppio del valore stimato con la legge di Newton.| - 6.241 + 2 ( 0.04879 ) ( 32 ) | = 3.1232|6.241+2(0.04879)(32)|=3.12

    Alle temperature medie, l'adattamento quadratico si muove nella direzione opposta. In effetti, al suo vertice nell'intervallo da a gradi, prevede quasi zero costi marginali di riscaldamento o raffreddamento, anche se questa temperatura media comprende giorni freddi come gradi e caldi come gradi. (Poche persone che leggono questo post avranno ancora il calore spento a gradi (= gradi C)!)68 50 78 50 10606850785010

In breve, sebbene appaia quasi altrettanto buono nella visualizzazione, l'adattamento quadratico erroneamente errato nella stima delle quantità fondamentali di interesse legate al consumo di energia. Il suo utilizzo per valutare i cambiamenti nell'uso è quindi problematico e dovrebbe essere scoraggiato.


Calcolo

Questo Rcodice ha eseguito tutte le operazioni di elaborazione e stampa. Può essere facilmente adattato a set di dati simili.

#
# Read and process the raw data.
#
x <- read.csv("F:/temp/energy.csv")
x$Daily <- x$Usage / x$Length
x <- x[order(x$Temp), ]
#pairs(x)
#
# Fit a quadratic curve.
#
fit.quadratic <- lm(Daily ~ Temp+I(Temp^2), data=x)
# par(mfrow=c(2,2))
# plot(fit.quadratic)
# par(mfrow=c(1,1))
#
# Fit a simple but realistic heating-cooling model with maximum likelihood.
#
response <- function(theta, x, s) {
  alpha <- theta[1]; beta <- theta[2]; gamma <- theta[3]; t.0 <- theta[4]
  x <- x - t.0
  gamma + (beta-alpha)*s^2*dnorm(x, 0, s) +  x*(beta + (alpha-beta)*pnorm(-x, 0, s))
}
log.L <- function(theta, y, x, s) {
  #   theta = (alpha, beta, gamma, t.0, sigma)
  #   x = time
  #   s = estimated SD
  #   y = response
  y.hat <- response(theta, x, s)
  sigma <- theta[5]
  sum((((y - y.hat) / sigma) ^2 + log(2 * pi * sigma^2))/2)
}
theta <- c(alpha=-1, beta=5/4, gamma=20, t.0=65, sigma=2) # Initial guess
x$Spread <- (x$Temp.high - x$Temp.low)/sqrt(6)            # Uniform estimate
fit <- nlm(log.L, theta, y=x$Daily, x=x$Temp, x$Spread)
names(fit$estimate) <- names(theta)
#$
# Set up for plotting.
#
i.pad <- 10
plot(range(x$Temp)+c(-i.pad,i.pad), c(0, max(x$Daily)+20), type="n", 
     xlab="Temp", ylab="Cost, kWh/day",
     main="Data, Model, and Fits")
#
# Plot the data.
#
l <- matrix(mapply(function(l,r,h) {c(l,h,r,h,NA,NA)}, 
                   x$Temp.low, x$Temp.high, x$Daily), 2)
lines(l[1,], l[2,], col="Gray")
points(x$Temp, x$Daily, type="p", pch=3)
#
# Draw the models.
#
x0 <- seq(min(x$Temp)-i.pad, max(x$Temp)+i.pad, length.out=401)
lines(x0, cbind(1, x0, x0^2) %*% coef(fit.quadratic), lwd=3, lty=3)
#curve(response(fit$estimate, x, 0), add=TRUE, lwd=2, lty=1)
t.0 <- fit$estimate["t.0"]
alpha <- fit$estimate["alpha"]
beta <- fit$estimate["beta"]
gamma <- fit$estimate["gamma"]
cool <- "#1020c0"; heat <- "#c02010"
lines(c(t.0, 0), gamma + c(0, -alpha*t.0), lwd=2, lty=1, col=cool)
lines(c(t.0, 100), gamma + c(0, beta*(100-t.0)), lwd=2, lty=1, col=heat)
#
# Display the fit.
#
pred <- response(fit$estimate, x$Temp, x$Spread)
points(x$Temp, pred, pch=16, cex=1, col=ifelse(x$Temp < t.0, cool, heat))
#lines(lowess(x$Temp, pred, f=1/4))
#
# Estimate the residual standard deviations.
#
residuals <- x$Daily - pred
sqrt(sum(residuals^2) / (length(residuals) - 4))
sqrt(sum(resid(fit.quadratic)^2) / (length(residuals) - 3))

4
Questa potrebbe essere la migliore risposta a qualsiasi domanda di overflow dello stack che ho letto. Apprezzo molto il tempo impiegato per spiegare la logica e il ragionamento alla base della soluzione.
Shawn,

1
La fisica è più pelosa di così. Il condensatore e l'evaporatore cambiano i ruoli in riscaldamento e raffreddamento. Ciò significa che agiscono come due sistemi diversi, non uno continuo. I giorni dei gradi di riscaldamento, i giorni dei gradi di raffreddamento e i gradi di deumidificazione sono tre fattori di costo separati e, a seconda della posizione geografica (si pensi ak, wi, ca, az, mo e fl) e l'anno possono agire in modo discontinuo (fine della stagione di riscaldamento non è lo stesso dell'inizio del raffreddamento). Statistiche decenti sui dati dicono che ci sono 5 stagioni, non 4. Maggio è la sua stagione, almeno negli ultimi 5 anni.
EngrStudent,

@EngrStudent Tutti i punti positivi e molto apprezzati. Direi che l'approccio qui presentato, sebbene semplificato, mostra ciò che è necessario per gettare le basi per prendere in giro questi effetti più sottili. Una volta che gestirai i grandi termini nel modello - e penso che nessuno negherà che la temperatura debba contribuire in modo dominante ai costi - quindi, se lo hai fatto in un modo fisicamente significativo, potresti essere in grado di identificare altri termini e forse anche stimare con precisione i loro effetti. Se non gestisci correttamente i grandi termini, non hai alcuna speranza di caratterizzare gli altri.
whuber

Adoro questa buona base / analisi, per favore ascoltala come un applauso, non una critica. Il processo di riscaldamento è diverso dal raffreddamento, quindi il quadratico non a tratti su entrambi i lati potrebbe essere in contrasto con quello. La serpentina dell'evaporatore si trova all'interno durante il raffreddamento e all'esterno durante il riscaldamento. Nella pompa di calore c'è anche lo sbrinamento del ciclo e il "backup di calore". Inoltre, il compressore deve lavorare di più per combattere una temperatura esterna più estrema, quindi non solo stai spostando più calore, ma lo stai spostando su una collina più alta. Non è lineare L'umidità è grande e può essere 2/3 del budget energetico. Infiltrazioni d'aria.
EngrStudent,

@EngrStudent Grazie ancora - questi sono tutti punti interessanti. Non avevo idea che l'umidità potesse rappresentare una parte così grande del budget. Questo è il tipo di osservazione che esemplifica il potenziale valore dell'accoppiamento di una buona teoria (o "modello concettuale" in alcuni ambienti) con l'analisi statistica.
whuber

0

Ho ricevuto una risposta su StackOverflow . Se qualcuno ha pensieri aggiuntivi, sono ancora molto interessato a soluzioni alternative.

/programming/29777890/data-visualization-how-to-represent-kwh-usage-by-year-against-average-temperatu


1
La soluzione su SO non è plausibile. La legge di Newton sul raffreddamento , che è una ragionevole approssimazione del primo ordine utile come punto di partenza, suggerisce che il diagramma del consumo di energia rispetto alla temperatura dovrebbe essere l'unione di due linee (forse di pendenze diverse). La media nasconde sbalzi di temperatura giornalieri (e anche orari) che sfocano la regione all'intersezione di quelle linee (dove non sono necessari né riscaldamento né raffreddamento). Un adattamento quadratico potrebbe essere ragionevole lì, ma asintoticamente l'adattamento deve essere lineare .
whuber

So che la precisione della sfocatura è media ma sono i dati che ho. A causa della scarsa comprensione delle statistiche non riesco a cogliere le frasi "dovrebbe essere l'unione di due linee ..." e "asintoticamente l'adattamento deve essere lineare" . Da un POV alle prime armi, il post SO sembra intuitivo in quanto soddisfa le mie aspettative che il consumo di energia aumenti alle estremità opposte della scala di temperatura pur essendo il più basso nella fascia media dove non erano necessari né riscaldamento né raffreddamento. Un adattamento quadratico non sarebbe simmetrico? Non credo che il consumo di energia sia simmetrico poiché usiamo più energia per riscaldare che raffreddare. Apprezzo correzioni o consigli.
Shawn,

Un adattamento quadratico, sebbene simmetrico, non è fisico agli estremi, perché dice che pagherai molto di più per il riscaldamento alle temperature più basse e molto di più per il raffreddamento alle temperature più elevate, di quanto sia fisicamente plausibile. Inoltre, la simmetria nella trama sarebbe prevedibile solo quando il costo per raffreddare la casa per grado è uguale al costo per riscaldarla per grado, il che presuppone che i sistemi di riscaldamento e raffreddamento siano ugualmente efficienti. Questo potrebbe o non potrebbe essere il caso, ma non dovresti imporre tale simmetria al tuo modello.
whuber

Sono d'accordo che differisce in quanto costa di più rispetto al calore per grado. Tuttavia, quindi capisco il primo commento, stai suggerendo che l'adattamento quadratico dal post SO - sebbene ragionevole - non sia veramente accurato e che un adattamento lineare sia la risposta tecnicamente corretta a causa della legge di raffreddamento di Newton? È l' implausibilità della soluzione SO che non riesco a capire.
Shawn,

1
Non potevo adattare la mia risposta a quest'ultima domanda nello spazio per un commento, quindi l'ho pubblicata come risposta. Tuttavia, non vedo come si deduca che i costi di raffreddamento per grado siano maggiori dei costi di riscaldamento per grado. I tuoi dati sembrano indicare il contrario (anche se i costi sono piuttosto vicini, come ci si aspetterebbe). E si noti che un modello lineare non implica un adattamento lineare ! C'è molto da fare qui per far sì che i dati si discostino sistematicamente da questo modello sottostante.
whuber
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.