Kategoriarkiv: Blogg

De bättre spektrala artiklarna

Allt större flugsmällor för allt mindre flugor

Varning: Detta inlägg innehåller extremt dålig Java-kod.
Läs på egen risk.

Den som nån gång har läst Reddit-sidan ProgrammerHumor har kanske lagt märke till tendenserna att hitta på alldeles absurda lösningar till mycket simpla problem eller koncept.
Till exempel, för cirka 9 månader sedan var volume sliders ett återkommande skämt och därav skapades många vackra implementationer, bl.a:

 

Mer nyligen var temat om hur man ”effektivast” kollar om ett givet heltal är jämnt eller udda. Funktioner som åstadkommer detta är lättare att implementera än volume sliders, så motiverad av mina nyfunna kunskaper i Tira (Tietorakenteet ja algoritmit) bestämde jag mig naturligtvis för att testa några i Java. Metoderna nedan är inspirerade av både ProgrammerHumor och egna idéer. Några av dem kan kräva kunskap om Java eller talteori för att förstå, så en TL;DR i meme- format finns längst ner för dem som inte bryr sig om tekniska detaljer.

Metod 1: Divisionsrest

Kolla talets divisionsrest med 2. Om resten är 0, så är talet jämnt, annars udda.

  • Tråkig normie lösning
  • Använder inte ens rekursion
public boolean isEven1(int n) {
    return n % 2 == 0;
}
Metod 2: Sista siffran

Vi undersöker talets sista siffra. Om den är 1, 3, 5, 7 eller 9 är talet udda, annars jämnt. Javas indexOf()- metod för listor returnerar -1 ifall det sökta objektet inte hittas i listan. Då gör vi ju så klart en lista av de udda siffrorna och kollar om metoden ger -1 för talets sista siffra.

  • Behöver inte utföra nån äcklig aritmetik
  • Konstant tidskomplexitet, fortfarande helt för effektiv
public boolean isEven2(int n) {
    List<Character> lastDigits
        = Arrays.asList('1', '3', '5', '7', '9');
    String number = Integer.toString(n);
    char last = number.charAt(number.length() - 1);
    
    return lastDigits.indexOf(last) == -1;
}
Metod 3: Induktion

Vi använder oss av matematisk induktion. Allmänt gäller att 0 är ett jämnt tal, efter varje jämnt tal följer ett udda, och efter varje udda följer ett jämnt. Vi bygger alltså iterativt upp en array av booleans tills vi nått det n:te elementet, som vi returnerar. Dock för att undvika en OutOfMemoryError måste vi tyvärr fuska lite och emellanåt skriva över gamla värden.

  • O(n) tidskomplexitet. Från Tira vet vi ju att O(n) är bra.
  • Induktionen kräver antagandet att 0 är ett jämnt tal.  Detta kan verifieras med en av de andra metoderna.
public boolean isEven3(int n) {
    n = n < 0 ? -n : n;        //gör n positivt
    int idx = 0;
    boolean isCurrentEven = true;
 
    boolean[] evenOdd = new boolean[10000];
    while (idx <= n) {
        if (idx == 10000) {
            idx -= 10000;
            n -= 10000;
        }
 
        evenOdd[idx] = isCurrentEven;
        isCurrentEven = !isCurrentEven;
        idx++;
    }
    return evenOdd[idx - 1];
}
Metod 4: Overflow

Alla vet ju att rekursion är bra, så här har vi en härlig blandning av rekursion och error handling.

Vi antar som baskunskap att Javas Integer.MAX_VALUE,
dvs. 2^31 – 1, är ett udda tal. Detta kan igen verifieras med någon annan metod.
Om  n = 2^31 – 1 är n udda. Annars kallar vi rekursivt på funktionen med parametern n + 2. Så klart, om n är ett jämnt tal borde den eventuellt hoppa över 2^31 – 1 och orsaka en OverflowException. Men eftersom Java hanterar den här situationen utan att klaga, måste vi använda Math.addExact()- metoden som explicit ger en Exception ifall vi går över 2^31 – 1.

Rekursionen upprepas i värsta fall ca 2^30 gånger, så en StackOverflowError orsakas långt före det. Vid detta skede avbryter vi rekursionen och startar om med en hjälpvariabel som säger hur långt vi kommit förut.

  • O(2^31 – n) tidskomplexitet. Större tal får snabbare svar.
  • isEven4(1200000000) svarade true på endast 23 sekunder.
int offset;
 
