Закохуємося в F# Доза 2 Будуємо фрактальне зображення, або безліч Мандельброта своїми руками

На минулому уроці ми розглянули основні поняття функціонального програмування, тепер спробуємо застосувати їх на практиці. Оскільки функціональне програмування, як ви напевно зрозуміли, ідеально підходить для вирішення математичних завдань, то розглянемо саме таке завдання — побудова зображення безлічі Мандельброта, найвідомішої фрактальної множини.

закохуємося

Математично, множина Мандельброта визначається наступним чином. Розглянемо послідовність комплексних чисел z(n+1) = z(n)^2+c, z(0)=0. Для різних c ця послідовність або сходиться, або розходиться Наприклад, для c=0 z(i) = 0, а для c=2 маємо послідовність, що розходиться. Так ось, безліч Мандельброта - це безліч тих, для яких послідовність сходиться.

Переходимо до реалізації алгоритму F#. Для початку, визначимо вихідну функцію

let mandelf (c:Complex) (z:Complex) = z * z + c;;

Тут нам довелося явно вказати тип Complex (це треба зробити хоча б для однієї зі змінних, але ми для симетрії зробили для двох), оскільки за замовчуванням для операції + належить цілий тип. Для того, щоб тип Complex став доступним, спочатку доведеться вказати преамбулу:

open Microsoft.FSharp.Math;; open System;

Щоб перевірити збіжність, ми приймемо невелике припущення. Вважатимемо, що послідовність сходиться, якщо z(20)

Тут знак >> позначає композицію функцій, а запис fun x->x - тотожну функцію. Взагалі, конструкція fun x -> . дозволяє задати функціональну константу, тобто. вираз типу функції від одного аргументу. Наприклад, такі дві конструкції —еквівалентні:

У разі функція rpt приймає один аргумент цілого типу n (кількість повторень), і деяку функцію f, тобто. має тип rpt: int -> ('a -> 'a) -> ('a -> 'a). Для n=0 повертається тотожна функція, а для n>0 - композиція f і (n-1)-кратного застосування f. Запис означає поліморфний тип, тобто. замість нього може бути будь-який припустимий тип даних.

Повертаючись до нашої задачі, пригадаємо, що для фіксованого c часткове застосування карованої функції (mandelf c) буде функцією одного аргументу (x), і застосуємо до цієї функції багаторазову композицію. В результаті z(20) обчислиться як rpt 20 (mandelf c) (Complex.zero) . Дійсно, rpt 20 (mandelf c) буде позначати 20-кратне застосування функції mandelf з , яке потім ми застосовуємо до 0. Тоді функція приналежності комплексного числа до множини Мандельброта запишеться як

Решта – справа техніки. Визначаємо функцію масштабування scale (вона як аргументи брати пари чисел — діапазони зміни змінних типу float*float і int*int ), і в подвійному циклі друкуємо безліч на консолі:

Але це ще не все! Згадаймо, що програмісту F# доступна вся міць платформи Microsoft.NET! Тому ми можемо побудувати графічне зображення у вікні, використовуючи Windows Forms та бібліотеку System.Drawing! Відповідний код:

Що з цього вийшло - див. на малюнку нижче:

зображення

Хардкорна конфа за С++. Ми запрошуємо лише профі.