Przejdź do głównej zawartości

Całkowanie numeryczne

Wprowadzenie
Całkowanie numeryczne można porównać do podziału powierzchni całkowanej funkcji na przedziały (im dokładniejszy wynik chcemy uzyskać, tym więcej przedziałów). W zależności od wybranej metody całkowania będziemy liczyć pole w przedziałach dla prostokąta, trapezu lub paraboli. Do wyboru pozostaje nam również wybór czy ewentualny będziemy całkować pole figury pod całkowaną funkcją (z niedomiarem - wtedy uzyskany wynik może być mniejszy niż oczekiwany) lub nad funkcją (z nadmiarem - wtedy oczekiwany wynik może być większy niż oczekiwany). Pod koniec działania programu musimy zsumować pola wszystkich figur z pod przedziałów, które policzyliśmy tak, by uzyskać wynik.

Graficzne przedstawienie problemu

Całkowanie tak prostej funkcji jakmetodą prostokątów może dać duży błąd. Parametry wielkości przedziałów (ich liczność w całkowanym przedziale) należy dobrać odpowiednio tak, by błąd był jak najmniejszy.
Całkowanie funkcji w przedziale od 0 do 8 z podziałem na 4 pod przedziały:


Całkowanie tej samej funkcji metodą trapezów daje wynik bezbłędny nawet przy 1 pod przedziale. Przykład całkowania funkcji y=x+2 w przedziale od 0 do 8 metodą trapezów z 2 pod przedziałami:



Przykład całkowania funkcji nieliniowej y = x * cos(x) metodą trapezów w przedziale od -2 do 2.


Kod programu całkującego metodą trapezów, prostokątów oraz parabol (python 2.x, najlepiej 2.6):

#!/usr/bin/python
# -*- coding: utf-8 -*-

import math

class Function(object):
 def __init__(self):
  pass
  
 def count(self,x):
  return math.exp(-math.sqrt(x))

 def c(self,x):
  return self.count(x)

class Zad1Function(Function):
 def count(self, x):
  return (x+2)

class Zad3FunctionA(Function):
 def count(self, x):
  return x * math.cos(x) 

class Zad3FunctionB(Function):
 def count(self, x):
  return (math.sin(x) + x**3)

class Zad3FunctionC(Function):
 def count(self,x):
  return ((x**2) * (math.e**x))

class Calka(object):
 def __init__(self,function, a, b,n,method_f="rectangle"):
  self.a = a
  self.b = b
  self.n = n
  self.f = function
  self.methodF = None
  self.setMethodF(method_f)

 def setParameters(self, a, b, n, 
                   function = None, method_f=None):
  self.a = a
  self.b = b
  self.n = n
  if(function!=None):
   self.f = function
  if(method_f!=None):
   self.setMethodF(method_f)

 def setMethodF(self, method_f):
  if(method_f == "rectangle"):
   self.methodF =  self.rectangleField
  elif(method_f == "trapezium"):
   self.methodF = self.trapeziumField

 def setPrecision(self, n):
  self.n = n

 def rectangleField(self, x0, x1, size):
  return min(x1,x0)*size
 
 def trapeziumField(self, x0, x1, size):
  return ((x0+x1)*size/2.0)

 def parabolaField(self, x1, x2, x3, size):
  return (x1+x3+(4*x2))*(size/6)

 def printMethodsConfrontation(self):
  print "Porownanie metod w przedziale 
         a: %f b: %f z %f iteracjami" 
         %(self.a,self.b,self.n)
  print "Metoda Prostokatow: %f " %(self.count("ractangle"))
  print "Metoda Trapezow   : %f " %(self.count("trapezium"))
  print "Metoda Parabol    : %f " %(self.parabolaCount())

 def count(self, method=None):
  if(method!=None):
   self.setMethodF(method)
    size = (self.b-self.a)/self.n 
  x0 = float(self.a) 
  x2 = math.fabs(self.f.c(x0))
  result = 0.0
  for i in range(int(self.n)):
   x1 = x2 
   x0 = x0 + size
   x2 = math.fabs(self.f.c(x0))
   result += self.methodF(x1,x2,size)
  return result 

 def parabolaCount(self):
  size = (float(self.b)-float(self.a))/float(self.n)
  x0 = float(self.a)
  x3 = math.fabs(self.f.c(x0))
  result = 0.0
  for i in range(int(self.n)):
   x1 = x3
   x2 = math.fabs(self.f.c(x0 + size/2.0))
   x3 = math.fabs(self.f.c(x0 + size))
   result += self.parabolaField(x1,x2,x3,size) 
   x0     += size 
  return result 

