Overloading Haskell numbers, part 2, Forward Automatic Differentiation.
I will continue my overloading by some examples that have been nicely illustrated by an article by Jerzy Karczmarczuk. And blogged about by sigfpe.
But at least I'll end this entry with a small twist I've not seen before.
When computing the derivative of a function you normally do by either symbolic derivation, or by a numerical approximation.
Say that you have a function
f(x) = x2 + 1
and you want to know the derivative at x=5. Doing it symbolically you first get f'
f'(x) = 2x
using high school calculus (maybe they don't teach it in high school anymore?), and then you plug in 5
f'(5) = 2*5 = 10
Computing it by numeric differentiation you compute
f'(x) = (f(x+h) - f(x)) / h
for some small h. Let's pick h=1e-5, and we get f'(5) = 10.000009999444615. Close, but not that good.
So why don't we always use the symbolic method? Well, some functions are not that easy to differentiate. Take this one
g x = if abs (x - 0.7) < 0.4 then x else g (cos x)
What's the derivative? Well, it's tricky because this is not really a proper definition of g. It's an equation that if solved will yield a definition of g. And like equations in general, it could have zero, one, or many solutions.
(If we happen to use CPOs there is always a unique smallest solution which is what programs compute, as if by magic.)
If you think g is contrived, lets pick a different example: computing the square root with Newton-Raphson.
sqr x = convAbs $ iterate improve 1
where improve r = (r + x/r) / 2
convAbs (x1:x2:_) | abs (x1-x2) < 1e-10 = x2
convAbs (_:xs) = convAbs xs
So symbolic is not so easy here, and numeric differentiation is not very accurate.
But there is a third way! Automatic differentiation.
The idea behind AD is that instead of computing with with just numbers, we instead compute with pairs of numbers. The first component is the normal number, and the second component is the derivative.
What are the rules for these numbers? Let's look at addition
(x, x') + (y, y') = (x+y, x'+y')
To add two numbers you just add the regular part and the derivatives.
For multiplication you have to remember how to compute the derivative of a product:
(f(x)*g(x))' = f(x)*g'(x) + f'(x)*g(x)
So for our pairs we get
(x, x') * (y, y') = (x*y, x*y' + x'*y)
i.e., first the regular product, then the derivative according to the recipe above.
Let's see how it works on
f(x) = x2 + 1
We want the derivative at x=5. So what is the pair we use for x? It is (5, 1).
Why? Well it has to be 5 for the regular part, and since this represents x and the derivative of x is 1, the pair is (5, 1).
In the right hand side for f we need to replace 1 by (1,0), since the derivative of a constant is 0.
So then we get
f (5,1) = (5,1)*(5,1) + (1,0) = (26,10)
using the rules above. And look! There is the normal result, 26, as well as the derivative, 10.
Let's turn this into Haskell, using the type PD to hold a pair of Doubles
data PD = P Double Double deriving (Eq, Ord, Show)
instance Num PD where
P x x' + P y y' = P (x+y) (x'+y')
P x x' - P y y' = P (x-y) (x'-y')
P x x' * P y y' = P (x*y) (x*y' + y'*x)
fromInteger i = P (fromInteger i) 0
A first observation is that there is nothing Double specific in this definitions; it would work for any Num. So we can change it to
data PD a = P a a deriving (Eq, Ord, Show) instance Num a => Num (PD a) where ...Let's also add abs&signum and the Fractional instance
...
abs (P x x') = P (abs x) (signum x * x')
signum (P x x') = P (signum x) 0
instance Fractional a => Fractional (PD a) where
P x x' / P y y' = P (x / y) ( (x'*y - x*y') / (y * y))
fromRational r = P (fromRational r) 0
We can now try the sqr example
Main> sqr (P 9 1) P 3.0 0.16666666666666666The derivative of x**0.5 is 0.5*x**(-0.5), i.e., 0.5*9**(-0.5) = 0.5/3 = 0.16666666666666666. So we got the right answer. BTW, if you want to be picky the derivative of signum is not 0. The signum function makes a jump from -1 to 1 at 0. So the "proper" value would be 2*dirac, if dirac is a Dirac pulse. But since we don't have numbers with Dirac pulses (yet), I'll just pretend the derivative is 0 everywhere. The very clever insight that Jerzy had was that when doing these numbers in Haskell there is no need to limit yourself to just the first derivative. Since Haskell is lazy we can easily keep an infinite list of all derivatives instead of just the first one. Let's look at how that definition looks. It's very similar to what we just did. But instead of the derivative being just a number, it's now one of our new numbers with a value, and all derivatives... Since we are now dealing with an infinite data structure we need to define our own show, (==), etc.
data Dif a = D a (Dif a)
val (D x _) = x
df (D _ x') = x'
dVar x = D x 1
instance (Show a) => Show (Dif a) where
show x = show (val x)
instance (Eq a) => Eq (Dif a) where
x == y = val x == val y
instance (Ord a) => Ord (Dif a) where
x `compare` y = val x `compare` val y
instance (Num a) => Num (Dif a) where
D x x' + D y y' = D (x + y) (x' + y')
D x x' - D y y' = D (x - y) (x' - y')
p@(D x x') * q@(D y y') = D (x * y) (x' * q + p * y')
fromInteger i = D (fromInteger i) 0
abs p@(D x x') = D (abs x) (signum p * x')
signum (D x _) = D (signum x) 0
instance (Fractional a) => Fractional (Dif a) where
recip (D x x') = ip
where ip = D (recip x) (-x' * ip * ip)
fromRational r = D (fromRational r) 0
This looks simple, but it's rather subtle. For instance, take the 0 in the definition of fromInteger. It's actually of Dif type, so it's a recursive call to fromInteger.
So let's try with our sqr function again, this time computing up to the third derivative.
The dVar is used to create a value for "variable" where we want to differentiate.
Main> sqr $ dVar 9 3.0 Main> df $ sqr $ dVar 9 0.16666666666666669 Main> df $ df $ sqr $ dVar 9 -9.259259259259259e-3 Main> df $ df $ df $ sqr $ dVar 9 1.5432098765432098e-3And the transcendentals in a similar way:
lift (f : f') p@(D x x') = D (f x) (x' * lift f' p)
instance (Floating a) => Floating (Dif a) where
pi = D pi 0
exp (D x x') = r where r = D (exp x) (x' * r)
log p@(D x x') = D (log x) (x' / p)
sqrt (D x x') = r where r = D (sqrt x) (x' / (2 * r))
sin = lift (cycle [sin, cos, negate . sin, negate . cos])
cos = lift (cycle [cos, negate . sin, negate . cos, sin])
acos p@(D x x') = D (acos x) (-x' / sqrt(1 - p*p))
asin p@(D x x') = D (asin x) ( x' / sqrt(1 - p*p))
atan p@(D x x') = D (atan x) ( x' / (p*p - 1))
sinh x = (exp x - exp (-x)) / 2
cosh x = (exp x + exp (-x)) / 2
asinh x = log (x + sqrt (x*x + 1))
acosh x = log (x + sqrt (x*x - 1))
atanh x = (log (1 + x) - log (1 - x)) / 2
And why not try the function g we defined above?
Main> g 10 0.6681539175313869 Main> g (dVar 10) 0.6681539175313869 Main> df $ g (dVar 10) 0.4047642621121782 Main> df $ df $ g (dVar 10) 0.4265424381635987 Main> df $ df $ df $ g (dVar 10) -1.4395397945007182It all works very nicely. So now when we can compute the derivative of a function, let's define something somewhat more interesting with it. Let's revisit the sqr function again. It uses Newton-Raphson to find the square root. How does Newton-Raphson actually work? Given a differentiable function, f(x), it finds a zero by starting with some x1 and then iterating xn+1 = xn - f(xn)/f'(xn) until we meet some convergence criterion. Using this, let's define a function that finds a zero of another function:
findZero f = convRel $ cut $ iterate step start
where step x = x - val fx / val (df fx) where fx = f (dVar x)
start = 1 -- just some value
epsilon = 1e-10
cut = (++ error "No convergence in 1000 steps") . take 1000
convRel (x1:x2:_) | x1 == x2 || abs (x1+x2) / abs (x1-x2) > 1/epsilon = x2
convRel (_:xs) = convRel xs
The only interesting part is the step function that does one iteration with Newton-Raphson. It computes f x and then divides the normal value with the derivative.
We then produce the infinite list of approximations using step, then cut it of at some point (in case it doesn't converge), and then we look down the list for two values that are within some relative epsilon.
And it even seems to work.
Main> findZero (\x -> x*x - 9) 3.0 Main> findZero (\x -> sin x - 0.5) 0.5235987755982989 Main> sin it 0.5 Main> findZero (\x -> x*x + 9) *** Exception: No convergence in 1000 steps Main> findZero (\x -> sqr x - 3) 9.0Note how it finds a zero of the sqr function which is actually using recursion internally to compute the square root. So now we can compute numerical derivatives. But wait! We also have symbolic numbers. Can we combine them? Of course, that is the power of polymorphism. Let's load up both modules:
Data.Number.Symbolic Dif3> let x :: Num a => Dif (Sym a); x = dVar (var "x") Data.Number.Symbolic Dif3> df $ x*x x+x Data.Number.Symbolic Dif3> df $ sin x cos x Data.Number.Symbolic Dif3> df $ sin (exp (x - 4) * x) (exp (-4.0+x)*x+exp (-4.0+x))*cos (exp (-4.0+x)*x) Data.Number.Symbolic Dif3> df $ df $ sin (exp (x - 4) * x) (exp (-4.0+x)*x+exp (-4.0+x)+exp (-4.0+x))*cos (exp (-4.0+x)*x)+(exp (-4.0+x)*x+exp (-4.0+x))*(exp (-4.0+x)*x+exp (-4.0+x))*(-sin (exp (-4.0+x)*x))We define x to be a differentiable number, "the variable", over symbolic numbers, over some numbers. And then we just happily use df to get the differentiated versions. So we set out to compute numeric derivatives, and we got these for free. Not too bad. One final note, the Dif type is defined above can be made more efficient by not keeping all the infinite tails with 0 derivatives around. In a real module for this, you'd want to make this optimization. [Edit: fixed typo.]
Labels: Haskell, overloading

42 Comments:
Just a minor typo, but shouldn't that be:
f'(x) = (f(x + h) - f(x)) / h
To make a derivative-taking operator fully general, it is important to be able to apply the derivative-taking function to functions that themselves internally take derivatives. This is difficult in Haskell; try using the code in the post and you'll see the problem. The issue is discussed in some detail in an IFL-2005 presentation Perturbation Confusion and Referential Transparency: Correct Functional Implementation of Forward-Mode AD by Jeff Siskind and Barak Pearlmutter (me). We also discussed using lazy towers of higher-order derivatives in the multivariate case in a POPL-2007 paper, Lazy Multivariate Higher-Order Forward-Mode AD, which includes working code.
The above all concerns forward-mode automatic differentiation. The reverse-mode AD construct is the one that is useful for taking gradients in high dimensions, and we've also been working on incorporating that into functional languages; see our web page on this FP/AD/Stalingrad stuff.
barak,
Can you give an example of the difficulty using derivatives internally? I've not read the IFL paper.
I have read your POPL paper and I have a Haskell version of that code. I have many parts to these posts left. :)
I also have a version of Jerzy's code for the adjoint AD in Haskell. It comes out quite nicely, with the adjoints forming a vector space.
barak,
I looked at your example in the IFL paper. I see your point. There's indeed sort of a variable capture problem with this approach since there's only one variable.
I don't think this is a fundamental problem, as just point out you just need some clever tagging.
barak,
So I tried your example
deriv (\ x -> x * deriv (\ y -> x + y) 1) 1
This doesn't type check because of the level confusion inside the inner lambda. I think that's acceptable behaviour.
The lifted version
deriv (\ x -> x * deriv (\ y -> dCon x + y) 1) 1
yields 1 as it should.
Yes, manual insertion of lift operators can bail you out some of the time. But they are fragile and delicate and easy to put in the wrong place. And because they are a static solution, but the problem is at root a dynamic one, they won't work when the correct placement of lift operators cannot be determined statically. For instance, they can't bail you out when the same function is called in multiple differential contexts. For example, consider finding a saddlepoint using min/max where max is defined in terms of min and min uses a gradient method.
Lennart, Barak,
I don't know if you noticed this thread. I think it at least takes care of the fragile, delicate and easy to put in the wrong place objections.
-Bjorn
welcome to the wow power leveling cheap service site, buy wow power leveling cheap wow gold,wow gold,world of warcraft wow power leveling buy wow gold
Gold key link for( wow power leveling )the law by( wow power leveling )all, such as bubble( power leveling )shadow dream hallucinations, such( wow gold )as exposed as well( wow powerleveling )as electricity, should be the case
Once I played Anarchy, I did not know how to get strong, someone told me that you must have Archlord gold. He gave me some Archlord money, he said that I could buy Archlord gold, but I did not have money, then I played it all my spare time. From then on, I got some archlord online Gold, if I did not continue to play it, I can sell cheap Archlord gold to anyone who want.
You must be not know too much about Asda Story gold. My classmate gave me some Asda Story money, he said that I could buy Asda Story Gold, but I did not have money, then I played it all my spare time. From then on, I got some cheap Asda Story gold.
When the Wow Gold wolf finally found the wow gold cheap hole in the chimney he crawled cheap wow gold down and KERSPLASH right into that kettle of water and that was cheapest wow gold the end of his troubles with the big bad wolf.
game4power.
The next day the Buy Wow Goldlittle pig invited hisbuy gold wow mother over . She said "You see it is just as Cheapest wow goldI told you. The way to get along in the world is to do world of warcraft gold things as well as you can." Fortunately for that little pig, he buy cheap wow gold learned that lesson. And he just wow gold lived happily ever after!.
Why was there no follow on bankruptcy then? The bailout of AIG FP went to (wow power leveling) hedge funds that bound credit swaps on Lehman failing or others betting on rating (wow power leveling) declines. AIG has drained over 100 billion from the government. Which had to go to (wow power leveling) those who bet on failures and downgrades. Many of whom (power leveling)were hedge funds. I-banks that had offsetting swaps needed the money from the AIG bailout or they would have been caught. Its an (wow powerleveling) insiders game and it takes just a little bit too much time for most people to think (wow gold) through where the AIG 100 billion bailout money went to, hedge funds and players, many of whom hire from the top ranks of DOJ, Fed, Treasury, etc. ZHANG XIAO CHEN
When the Wow Gold wolf finally found the wow gold cheap hole in the chimney he crawled cheap wow gold down and KERSPLASH right into that kettle of water and that was cheapest wow gold the end of his troubles with the big bad wolf.
game4power.
The next day the Buy Wow Goldlittle pig invited hisbuy gold wow mother over . She said "You see it is just as Cheapest wow goldI told you. The way to get along in the world is to do world of warcraft gold things as well as you can." Fortunately for that little pig, he buy cheap wow gold learned that lesson. And he just wow gold lived happily ever after!.
A slim, wide-eyed mygamegoldwoman almost human in virbanksfeatures eyed agamegold the pair. Her nose was sharp, but very elegant. She had tbcgold a pale, trade4gamebeautiful face the color of ivory, and veryge for hair she wore a wondrous mane of downy feathers. Her gown fluttered as she walked—on two delicate worldofgolds but still sharply-taloned feet. “Awake, awake you are,” she said with a pvp365 slight frown. “You should rest, rest.” Krasus bowed to her. “I am ezmmorpg grateful for your ighey hospitality, mistress, but I am well enough to continue on9a9z now.” She cocked her head as a bird might, giving the mageltk365 a reproving look. “No, no…too soon, toogold4guild soon. Please, sit.” The duo looked around u4game and discovered that two chairs, made in the same ready4game fashion as the nest, waited behind happygolds them. Malfurion waited for Krasus, who finally nodded and sat.
There are several tbcgold races stand up and take the fightakgame to the demons under assault by the Legion. The races are unaligned at character mygamestock start, and can choose to become ttgaming friendly with either Horde or Alliance over the course of their careers. Faction gained belrion with one side eventually live4game causes faction loss with the other, until the character is as much Horde or Alliance as an Orc or mmopawn Human. Each race has awowgoldget starting city with 1-20 zone content.
When you hunt, the enemies you agamegoldkill drop items, and even the most useless ones can be sold to vendors for money. Quests trade4game on the other hand give up rewards in money and items, the money gamersell part is most useful as it is usually a large sum world of warcraft rpg-tradergold. Crafting is also another alternative for earning Gold, you just choose wowpoweronany two professions and use it to gather raw materials or create gamegoodyitems which you can sell to vendors or players. Items sell egrichhigher to players since vendors have a set price and people always want to buy wow gold us ogpalat a lower price than the vendor but sell at a higher price, so there usually is a euwowgoldmiddle price world of warcraft gold. To see what the going ratemymmoshop is, type in "PC" (Price Check) in the Trade Chat window and the item you want to price check and someone should reply with the going-rate for that item
Puma shoes , Ugg Boots , nike max shoes, NIKE AIR MAX TN ,nike max shoes ,PUMA CHAUSSURES, NIKE SHOX Torch ,puma Ferrari F1 ,PUMA DRIFT CATmens clothing men's sweate, cheap columbia jackets, lacoste sweater, ralph lauren polo shirts,ski clothing. Free Shipping, PayPal Payment. Enjoy your shopping experience on mensclothingstore.Us
nike tnEnter the necessary language
translation, up to 200 bytes winter, moves frequently in Chinanike chaussures showing that the deep strategy of the Chinese market. Harvard Business School, tn chaussures according to the relevant survey data show that in recent years the Chinese market three brands, Adidas, Li Ning market share at 21 percent, respectively,
chaussures puma stores offer you the most popular fashion shoes, including the puma basketpuma puma BanXie and shoes. All the puma product factory direct sale, special processing, create the most inexpensive puma stores.National Weather Service Meteorologist Jason puma CAT said this week's temperatures will mirror seasonable averages of highs around 71 and lows about 42 degrees ...
Bought the Tennis Racquet is important, exercise can reduce the harm, especially for the wrist injury. But the good of Tennis Racket in general in the real prices are more expensive, so a lot of websites now have cheap tennis racquet、tennis racquet discount、cheap tennis racket、discount Tennis Racket .
chaussures pumaBon March¨¦ Chaussure Sports Shop:baskets pumaChaussure Puma Femme,Chaussure Puma Homme,Chaussure Nike Femme,Chaussure Nike homme,nike shoxChaussure Sport et plus. Livraison Rapide.Paypal
Cheap Brand Jeans ShopMen Jeans - True Religion Jeans, Women JeansGUCCI Jeans, Levi's Jeans, D&G Jeans, RED MONKEY Jeans, Cheap JeansArmani Jeans, Diesel Jeans, Ed hardy Jeans, Evisu Jeans, Jack&Jones Jeans...ed hardy clothing Online Store - We wholesale and retail cheap ed hardy shirts
g including Ed Hardy Men's Clothing,ed hardy clothing Clothing,Ed Hardy Kids Clothing, ed hardy womens Sunglasses, Ed Hardy Swimwear and more.
Lacoste polo shirts
north face jackets
cheap handbags
cheap purse
women's nike shoes
In a womens clothing boutique store, several girls were trying on fashionable new polos men poloswomen polos. In addition to flower dresspolo fashionembroodered polostennis racketsclothing poloclothingedhardyshirtedhardyclothingedhardysummer ed hardy clothingcheap shirtsed hardy brandcheap ed hardypolo shirts cheapcheap tennis racketsdiscount tennis racketsralphlaurenpoloshirtscheappolospolo fashion, flower shirt, flower jacket, even with the scarf pattern is all kinds of flowers.
This issue ed hardy t-shirts is of paramount importance as forensic experts ed hardy mens claimed to have discovered in the collar of one of ed hardy womens the fragment of an electronic timer which provided the key link ed hardy sunglasses between the bombing and Libya.They will surely love polo ralph laurenlike this. The styles are so fabulous burberry polos catching the light who would not love lacoste polo shirts like these.
Advanced precision comes from the connection of the Side prince-o3-tour to the cheap tennis racquets at three o'clock and nine o'clock, which results in less torque (or twisting) at polo logopolo shirts in voguepolo women clothinged-hardy shirtsed-hardy sunglassesimpact.
It was just a ed hardy clothing with a colourful design of three wolves howling at the moon. Now, it’s a viral sensation with its own ed hardy clothes, videos and an exploding following that has swamped a tiny New ed hardy shirts. Longer arms extend the yoke farther up each side of the babolat pure drive. These arms - or Side Drivers wilson k six- create a stiffer construction and distribute maximum power from the base of the yoke to the middle of the head microgel.
discount ralph lauren polos are one of the highest in demand cheappolos because along with protecting your skin it also enhances your looks. These polo clothingare the in-thing in today's ralph lauren polo shirts fashion world and among the youngstersdiscount polossummer polospolo shirts whosale.
For the polo shirts, many people loveralphlaurenpoloshirtscheappolos but hate it. This brand is favorite, products like his style; the same is hard not to develop the Lacoste polo shirts brand has been cheap lacoste polos the Asian market. There are stores to buy wholesale polo shirts, However, ralph lauren polo shirts is too many fakes. It will be out of shape cheap ralph lauren polos.
There are ed hardy shirts
,pretty ed hardy shirt for men,
ed hardy womens in the ed hardy online store
designed by ed hardy ,
many cheap ed hardy shirt ,glasses,caps,trouers ed hardy shirts on sale ,
You can go to edhardyshirts.com to have a look ,you may find one of ed hardy clothing fit for you
Top qualitymen's jacket,
These cheap jacket are on sale now,you can find
north face jackets inmage on our web
Do you wannaghd hair straighteners for you own , we have many
cheap ghd hair straightenersin style and great,you can choose one from these
hair straighteners
Authentic chaussure puma
chaussure sport
And chaussure nike shoes
Come here to have a look of our Wholesale Jeans
Many fashionMens Jeans ,eye-catching
Womens Jeans ,and special out standing
Blue Jeans ,you can spend less money on our
Discount Jeans but gain really fine jeans, absolutely a great bargain.
www.crazypurchase.com
China Wholesale
wholesale from china
buy products wholesale
China Wholesalers
http://weddingdressseason.com
Ralph Lauren Polo is the most famous sports shirt.Burberry Polo Shirt is the most well-known in France jerseys. The north face jacket is a winter essential goods.Columbia jacket and spyder jacket let people have more choice of clothes. Different brands have different design styles, but all it attracts us.
cheap tennis racquet
tennis racquet discount
cheap tennis racket
discount Tennis Racket
Modern tennis racquet in the manufacturing sector have been in use for close to the aerospace industry and military-industrial material products. Over the past two decades, metal materials and chemical materials to upgrade the high level of tennis racket manufacturer has laid a solid foundation. In today's big brands have more than tennis: Head junior tennis racket,Wilson tennis racquet, Wilson tennis racket,Head tennis racket,Babolat tennis racket......
ed hardy clothing
ed hardy clothes
ed hardy shirts
ed hardy t-shirts
ed hardy sunglasses
ed hardy mens
ed hardy womens
Wholesale Handbags
Cheap Handbags
Womens Handbags
Cheap Purses
Designer Handbags
Thank you so much!!polo shirt men'ssweate,cheap polo shirts cheap columbia jackets, lacoste sweater, ralph lauren polo shirts,ski clothing. Free Shipping, PayPal Payment. Enjoy your shopping experience on mensclothingus.com.We have mens polo shirts.
Awesome!!!Best wishes for you !!wholesale polo shirts is the father of the summer should be prepared to most commonly used item, it has both style and shape of polo clothing, and vest with a random function, so that in the short-sleeved apply to both on many occasions, the pink and black color men's polo shirts brought into effect, lightweight cotton, linen texture to demonstrate masculine temperament and sense of fashion exhaustively. polo shirts for sale
Wonderful!!You can find the father who desire fashionable, intellectual cheap polos simultaneously, you can find a psychologist to study the most harmonious of families should be pink mens clothing, so do not want to take the mature route for the father, buy cheap polos, the learn from such a walk in between the formal and casual styling, refined style to create a sense of mild authority.
Perfect!!You are a outstanding person!Have you ever wore chaussures puma, puma CAT,Puma shoes store gives some preview of puma speed cat,puma basket, puma speed, puma speed and other puma shoes. These puma sport items are at store recently and available for anyone.
Do not mean bad.Thank you so much!Men's polo shirts was the shirt of choice for diverse groups of teenagers.Brightly coloured polo shirts can make you look like a Day-glo dirigible.
Wonderful!You can find the father who desire fashionable eg,uggs fashion,you can enjoy uggs online here, intellectual polo shirt simultaneously.
fantastic!God bless you!Meanwhile,you can visit my China Wholesale,we have the highest quality but the lowest price fashion products wholesale from China.Here are the most popular China Wholesale products for all of you.Also the polo clothing is a great choice for you.
God bless you!I really agree with your opinions.Also,there are some new fashion things here,gillette razor blades.gillette mach3 razor bladesfor men.As for ladies,gillette venus razor blades must the best gift for you in summer,gillette fusion blades are all the best choice for you.
1)
cheap hair straighteners
chi hair straightener
chi flat iron
new polo shirts
cheap Lacoste polo shirts
cheap Lacoste polo shirts
cheap handbags
cheap bags
puma chaussures
chaussures puma
chaussure puma
Men's North Face
Women's North Face
hair straighteners
sexy lingerie store
cheap ugg boots
tattoo wholesale
men's clothing
women's clothing
2009 nike shoes
new nike shoes
Women's max
Men's max 93
nike shox
Nike air force
Nike air max 2003
nike air max ltd
nike air max tn
Nike air rift
Nike air Yeezy
nike airmax
Nike air max 90
Nike air max 97
nike birds nest shoes
nike dunk
nike RT1 shoes
nike SB
nike shox shoes
Nike shox OZ shoes
Nike shox R2 shoes
Nike shox R3 shoes
Nike shox R4 shoes
Nike shox R5 shoes
Nike shox TL3
nike trainers lovers
tennis rackets
Wilson tennis rackets
HEAD tennis rackets
Babolat tennis rackets
視訊|影音視訊聊天室|視訊聊天室|視訊交友|視訊聊天|視訊美女|視訊辣妹|免費視訊聊天室
自慰器|自慰器
網頁設計|網頁設計公司|最新消息|訪客留言|網站導覽
免費視訊聊天|辣妹視訊|視訊交友網|美女視訊|視訊交友|視訊交友90739|成人聊天室|視訊聊天室|視訊聊天|視訊聊天室|情色視訊|情人視訊網|視訊美女
一葉情貼圖片區|免費視訊聊天室|免費視訊|ut聊天室|聊天室|豆豆聊天室|尋夢園聊天室|聊天室尋夢園|影音視訊聊天室||
Post a Comment
<< Home