Introduktion til Apache Commons Math

1. Oversigt

Vi har ofte brug for matematiske værktøjer og nogle gange java.lang.Math er simpelthen ikke nok. Heldigvis har Apache Commons målet at udfylde lækagerne i standardbiblioteket med Apache Commons Math.

Apache Commons Math er det største open source-bibliotek med matematiske funktioner og hjælpeprogrammer til Java. Da denne artikel kun er en introduktion, giver vi bare et overblik over biblioteket og præsenterer de mest overbevisende brugssager.

2. Startende med Apache Commons Math

2.1. Anvendelsen af ​​Apache Commons Math

Apache Commons Math består af matematiske funktioner (erf for eksempel), strukturer, der repræsenterer matematiske begreber (som komplekse tal, polynomier, vektorer osv.), og algoritmer, som vi kan anvende på disse strukturer (rodfinding, optimering, kurvetilpasning, beregning af skæringspunkter mellem geometriske figurer osv.).

2.2. Maven-konfiguration

Hvis du bruger Maven, skal du blot tilføje denne afhængighed:

 org.apache.commons commons-math3 3.6.1 

2.3. Pakkeoversigt

Apache Commons Math er opdelt i flere pakker:

  • org.apache.commons.math3.stat - statistikker og statistiske tests
  • org.apache.commons.math3.distribution - sandsynlighedsfordelinger
  • org.apache.commons.math3.random - tilfældige tal, strenge og datagenerering
  • org.apache.commons.math3.analyse - rodfinding, integration, interpolation, polynomer osv.
  • org.apache.commons.math3.linear - matricer, løsning af lineære systemer
  • org.apache.commons.math3.geometry - geometri (euklidiske rum og binær rumpartitionering)
  • org.apache.commons.math3.transform - transformeringsmetoder (hurtig Fourier)
  • org.apache.commons.math3.ode - almindelig integration af differentialligninger
  • org.apache.commons.math3.fitting - kurvetilpasning
  • org.apache.commons.math3.optim - funktionsmaksimering eller minimering
  • org.apache.commons.math3.genetics - genetiske algoritmer
  • org.apache.commons.math3.ml - maskinindlæring (klyngedannelse og neurale netværk)
  • org.apache.commons.math3.util - almindelige matematik / statfunktioner, der udvider java.lang.Math
  • org.apache.commons.math3.special - specielle funktioner (Gamma, Beta)
  • org.apache.commons.math3.complex - komplekse tal
  • org.apache.commons.math3.fraction - rationelle tal

3. Statistik, sandsynligheder og tilfældighed

3.1. Statistikker

Pakken org.apache.commons.math3.stat giver flere værktøjer til statistiske beregninger. For eksempel kan vi beregne gennemsnit, standardafvigelse og mange flere Beskrivende statistik:

dobbelt [] værdier = nyt dobbelt [] {65, 51, 16, 11, 6519, 191, 0, 98, 19854, 1, 32}; DescriptiveStatistics descriptiveStatistics = ny DescriptiveStatistics (); for (dobbelt v: værdier) {descriptiveStatistics.addValue (v); } dobbelt gennemsnit = descriptiveStatistics.getMean (); dobbelt median = deskriptivStatistics.getPercentile (50); dobbelt standardDeviation = deskriptiveStatistics.getStandardDeviation (); 

I denne pakke kan vi finde værktøjer til beregning af kovariansen, korrelationen eller til at udføre statistiske tests (ved hjælp af TestUtils).

3.2. Sandsynligheder og fordelinger

I kernen Java, Math.random () kan bruges til at generere tilfældige værdier, men disse værdier fordeles ensartet mellem 0 og 1.

Nogle gange ønsker vi at producere en tilfældig værdi ved hjælp af en mere kompleks distribution. Til dette kan vi bruge rammerne fra org.apache.commons.math3.distribution.

Sådan genereres tilfældige værdier i henhold til normalfordelingen med gennemsnittet på 10 og standardafvigelsen på 3:

NormalDistribution normalDistribution = ny NormalDistribution (10, 3); dobbelt randomValue = normalDistribution.sample (); 

Eller vi kan opnå sandsynligheden P (X = x) for at få en værdi for diskrete distributioner eller den kumulative sandsynlighed P (X <= x) til kontinuerlige distributioner.

4. Analyse

Analyserelaterede funktioner og algoritmer findes i org.apache.commons.math3.analyse.

4.1. Root Finding

