commit 784b1b8a34b5f3192dd8962b2b369685028a4cf6 Author: Mahdi Dibaiee Date: Fri Nov 4 23:09:14 2016 +0330 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..35bf8ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +#### joe made this: http://goel.io/joe +#### haskell #### +dist +dist-* +cabal-dev +*.o +*.hi +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog +.stack-work/ +cabal.project.local +.HTF/ + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f44d204 --- /dev/null +++ b/LICENSE @@ -0,0 +1,101 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, diff --git a/README.md b/README.md new file mode 100644 index 0000000..eecfbb3 --- /dev/null +++ b/README.md @@ -0,0 +1,68 @@ +slope-field +=========== + +I was studying [this course on Integration](https://www.edx.org/course/calculus-1b-integration-mitx-18-01-2x) when I encountered +slope fields and I found them interesting! + +So I thought I would give it a shot and try to write a program to draw slope fields myself! +In order to read a mathematical function definition from input, I wrote [mathexpr](/mdibaiee/mathexpr). + +Get Started +----------- +If you don't already, install [Haskell Platform](https://www.haskell.org/platform/). + +``` +git clone https://github.com/mdibaiee/slope-field +cd slope-field +stack install +slope-field +``` +Examples +-------- +Parameters: + - dy/dx: derivative of the function you are trying to visualize + - range: range of numbers to draw + - estimation size: size of `deltax` which is used to draw the slope corresponding to a small point, `0.03` is usually a good number, but you might want to try out larger numbers to get a more detailed picture on some examples +``` +dy/dx = +x + y +range - format: (lower, upper): +(-10, 10) +estimation size: +0.03 +``` + +![x plus y](https://github.com/mdibaiee/slope-field/blob/master/xpy.png?raw=true) + +``` +dy/dx = +x * y +range - format: (lower, upper): +(-10, 10) +estimation size: +0.03 +``` + +![x times y](https://github.com/mdibaiee/slope-field/blob/master/xty.png?raw=true) + +``` +dy/dx = +-y +range - format: (lower, upper): +(-10, 10) +estimation size: +0.03 +``` + +![minus y](https://github.com/mdibaiee/slope-field/blob/master/minusy.png?raw=true) + +``` +dy/dx = +y/x +range - format: (lower, upper): +(-10, 10) +estimation size: +0.1 +``` + +![y divided by x](https://github.com/mdibaiee/slope-field/blob/master/ydx.png?raw=true) diff --git a/Setup.hs b/Setup.hs new file mode 100644 index 0000000..9a994af --- /dev/null +++ b/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/app/Main.hs b/app/Main.hs new file mode 100644 index 0000000..1ecb331 --- /dev/null +++ b/app/Main.hs @@ -0,0 +1,37 @@ +{-# LANGUAGE ScopedTypeVariables #-} + +module Main where + import Lib + import System.IO + import Graphics.Rendering.Chart + import Graphics.Rendering.Chart.Backend.Cairo + import Control.Lens + import Data.Default.Class + + main :: IO () + main = do + putStrLn "dy/dx = " + math <- getLine + putStrLn "range - format: (lower, upper): " + (lower, upper) :: (Int, Int) <- read <$> getLine + putStrLn "estimation size: " + s <- read <$> getLine + + let pts = points (lower, upper) + field = slopeField math pts s + + let chart = toRenderable layout + where + layout = layout_title .~ "slope field" + $ layout_plots .~ [vectors] + $ def + + vectors = plotVectorField + $ plot_vectors_values .~ field + $ plot_vectors_scale .~ 0 + $ plot_vectors_style . vector_head_style . point_radius .~ 0 + $ def + + renderableToFile def "slope-field.png" chart + putStrLn "created file slope-field.png" + return () diff --git a/minusy.png b/minusy.png new file mode 100644 index 0000000..b292932 Binary files /dev/null and b/minusy.png differ diff --git a/slope-field.cabal b/slope-field.cabal new file mode 100644 index 0000000..fe29535 --- /dev/null +++ b/slope-field.cabal @@ -0,0 +1,38 @@ +name: slope-field +version: 0.1.0.0 +synopsis: Visualize mathematical function's slope fields +description: Visualize mathematical function's slope fields +homepage: https://github.com/mdibaiee/slope-field +license: GPL-3 +license-file: LICENSE +author: Mahdi Dibaiee +maintainer: mdibaiee@aol.com +copyright: 2016 Mahdi Dibaiee +category: Web +build-type: Simple +-- extra-source-files: +cabal-version: >=1.10 + +library + hs-source-dirs: src + exposed-modules: Lib + build-depends: base >= 4.7 && < 5 + , mathexpr >= 0.3.0.0 + , data-default-class + default-language: Haskell2010 + +executable slope-field + hs-source-dirs: app + main-is: Main.hs + ghc-options: -threaded -rtsopts -with-rtsopts=-N + build-depends: base + , slope-field + , Chart + , Chart-cairo + , lens + , data-default-class + default-language: Haskell2010 + +source-repository head + type: git + location: https://github.com/mdibaiee/slope-field diff --git a/src/Lib.hs b/src/Lib.hs new file mode 100644 index 0000000..76c0dbe --- /dev/null +++ b/src/Lib.hs @@ -0,0 +1,21 @@ +module Lib + ( points + , slopeField + ) where + import Numeric.MathExpr + import Data.Default.Class + + type Range = (Int, Int) + + points :: Range -> [(Double, Double)] + points (lower, upper) = + let range = [lower..upper] + in [ (fromIntegral x, fromIntegral y) | x <- range, y <- range ] + + slopeField :: String -> [(Double, Double)] -> Double -> [((Double, Double), (Double, Double))] + slopeField math pts diff = + let d x y = evaluate def math [("x", x), ("y", y)] + half = diff / 2 + res = map (\(x, y) -> ((x - half, y), (half, d x y * diff))) pts + inf = 1/0 + in filter (\((x0, y0), (x, y)) -> x < inf && y < inf && x > -inf && y > -inf) res diff --git a/stack.yaml b/stack.yaml new file mode 100644 index 0000000..45d2a46 --- /dev/null +++ b/stack.yaml @@ -0,0 +1,68 @@ +# This file was automatically generated by 'stack init' +# +# Some commonly used options have been documented as comments in this file. +# For advanced use and comprehensive documentation of the format, please see: +# http://docs.haskellstack.org/en/stable/yaml_configuration/ + +# Resolver to choose a 'specific' stackage snapshot or a compiler version. +# A snapshot resolver dictates the compiler version and the set of packages +# to be used for project dependencies. For example: +# +# resolver: lts-3.5 +# resolver: nightly-2015-09-21 +# resolver: ghc-7.10.2 +# resolver: ghcjs-0.1.0_ghc-7.10.2 +# resolver: +# name: custom-snapshot +# location: "./custom-snapshot.yaml" +resolver: lts-7.6 + +# User packages to be built. +# Various formats can be used as shown in the example below. +# +# packages: +# - some-directory +# - https://example.com/foo/bar/baz-0.0.2.tar.gz +# - location: +# git: https://github.com/commercialhaskell/stack.git +# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a +# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a +# extra-dep: true +# subdirs: +# - auto-update +# - wai +# +# A package marked 'extra-dep: true' will only be built if demanded by a +# non-dependency (i.e. a user package), and its test suites and benchmarks +# will not be run. This is useful for tweaking upstream packages. +packages: +- '.' +- '../mathexpr' +# Dependency packages to be pulled from upstream that are not in the resolver +# (e.g., acme-missiles-0.3) +extra-deps: + - mathexpr-0.3.0.0 + +# Override default flag values for local packages and extra-deps +flags: {} + +# Extra package databases containing global packages +extra-package-dbs: [] + +# Control whether we use the GHC we find on the path +# system-ghc: true +# +# Require a specific version of stack, using version ranges +# require-stack-version: -any # Default +# require-stack-version: ">=1.1" +# +# Override the architecture used by stack, especially useful on Windows +# arch: i386 +# arch: x86_64 +# +# Extra directories used by stack for building +# extra-include-dirs: [/path/to/dir] +# extra-lib-dirs: [/path/to/dir] +# +# Allow a newer minor version of GHC than the snapshot specifies +# compiler-check: newer-minor diff --git a/test/Spec.hs b/test/Spec.hs new file mode 100644 index 0000000..cd4753f --- /dev/null +++ b/test/Spec.hs @@ -0,0 +1,2 @@ +main :: IO () +main = putStrLn "Test suite not yet implemented" diff --git a/xpy.png b/xpy.png new file mode 100644 index 0000000..e60b64c Binary files /dev/null and b/xpy.png differ diff --git a/xtp.png b/xtp.png new file mode 100644 index 0000000..41a2261 Binary files /dev/null and b/xtp.png differ diff --git a/ydx.png b/ydx.png new file mode 100644 index 0000000..0f77588 Binary files /dev/null and b/ydx.png differ