public boolean increment(int n) {
    if (n == Integer.MAX_VALUE) {
        return false;
    }
    try {
        n = Math.addExact(n, 2);
        offset += 2;
        return increment(n);
    } catch (ArithmeticException e) {
        return true;
    }
}
 
public boolean isEven4(int n) {
    offset = 0;
    while (true) {
        try {
            return increment(n + offset);
        } catch (StackOverflowError e) {
            //inget fel här, moving on...
        }
    }
}
Metod 5: Goldbach

En välkänd hypotes inom talteorin är den s.k. Goldbach Conjecture, som säger att varje jämnt tal större än 2 kan uttryckas som summan av två primtal. Resultatet har inte bevisats för godtyckligt stora jämna tal, men det har verifierats med dator för tillräckligt stora tal för våra ändamål.
Det enda jämna primtalet är 2, dvs det största jämna talet som kan uttryckas som summan av två jämna primtal är 4. Alltså om vårt tal är större än eller lika med 6 söker vi udda primtal vars summa är vårt givna tal. Annars undersöker vi talet med Metod 4.

Hur kan vi då visa att ett givet tal är ett primtal? Vi använder så klart Wilson’s Theorem. Enligt denna sats är n ett primtal om och endast om talets (n-1)! divisionsrest med n är n-1, dvs.
(n-1)!\ \equiv\ -1 \pmod n
Till detta ändamål har vi hjälpfunktionerna modFactorial och isPrime.

  • Antagligen O(n^3) tidskomplexitet. Funktionen modFactorial är O(n) och isEven5 har en dubbel loop.
  • Körtiden varierar kraftigt mellan udda och jämna tal av ungefär samma storlek:
    isEven5(4000) gav true på 2 sekunder och isEven5(4001) gav false på cirka 15 sekunder.
    isEven5(10000) gav true efter 30 sekunder. Hur länge tog det för isEven5(10001)?
  • Använd alltså den här metoden om du redan anar att ditt tal är jämnt!
public int modFactorial(int p, int mod) {
    if (p < 1) {
        return -1;
    }
    long n = 1;
    for (int i = 1; i <= p; i++) {
        n = n*i % mod;
    }
    return (int) n;
}
 
public boolean isPrime(int n) {
    if (n < 2) {
        return false;
    } else {
        return modFactorial(n - 1, n) == n - 1;
    }
}
 
public boolean isEven5(int n) {
    n = n < 0 ? -n : n; //gör n positivt
    if (n < 6) {
        return isEven4(n);
    }
 
    for (int i = 3; i < n; i++) {
        if (!isPrime(i)) {
            continue;
        }
        for (int j = 3; j <= i; j++) {
            if (!isPrime(j)) {
                continue;
            }
            if (i + j == n) {
                return true;
            }
        }
    }
    return false;
}

Här tog kreativiteten och/eller tålamodet slut, för om vi vill kan vi göra godtyckligt ”effektiva” algoritmer, men de är inte nödvändigtvis så intressanta. Men nu har vi ju jobbat under premissen att vår metod ska ge ett svar för just det talet vi stoppar in, och att svaret ska vara rätt. Vad om vi ändrar på spelreglerna lite? En bonusmetod, isEven6, hittas under länken längst ner.

Det här inlägget kunde tolkas både som en uppmuntran och en varning. Avsiktligt dålig kod kan vara väldigt underhållande och lära en tänka på problem på nya sätt (om det här är en bra eller dålig sak är upp till läsarens tolkning). Å andra sidan är dessa metoder det oundvikliga resultatet av att spendera helt för mycket tid på Tira.

TL;DR

https://i.imgur.com/TUYX6Tq.jpg

 

Summer is coming

I fantasybokserien ”A song of Ice and Fire” och i den mer kända tv-serien ”Game of Thrones” kastas vi in i en värld präglad av illistiga ränker och ond bråd död. Vi befinner oss på den stora kontinenten Westeros, i ett slags medeltida feodalsamhälle där mäktiga adelsätter styr och ställer över bönder och borgare. För inte allt för länge sedan har ett fruktansvärt inbördeskrig slitit riket i bitar, då den uråldriga kungaätten Targaryens siste vansinnige kung störtades av sina tidigare vasaller. För första gången på århundraden är det en annan ätt som sitter på Järntronen och härskar över de Sju Kungadömena. Det är dock uppenbart att stormen efter den förre kungens död ännu inte helt bedarrat, att livsfarliga strömvirvlar ännu rör sig under samhällets tillsynes lungna yta.