En rod er en værdi, hvor en funktion har værdien 0. Commons-Math inkluderer implementering af flere rodfindingsalgoritmer.

Her forsøger vi at finde roden til v -> (v * v) - 2 :

UnivariateFunction-funktion = v -> Math.pow (v, 2) - 2; UnivariateSolver solver = ny BracketingNthOrderBrentSolver (1.0e-12, 1.0e-8, 5); dobbelt c = solver.solve (100, funktion, -10,0, 10,0, 0); 

Først starter vi med at definere funktionen, derefter definerer vi løseren, og vi indstiller den ønskede nøjagtighed. Endelig kalder vi løse() API.

Rodfindingsoperationen udføres ved hjælp af flere iterationer, så det er et spørgsmål om at finde et kompromis mellem eksekveringstid og nøjagtighed.

4.2. Beregning af integraler

Integrationen fungerer næsten som rodfinding:

UnivariateFunction-funktion = v -> v; UnivariateIntegrator integrator = ny SimpsonIntegrator (1.0e-12, 1.0e-8, 1, 32); dobbelt i = integrator. integrer (100, funktion, 0, 10); 

Vi starter med at definere en funktion, vi vælger en integrator blandt de eksisterende integrationsløsninger, vi indstiller den ønskede nøjagtighed, og endelig integrerer vi.

5. Lineær algebra

Hvis vi har et lineært ligningssystem under formen AX = B, hvor A er en matrix af reelle tal, og B en vektor med reelle tal - Commons Math giver strukturer til at repræsentere både matrixen og vektoren og giver også løsere til at finde værdien af ​​X:

RealMatrix a = ny Array2DRowRealMatrix (ny dobbelt [] [] {{2, 3, -2}, {-1, 7, 6}, {4, -3, -5}}, falsk); RealVector b = ny ArrayRealVector (ny dobbelt [] {1, -2, 1}, falsk); DecompositionSolver solver = new LUDecomposition (a) .getSolver (); RealVector-løsning = solver.solve (b); 

Sagen er ret ligetil: vi definerer en matrix -en fra en række matrixer med dobbelt og en vektor b fra en matrix af en vektor.

Derefter opretter vi en LUD-sammensætning som giver en løser for ligninger under formularen AX = B. Som navnet siger det, LUD-sammensætning er afhængig af LU-nedbrydning og fungerer således kun med firkantede matricer.

For andre matricer findes forskellige opløsere, der normalt løser ligningen ved hjælp af metoden med mindst kvadrat.

6. Geometri

Pakken org.apache.commons.math3.geometry giver flere klasser til at repræsentere geometriske objekter og flere værktøjer til at manipulere dem. Det er vigtigt at bemærke, at denne pakke er opdelt i forskellige underpakker med hensyn til den slags geometri, vi vil bruge:

Det er vigtigt at bemærke, at denne pakke er opdelt i forskellige underpakker med hensyn til den slags geometri, vi vil bruge:

  • org.apache.commons.math3.geometry.euclidean.oned - 1D euklidisk geometri
  • org.apache.commons.math3.geometry.euclidean.twod - 2D euklidisk geometri
  • org.apache.commons.math3.geometry.euclidean.threed - 3D euklidisk geometri
  • org.apache.commons.math3.geometry.spherical.oned - 1D sfærisk geometri
  • org.apache.commons.math3.geometry.spherical.twod - 2D sfærisk geometri

De mest nyttige klasser er sandsynligvis Vector2D, Vector3D, Linieog Segment. De bruges til at repræsentere henholdsvis 2D-vektorer (eller punkter), 3D-vektorer, linjer og segmenter.

Når du bruger klasser nævnt ovenfor, er det muligt at udføre nogle beregninger. For eksempel udfører følgende kode beregningen af ​​skæringspunktet mellem to 2D-linjer:

Linje l1 = ny linje (ny Vector2D (0, 0), ny Vector2D (1, 1), 0); Linje l2 = ny linje (ny Vector2D (0, 1), ny Vector2D (1, 1.5), 0); Vector2D-skæringspunkt = l1.kryds (l2); 

Det er også muligt at bruge disse strukturer til at få afstanden fra et punkt til en linje eller det nærmeste punkt på en linje til en anden linje (i 3D).

7. Optimering, genetiske algoritmer og maskinindlæring

Commons-Math giver også nogle værktøjer og algoritmer til mere komplekse opgaver relateret til optimering og maskinindlæring.

7.1. Optimering