func     = Zad1Function()
calka    = Calka(func,0.0, math.pi,315.0)
print  "Funkcja 1: "
calka.printMethodsConfrontation()
calka.f  = Zad3FunctionA()
print  "Funkcja 3a: "
calka.printMethodsConfrontation()
calka.f  = Zad3FunctionB()
print  "Funkcja 3b: "
calka.b = 3 * math.pi
calka.printMethodsConfrontation()
calka.f  = Zad3FunctionC()
print  "Funkcja 3c: "
calka.b = 1.0
calka.printMethodsConfrontation() 
 
 
Schemat pracy w/w algorytmu przedstawia się następująco:
 


Artykuł udostępniany na licencji CC-BY-SA-3.0

Komentarze

  1. Bardzo przydatna strona ;-) Na informatyce mam właśnie obliczanie pola pod krzywą ...

    OdpowiedzUsuń

Prześlij komentarz

Popularne posty z tego bloga

WordPress -> SQL Injection poprzez plugin Webdorado SpiderCalendar

W zeszłym roku sprawdziłem jakość kodu oraz poprawność przetwarzania danych wejściowych przez plugin „Form Maker” przygotowany przez wydawcę Webdorado. Tym razem postanowiłem sprawdzić czy autor poprawił jakoś kodu swoich produktów. Należy tutaj nadmienić, że poza wersjami darmowymi opartymi na licencji GNU/GPLv2 oferuje on również wersję płatne z dodatkowymi szablonami. Tym razem postaram się opisać wszelkie przeszkody, które musiałem pokonać aby n apisać działającego exploita. Zacząłem zabawę tak, że program był dla mnie black-boxem, ale niestety skończyło się na przejrzeniu kodu. Zapraszam do lektury. Poniżej można zobaczyć jeden z widoków częściowych kalendarza, który domyślnie jest wywoływany z JavaScriptu jako XHR, można jednak go z powodzeniem otworzyć w przeglądarce jako widok główny: http://localhost:8888/wp/wp-admin/admin-ajax.php?action=spiderbigcalendar_month&theme_id=13&calendar=1&select=month,list,week,day,&date=2015-02&many_sp_calend

Inkscape - Ikona koperty

Podstawą naszej pracy będzie oczywiście narysowanie koperty. Lepszy efekt uzyskamy, jeśli narysujemy ją pod pewnym kątem. Musimy jednak oczywiście pamiętać, że konieczne będzie zachowanie proporcji oraz prawidłowe użycie rzutu. Rysujemy najpierw zewnętrzne kontury, potem wewnętrzne elementy, do momentu uzyskania podobnych efektów jak na poniższym zrzucie szkieletowym. By uzyskać widok szkieletowy włączamy opcję Widok -> Tryb Wyświetlania -> Szkieletowy . Z powyginanych trójkątów postaramy się zrobić coś w rodzaju cieni. Grubość linii koperty, które należy narysować u siebie ustawiłem na 4 - tak,by przy mniejszym rozmiarze ikony koperta była bardziej widoczna. Zresztą porównajcie to z oczekiwanym efektem końcowym. Po narysowaniu koperty przejdźmy do tworzenia tła pod kopertę. Jak widać na powyższym załączniku, będzie ono okrągłe. Korzystając z narzędzia "owal" by uzyskać idealne koło przytrzymujemy Ctrl+Shift, podczas gdy rysujemy. Wykorzystany gradient to gradient typu

Przydatne skrypty w MS SQL Server dla platformy Azure

 Jak przygotować skrypt, który wyłączy "Constrainty" w MS SQL Azure:     SELECT 'ALTER TABLE [' + s.name + '].[' + o.name + '] NOCHECK CONSTRAINT ' + i.name AS a     FROM sys.foreign_keys i     INNER JOIN sys.objects o ON i.parent_object_id = o.OBJECT_ID     INNER JOIN sys.schemas s ON o.schema_id = s.schema_id Jak przygotować skrypt, który wycziści wszystkie tabele, po tym jak wyłączysz "Constrainty" w MS SQL Azure:     SELECT DISTINCT 'DELETE FROM  [' + t.name + '] ' AS a     FROM sys.tables t     WHERE t.name <> 'appusers' AND t.name <> 'flyway_schema_history'; Jak przygotować skrypt, który włączy "Constrainty" w MS SQL Azure:     SELECT 'ALTER TABLE [' + s.name + '].[' + o.name + '] CHECK CONSTRAINT ' + i.name AS a     FROM sys.foreign_keys i     INNER JOIN sys.objects o ON i.parent_object_id = o.OBJECT_ID     INNER JOIN sys.schemas s ON o.schema_id = s.schema_i