Vi dras in i ett komplicerat maktspel mellan rikets stora ätter och inser snabbt hur komplext och opålitligt spelet är. Så gott som varje ädling och många av de som frodats nära maktens centrum kämpar för att få mer makt och strävar efter det slutgiltiga målet: att själv en dag få sitta på Järntronen som enväldig monark. Var och en ser sin egen kamp som mest berättigad, medan vi i exil i världsdelen Essos möter tronens ”rättmätiga” arvatagare, den förre kungens sista ättling Daenerys Targaryen.

summeriscoming_4

Medvetet eller omevetet väcks våra sympatier för någon av alla dem som kämpar för att nå sina egna höga mål, vare sig det är den allvarliga ätten Stark i norr, den rika ätten Lannister eller den regerande kungaätten Baratheon. Samtidigt följer vi beundrande med hur Daenerys, en ung kvinna i en mansdominerad värld, lyckas samla allt fler anhängare och få allt mer makt (till en början till och med utan hjälp av drakar). Innerst inne hejar vi som läsare eller tittare på att någon av alla dessa ska segra och få sitt lyckliga slut. Vi blir chockade och förfasade då våra hjältar brutalt dödas och vi fylls av triumferande segerglädje då deras fiender går sitt rättvisa slut till mötes. Vi ser de flyktingströmmar och den misär som går i de politiska ränkernas fotspår, men de tycks oss ofta mindre viktiga än det Stora Spelet. Allt blir nog bra igen, bara rätt ätt sitter på tronen!

Men under berättelsens gång inser vi mer och mer att alla politiska ränker och blodiga slag bara är sidoberättelser, en rad mer eller mindre obetydliga händelser i utkanten av något mycket större. Vid de Sju Kungadömenas norra gräns vakar den uråldriga orden Nattens Väktare över en lika uråldrig mur mot de fjärran isvidderna i norr. Under århundradenas gång har de flesta glömt bort denna ordens och Murens sanna syfte, och de ovetande ätterna i söder tror att de är ett skydd mot de vilda stammarna bortom. Istället för krigare består Nattens Väktare i dessa dagar av deporterade kriminella och politiska fiender till kungen, och Muren ses som ett alternativ till avrättning. Sanningen är dock att något mycket värre än vilda stammar närmar sig i norr. I takt med den annalkande vintern (som i denna värld kan vara i åratal) marscherar en ständigt växande här av vandrande döda, ledda av magiska iskrigare från forntidens mörkaste sagor. Vi inser att om denna här tar sig förbi Muren så kommer knappast ens söderns stora arméer att kunna besegra den, speciellt inte om de först huggit varandra i småbitar. Männen och kvinnorna i maktpositioner skrattar trots detta bara bort varningarna som Nattens Väktare skickar söderut. De tror inte på sagor.

Det finns en skrämmande parallell mellan George R. R. Martins berättelse och den värld vi lever i. Vår tid är en minst lika politiskt orolig tid som den i Westeros, med främlingsfientliga och rasistiska politiker till höger och vänster. I Syrien pågår ett konstant och fruktansvärt förödande krig som aldrig verkar få sitt slut, medan resten av Mellanöstern ständigt tycks antingen i krig eller på randen till krig. Terroristorganisationer för med sig osäkerheten och rädslan till resten av världen, medan väldiga flyktingströmmar ruckar på våra trygga rutiner i Europa. Vår världs stormakter spänner sina muskler i ett kyligt politiskt klimat.

Vi försöker leva våra liv som vanligt, unna oss den lilla lyx som vi vant oss vid i vår nordiska välfärd, men ständiga nedskärningar och fasansfulla nyhetsrubriker från utlandet gör det svårt att blunda för oron. Vi kanske donerar pengar till Röda Korset eller andra organisationer för att hjälpa de värst drabbade och för att lindra vårt dåliga samvete. Vi kanske ligger vakna om nätterna och oroar oss för vår egen framtid. Kommer vi att hitta ett jobb med tillräckligt hög lön för att vi ska kunna fortsätta som vanligt? Kommer vi en dag att kunna skaffa familj och leva det liv som är vår födslorätt? Vi förbannar de osynliga massor som röstar så att uppenbart olämpliga personer får representera våra intressen. Men liksom i Westeros är allt detta en distraktion, något som tär på våra krafter och vänder vår uppmärksamhet åt fel håll. Även vi har en osynlig Mur, bemannad av en fåtalig skara Väktare.