Optimering består normalt af at minimere eller maksimere omkostningsfunktioner. Algoritmer til optimering kan findes i org.apache.commons.math3.optim og org.apache.commons.math3.optimering. Det inkluderer lineære og ikke-lineære optimeringsalgoritmer.

Vi kan bemærke, at der er duplikatklasser i optim og optimering pakker: optimering pakken er for det meste udfaset og vil blive fjernet i Commons Math 4.

7.2. Genetiske algoritmer

Genetiske algoritmer er en slags metaheuristikker: de er en løsning til at finde en acceptabel løsning på et problem, når deterministiske algoritmer er for langsomme. En oversigt over genetiske algoritmer kan findes her.

Pakken org.apache.commons.math3.genetics giver en ramme til udførelse af beregninger ved hjælp af genetiske algoritmer. Den indeholder struktur, der kan bruges til at repræsentere en population og et kromosom, og standardalgoritmer til at udføre mutations-, crossover- og selektionsoperationer.

Følgende klasser giver et godt startpunkt:

  • Genetisk algoritme - den genetiske algoritmeramme
  • Befolkning - grænsefladen, der repræsenterer en befolkning
  • Kromosom - grænsefladen repræsenterer et kromosom

7.3. Maskinelæring

Maskinindlæring i Commons-Math er opdelt i to dele: klyngedannelse og neurale netværk.

Klyngedelen består i at sætte en etiket på vektorer i henhold til deres lighed med hensyn til en afstandsmetrik. De leverede klyngealgoritmer er baseret på K-middelalgoritmen.

Den neurale netværksdel giver klasser til at repræsentere netværk (Netværk) og neuroner (Neuron). Man kan bemærke, at de leverede funktioner er begrænsede sammenlignet med de mest almindelige neurale netværksrammer, men det kan stadig være nyttigt til små applikationer med lave krav.

8. Hjælpeprogrammer

8.1. FastMath

FastMath er en statisk klasse placeret i org.apache.commons.math3.util og arbejder nøjagtigt som java.lang.Math.

Dens formål er at give mindst de samme funktioner, som vi kan finde i java.lang.Math, men med hurtigere implementeringer. Så når et program er stærkt afhængig af matematiske beregninger, er det en god ide at erstatte opkald til Math.sin () (for eksempel) at ringe til FastMath.sin () for at forbedre applikationens ydeevne. På den anden side skal du være opmærksom på det FastMath er mindre nøjagtig end java.lang.Math.

8.2. Almindelige og specielle funktioner

Commons-Math leverer standard matematiske funktioner, der ikke er implementeret i java.lang.Math (ligesom en faktor). De fleste af disse funktioner findes i pakkerne org.apache.commons.math3.special og org.apache.commons.math3.util.

For eksempel, hvis vi ønsker at beregne en faktor 10, kan vi ganske enkelt gøre:

lang faktor = CombinatorialUtils.faktor (10); 

Funktioner relateret til aritmetik (gcd, lcmosv.) kan findes i ArithmeticUtils, og funktioner relateret til kombinatoriske kan findes i CombinatorialUtils. Nogle andre specielle funktioner, som f.eks erf, kan tilgås i org.apache.commons.math3.special.

8.3. Brøk og komplekse tal

Det er også muligt at håndtere mere komplekse typer ved hjælp af commons-math: fraktion og komplekse tal. Disse strukturer giver os mulighed for at udføre specifik beregning på denne type tal.

Derefter kan vi beregne summen af ​​to brøker og vise resultatet som en strengrepræsentation af en brøkdel (dvs. under formularen "a / b"):

Fraktion lhs = ny fraktion (1, 3); Brøk rhs = ny fraktion (2, 5); Fraktionssum = lhs.add (rhs); Streng str = nyt FractionFormat (). Format (sum); 

Eller vi kan hurtigt beregne effekten af ​​komplekse tal:

Kompleks først = ny kompleks (1.0, 3.0); Kompleks sekund = ny kompleks (2.0, 5.0); Kompleks kraft = første. Pow (sekund); 

9. Konklusion

I denne vejledning præsenterede vi et par af de interessante ting, du kan gøre ved hjælp af Apache Commons Math.

Desværre kan denne artikel ikke dække hele analysefeltet eller lineær algebra og giver derfor kun eksempler på de mest almindelige situationer.

For mere information kan vi dog læse den velskrevne dokumentation, som indeholder mange detaljer til alle aspekter af biblioteket.

Og som altid kan kodeeksemplerne findes her på GitHub.