summeriscoming_2

Bortom denna Mur väntar en framtid som får det nuvarande tumultet att blekna vid en jämförelse. Bortom Muren ser vi en värld där kaos härskar i spåren efter otaliga naturkatastrofer. Den globala uppvärmningen, som vår tids politiker lovat begränsa till en förhöjd medeltemperatur på 2°C, har accelererat bortom all räddning. Klimatförändring och konstant utarmning av naturen har förvandlat vår vackra planet till en stormhärjad, skövlad plats. De stora inlandsisarna på Antarktis och på Grönland har till stora delar smultit bort och höjt den globala havsnivån, medan frisläppt metangas från isarna ytterligare bidrar till uppvärmningen av atmosfären.

I denna möjliga framtid är fruktansvärda orkaner allt vanligare vid de översvämmade kustområdena, medan det förändrade klimatet skapar zoner av outhärdlig hetta och torka i Mellanöstern och kring Medelhavet, för att inte tala om Afrika, södra Asien och centrala Amerika. Massiva strömmar av klimatflyktingar, många gånger större än vår tids flyktingströmmar, rör sig ständigt bort från områden där det inte längre går att leva. Miljarder människor tävlar om de kvarvarande grödorna och matförråden, medan färskvatten blir en bristvara i allt större delar av världen. I Norden och i andra tidigare tempererade områden kan man en tid ägna sig åt större jordbruk, men att undvika svält i stora delar av världen är i stort sett omöjligt. Stora krig orsakar omfattande skador då människogrupper och forna nationer kämpar om kvarvarande resurser och boplatser.

Bortom den osynliga Muren ser vi även en värld där mer än en tredjedel av dagens djurarter har dött ut. Minsta lilla rubbning i till exempel tropiska ekosystem vore katastrofala, och nu har stora delar av regnskogarna helt försvunnit. Kvarvarande arter har krympt då de tvingats anpassa sig till nya ekosystem, och ständigt är det fler som ansluter sig till de utdödas tysta följe. Våra stora åkerjordar och omfattande vägnät har gjort det svårt för alla vilda djur att finna en trygg boplats i de områden där klimatet ännu tillåter dem att leva. De förorenade haven är tomma på de djurarter som i vår tid överfiskats på det mest fasansfulla vis.

summeriscoming_7

Detta är vår världs Fiende. Detta är det stora hot som växer sig allt starkare bakom vår Mur. Ännu har vi en chans att besegra fienden, ännu är inte allt förlorat, men tiden rinner snabbt ut. Våra ledare talar med stort allvar om att stoppa klimatförändringen och utarmningen av naturen, men så länge de sätter ekonomisk tillväxt och allas vår bekvämlighet först är vår chans liten. Hur kan någon av oss förvänta sig att vi ska kunna fortsätta leva på samma sätt och ändå åstadkomma en förändring? Borde vi inte se förbi alla de i slutändan relativt små problem som distraherar oss från den verkliga faran? Borde vi inte tillsammans marschera till Muren och ge de få Väktarna den förstärkning som behövs?

Ingen annan än vi själva kan i slutändan kämpa för vårt vackra hem!

summeriscoming_6

Mer läsning:

https://wwf.fi/mediabank/9562.pdf

https://climate.nasa.gov/

https://www.vox.com/videos/2017/7/14/15969034/game-of-thrones-theory-climate-change

Fake news och felmarginaler

Det sägs att en bild säger mera än tusen ord, trots det står en man och påstår att det som syns på bilden är en lögn och detta med endast två ord: ”Fake news”. Falska nyheter är inte på något sätt ett nytt begrepp. Termen har dock börjat dyka upp allt oftare. Vad är egentligen ”fake news” och vad kan de ha för koppling till fysik?

Falska nyheter eller ”fejknyheter” är ett medvetet spridande av desinformation, antingen via traditionella nyhetsmedier eller sociala medier. Falska nyheter har förekommit ända sedan antikens Rom och har under årtusendena använts för att ingjuta osäkerhet och skräck hos fiender, starta osanna rykten om politiska motståndare eller för egen ekonomisk vinning. Användningen av ”fejknyheter” har ökat under de senaste åren och speciellt på sociala medier.

I samband med presidentvalet i USA 2016 så förekom ”fake news” nästintill dagligen i nyhetsrapporteringarna, tillsammans med nya termer såsom: ”alternativa fakta” och ”alternativ information.” Alltså att beskriva något som fakta, trots att det strider mot vad som kan bevisas från tillgängliga källor. Till exempel att påstå att storleken på en publik var mycket större än vad ett fotografi av publiken klart visar. Vid detta tillfälle så påstods den ”alternativa fakta” vara den korrekta, medan den bevisligen korrekta informationen ansågs vara osann. De erkänt seriösa och traditionella nyhetsbolagen som rapporterade den korrekta informationen fick stämpeln ”fake news” av president Donald Trump och omnämns oftast således i hans tweets. Trump deklarerar sina egna åsikter som fakta och bevisligen sanningsenlig fakta som ”fake news”. Han skapar egen fakta och egna verkligheter för att förbättra sin egen situation. Presidenter ljuger, det är ingen nyhet. Faktagranskningshemsidan Politifact analyserar påståenden som amerikanska politiker framför och enligt dem så visade sig 26 % av president Obamas utsagor vara osanna. Trumps felprocent är 69 %, d.v.s. över två tredjedelar av hans officiella utsagor är till större delen icke sanningsenliga.

Som fysiker så approximerar jag dagligen. Jag använder inte helt exakta värden på konstanter och förenklar verkliga situationer genom t.ex. att negligera luftmotstånd. Jag använder mig alltså av delvis osann information och erhåller således ett delvist felaktigt svar. Jag skapar likt Trump en verklighet som är bättre anpassad för mig. Men mina approximationer är baserade på att jag förstår situationen. Till exempel: jag vill bestämma sluthastigheten hos en metallkula som släpps från en höjd på 2 meter. Då gör jag följande antaganden för att förenkla situationen: antar att kulan kommer att accelereras med gravitationsaccelerationen g = 9,81 m/s² och att kulan är så liten att luftmotståndet kommer ha minimal verkan på kulan under den korta sträckan den faller. Jag vet dock att gravitationsaccelerationen är bestämd mer exakt: g = 9,8197… m/s² för Helsingfors (beroende av breddgrad, höjd över havet, lokala densitetsskillnader i jordskorpan, etc..) och för att få ett exakt svar borde jag även ta luftmotståndet i beräkningarna.

Vill jag experimentellt bestämma hastigheten så behöver jag mäta tiden som det tar för kulan att falla till golvet. Denna tid kan bestämmas med en viss noggrannhet, inte exakt. Mäter jag med ett stoppur så är noggrannheten ca +/- 0.4 sekunder, medan ifall jag använder ljusportar så är noggrannheten ca +/- 0.001 sekunder. Experiment ska sedan utföras flertalet gånger under liknande förhållanden för att slutligen erhålla ett medelvärde och ett medelfel. Hur dyr och fin mätutrustning en fysiker än använder sig av så kommer den ha en felmarginal. (LIGO-detektorn kunde mäta en förändring i dess 4 km långa armar med en noggrannhet på 1/1000 av en protons diameter ). Detta gör att mitt resultat också kommer ha en noggrannhet eller en felmarginal. Denna felmarginal bestäms enligt principen för felens fortplantning, ett par olika formler som används beroende på hur uträkningen ser ut. Enkelt förklarat så fungerar det som trasiga telefonen: en ursprunglig felmarginal (noggrannhet) färdas genom mätdata och kombineras med andra felmarginaler och kommer slutligen ut som en kombinerad felmarginal. Resultatet från exempelexperimentet skulle kunna ha formen: hastigheten = 6.3 +/- 0.1 m/s.

I dagens informationssamhälle kan felmarginalen för ett påstående motsvaras av den omtalade ”nypan salt” som man ska ta vissa saker med. På nyhetssajter och sociala medier, främst Facebook och Twitter, så är nyhetsflödena fyllda av artiklar med varierande nivå av sanningsenlighet. Problemet är att i nyhetsflödet så är det betydligt svårare att observera felmarginalerna och felens fortplantning än i laboratoriets kontrollerade miljö. Det krävs sakkunnighet för att kunna hitta de, av politiker och journalister, utförda approximationer och felgränser. Läsaren behöver förkunskap i ämnet för att inte hen ska falla för ”fake news” propagandan. Den dystra sanningen är att ”fejknyheter” alltid har funnits och högst antagligen tyvärr alltid kommer att förekomma. Men med en allmänhet som är källkritisk, nyfiken och villig att förvärva kunskap om okända ämnen, så kommer spridningen att hindras.

Sebastian H, källkritisk och vetgirig fysiker.