________fear_of_underscores

среда, 20 июня 2012 г.

MS Visual Studio Template for Data Analysis

Уже довольно давно я пользуюсь няшным шаблоном для VS, который помогает в пару кликов мышки создать проект F#, в котором легко можно делать матричные операции с помощью Math.Net Numerics, использовать HtmlAgilityPack и рисовать графики с помощью FSharpChart:


Я сделал этот шаблон, когда понял, что если ещё один раз буду вручную добавлять все нужные библиотеки — повешусь. Тем не менее, сам процесс создания шаблона не обошёлся без пары gotchas, так что я решил записать его; сейчас же перепишу его сюда и приложу сам шаблон, на благо общественности.

В шаблоне используются библиотеки, добытые с помощью NuGet'a и скрипт FSharpChart. Все права на всё принадлежат тем, кому они принадлежат ^_^.

АлгоритмЪ:
  1. Создать обычный проект F#, включить в него все нужные библиотеки и файлы, загрузить все нужные NuGet-пакеты, написать весь boilerplate код. В моём случае это выглядело так:
    #if INTERACTIVE 
    //Math.Net Numerics
    #r @"..\packages\MathNet.Numerics.2.1.2\lib\Net40\MathNet.Numerics.dll"
    #r @"..\packages\MathNet.Numerics.FSharp.2.1.2\lib\Net40\MathNet.Numerics.FSharp.dll"
    //PowerPack
    #r @"..\packages\FSPowerPack.Community.2.1.1.1\Lib\Net40\FSharp.PowerPack.dll"
    #r @"..\packages\FSPowerPack.Community.2.1.1.1\Lib\Net40\FSharp.PowerPack.Linq.dll"
    #r @"..\packages\FSPowerPack.Community.2.1.1.1\Lib\Net40\FSharp.PowerPack.Metadata.dll"
    #r @"..\packages\FSPowerPack.Community.2.1.1.1\Lib\Net40\FSharp.PowerPack.Parallel.Seq.dll"
    //FSharpChart
    #r @"..\packages\MSDN.FSharpChart.dll.0.60\lib\MSDN.FSharpChart.dll"
    #load "FSharpChart.fsx"
    //HtmlAgility
    #r @"..\packages\HtmlAgilityPack.1.4.3\lib\HtmlAgilityPack.dll"
    #r @"System.Xml"
    #r @"System.Xml.Linq"
    #endif
    
    open System
    open System.Collections.Generic
    open System.Linq
    open System.Text
    open System.IO
    open System.Drawing
    open System.Windows.Forms
    open System.Windows.Forms.DataVisualization.Charting
    open System.Xml
    open System.Xml.Linq
    
    open MathNet.Numerics
    open MathNet.Numerics.FSharp
    open MathNet.Numerics.LinearAlgebra.Double
    open MathNet.Numerics.LinearAlgebra.IO
    open MathNet.Numerics.Distributions
    open MSDN.FSharp.Charting  //FSharpChart
    open HtmlAgilityPack       //HtmlAgility
    open Microsoft.FSharp.Math //PowerPack
    
  2. File > Export Template...
  3. Получится .zip файл, в корневую папку которого надо вставить все .nupkg файлы:
  4. В файле MyTemplate.vstemplate надо поменять метаданные в разделе TemplateData :
    <TemplateData>
        <Name>Data Analysis App Extended</Name>
        <Description>Data Analysis Application with installed Math.Net Numerics,
             FSharpChart, HtmlAgility and F# PowerPack libraries.</Description>
        <ProjectType>FSharp</ProjectType>
        ...
    </TemplateData>
    
  5. В разделе WizardData нужно добавить информацию о всех используемых NuGet-пакетах:
    <WizardData>
        <packages repository="template">
          <package id="zlib.net" version="1.0.3.0" />
          <package id="MathNet.Numerics" version="2.1.2" />
          <package id="MathNet.Numerics.FSharp" version="2.1.2" />
          <package id="MSDN.FSharpChart.dll" version="0.60" />
          <package id="HtmlAgilityPack" version="1.4.3" />
          <package id="FSPowerPack.Community" version="2.1.1.1" />
        </packages>
      </WizardData>
    
  6. Наконец, в самом файле проекта .fsproj, нужно убедиться, что используются относительные пути для NuGet-пакетов:
    <PropertyGroup>
        ...
        <ReferencePath>..\packages\</ReferencePath>
    </PropertyGroup>
    ...
    <ItemGroup>
        <Compile Include="Program.fs" />
        <None Include="packages.config" />
        <None Include="FSharpChart.fsx" />
    </ItemGroup>
    <ItemGroup>
        <Reference Include="FSharp.PowerPack">
          <HintPath>..\packages\FSPowerPack.Community.2.1.1.1\Lib\Net40\FSharp.PowerPack.dll</HintPath>
          <Private>True</Private>
        </Reference>
        <Reference Include="FSharp.PowerPack.Linq">
          <HintPath>..\packages\FSPowerPack.Community.2.1.1.1\Lib\Net40\FSharp.PowerPack.Linq.dll</HintPath>
          <Private>True</Private>
        </Reference>
        <Reference Include="FSharp.PowerPack.Metadata">
          <HintPath>..\packages\FSPowerPack.Community.2.1.1.1\Lib\Net40\FSharp.PowerPack.Metadata.dll</HintPath>
          <Private>True</Private>
        </Reference>
        <Reference Include="FSharp.PowerPack.Parallel.Seq">
          <HintPath>..\packages\FSPowerPack.Community.2.1.1.1\Lib\Net40\FSharp.PowerPack.Parallel.Seq.dll</HintPath>
          <Private>True</Private>
        </Reference>
        <Reference Include="HtmlAgilityPack">
          <HintPath>..\packages\HtmlAgilityPack.1.4.3\lib\HtmlAgilityPack.dll</HintPath>
          <Private>True</Private>
        </Reference>
        <Reference Include="mscorlib" />
        <Reference Include="FSharp.Core" />
        <Reference Include="System" />
        ...
        <Reference Include="System.Xml" />
        <Reference Include="System.Xml.Linq" />
        <Reference Include="MathNet.Numerics">
          <HintPath>..\packages\MathNet.Numerics.2.1.2\lib\Net40\MathNet.Numerics.dll</HintPath>
          <Private>True</Private>
        </Reference>
        <Reference Include="MathNet.Numerics.FSharp">
          <HintPath>..\packages\MathNet.Numerics.FSharp.2.1.2\lib\Net40\MathNet.Numerics.FSharp.dll</HintPath>
          <Private>True</Private>
        </Reference>
        <Reference Include="MSDN.FSharpChart">
          <HintPath>..\packages\MSDN.FSharpChart.dll.0.60\lib\MSDN.FSharpChart.dll</HintPath>
          <Private>True</Private>
        </Reference>
        <Reference Include="zlib.net">
          <HintPath>..\packages\zlib.net.1.0.3.0\lib\zlib.net.dll</HintPath>
          <Private>True</Private>
        </Reference>
    </ItemGroup>
    
    Значение тега <Private>true — значит, что все .dll будут скопированы в папку создаваемого с помощью шаблона проекта.
  7. Чтобы добавить исправленные файлы обратно в .zip-архив, нужно использовать Windows Explorer — просто выделите и перетащите их на .zip файл. Я понятия не имею, почему не работает добавление с помощью WinRar'а, но я смог добиться успеха в сём предприятии только так.
  8. Осталось только перетащить исправленный .zip архив с шаблоном в папку C:\Users\...\Documents\Visual Studio 2010\Templates\ProjectTemplates, и новый шаблон появится в диалоге создания нового проекта.
Ну и, как и было обещано, сам шаблон (или на github'e).
После создания проекта запустите компиляцию, чтобы VS нашла все библиотеки. Alt+Enter поможет вам проверить работу шаблона:
FSharpChart.Point
    [|
        let gaussian = new Normal()        
        for _ in 1..100 -> gaussian.Sample(), gaussian.Sample() |]

воскресенье, 10 июня 2012 г.

Формулы, подсветка синтаксиса и все-все-все

Так как планирую писать здесь не только о музыке, но и о технике, жизненно необходима поддержка TeX-а и подсветки синтаксиса для языков, которыми пользуюсь или планирую пользоваться: F#, C#, Erlang, Matlab/Octave и Python.

Встроил MathJax:
\[P(E) = {n \choose k} p^k (1-p)^{n-k}\tag{Cthulhu fhtagn!}\label{ref1}\]
Вот таким скриптом:
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  TeX: { equationNumbers: { autoNumber: "all" } }
});
</script>
<script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript">
</script>

В комментах тоже, конечно, работает, надо просто писать LaTeX-выражения вот так:
\[ ... \] для отдельных формул
\( ... \) для инлайна
И номера с ссылочками: \ref{ref1}, тоже. С разными — \eqref{ref1}.
А чтобы этот скрипт был вам нормально виден, надо было ещё вот это вставить:
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css"></link>
<!--SYNTAX HIGHLIGHTER BEGINS-->
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeFadeToGrey.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'/>
<script src='http://sites.google.com/site/lakretsh/home/brushErlang.js' type='text/javascript'/>
<script src='http://sites.google.com/site/lakretsh/home/brushFSharp.js' type='text/javascript'/>
<script language='javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = &#39;http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf&#39;;
SyntaxHighlighter.all();
</script>
<style type="text/css">
.syntaxhighlighter { overflow-y: hidden !important; }
</style>
<!--SYNTAX HIGHLIGHTER ENDS-->

Грязный трюк с brush для F# и Erlang я подсмотрел на сайте другого F#-разработчика xD

Кстати, Erlang:
%% qsort:qsort(List)
%% Sort a list of items
-module(qsort).     % This is the file 'qsort.erl'
-export([qsort/1]). % A function 'qsort' with 1 parameter is exported (no type, no name)
 
qsort([]) -> []; % If the list [] is empty, return an empty list (nothing to sort)
qsort([Pivot|Rest]) ->
    % Compose recursively a list with 'Front' for all elements that should be before 'Pivot'
    % then 'Pivot' then 'Back' for all elements that should be after 'Pivot'
    qsort([Front || Front <- Rest, Front < Pivot])
    ++ [Pivot] ++
    qsort([Back || Back <- Rest, Back >= Pivot]).

F#:
let asynctask = async
{
    let req = WebRequest.Create(url)
    let! response = req.GetResponseAsync()
    use stream = response.GetResponseStream()
    use streamreader = new System.IO.StreamReader(stream)
    return streamreader.ReadToEnd()
}

Потом надо будет добавить ещё Matlab, но пока лень и наплевать)

Печалька заключается только в том, что приходится редактировать код в HTML-редакторе, когда пишу посты с кодом — всякое такое:
<pre class="brush:html">
</pre>

<pre class="brush:f#">
</pre>

<pre class="brush:erl">
</pre>
добавлять на другой вкладке + для публикации html надо использовать вот такие штуки. Ну да ничего.

P.S. Для готовящихся постов по PGM я также добавил экспандеры.
Код экспандера в экспандере! :)
JavaScript:
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'/>
<script type='text/javascript'>
$(document).ready(function()
{
  $(&quot;.exp-content&quot;).hide();
  $(&quot;.exp-head&quot;).click(function()
  {
    $(this).next(&quot;.exp-content&quot;).slideToggle(200);
  });
});
</script>
CSS:
.exp-head {
padding: 1px 15px;
cursor: pointer;
margin: 5px 0px;
font-weight: bold;
}

.exp-content {
padding: 2px 15px;
background-color: whiteSmoke;
}

.exp {
margin: 0px 30px;
background-color: whiteSmoke;
color: black;
}
Использование:
<div class="exp">
<div class="exp-head">Заголовок</div>
<div class="exp-content">Текст</div>
</div>

Металл и вода I

Для большинства людей вполне характерно эмоциональное отношение к различным аспектам некой деятельности, которой они занимаются. Так как я являюсь довольно эмоциональным существом (и считаю это своим достоинством), в любых моих увлечениях есть вещи, которые я обожаю, и вещи, которые я ненавижу, — и говорить о первых гораздо интереснее, чем о вторых.

В саунддизайне есть ровно одна вещь, которая меня заводит, то самое, что заставило меня потратить около трёх лет на чтение различной литературы по теме, просмотр видеоуроков и бесчисленные ночные часы, собственно, саунддизайна — это модуляция. Я обожаю огибающие. Я болен LFO. Я схожу с ума от слов "keyscaling", "velocity", "cc" и "MIDI-mapping". И из этой моей страсти (ну, не только из неё, но всё же) непосредственно следует моя любовь к двум типам звуков, доминирующим в моём творчестве и доставляющим мне огромное удовольствие самим процессом своего создания: я люблю металлические лязганья, удары, "струны" (раз) и я люблю пэды (два).

Какая же связь между модуляцией и этими типами звуков? Let's take one at a time.

Металл

Металлические звуки в большинстве своём для неискушённого слушателя звучат безумно похоже. Тут тренькнуло, там звякнуло. Но нас ведь не интересуют неискушённые слушатели, правда? У фанатов Einstürzende Neubauten (к которым я отношусь)) свяо тмоасфреа — вы только послушайте это или это. Большинство этих звуков, тем не менее, получены вживую, а мы говорили о синтезе. Первая мысль у большинства саунддизайнеров при словах "металлический звук" — это мысль про FM-синтез. А FM-синтез — это много сложных модуляций! Например, вот такой простой звук, сделанный на коленке за 5 минут:

Metal Simple by Lakret
выглядит в синтезаторе примерно так:
Ладно, это не особо интересно. А если увеличить атаку и ПИЗДАНУТЬ РЕВЕРБА?))
При желании из этого простенького звука можно легко сделать очень психоделические вещи:
Но интереснее то, что произойдёт с этим звуком, если мы немножко поиграемся с огибающими. Было так:

Стало так:

И звучит это вот так (без БЕЗУМИЯ):
Metal env 1 by Lakret
(с БЕЗУМИЕМ):
Metal env 1b by Lakret
Wow, не правда ли?)
To be continued... 


P.S. Btw, если вам понравилось наше маленькое путешествие, а точнее — звуки, которые получились, вам стоит послушать это.

пятница, 8 июня 2012 г.

Week 1: Non-uniform

Metalizer: "Just this sound but a bit more metallic"

Simple Delay to the rescue!

От ваших заблуждений умирают няшные котики!

Каждый раз, когда в общей, среднестатистической дискуссии произносится слово "Вера" (именно так, с ужасающей заглавной буквы), все, по (ещё) неписанному сценарию, должны сделать постные мины и закатить глаза (в некоторых культурах нужно сразу упасть на колени и начать биться в конвульсиях, но пока такие культуры, к счастью, не являются среднестатистическими). Даже у многих атеистов в голове есть дурацкая установка про уважение к вере (на ещё одну заглавную букву для этого слова у меня сил уже не хватило). Но что такое "вера" и заслуживает ли она такого уважения или изображения оного?

В сухом остатке, без истеричных воплей, крёстных знамений и молитвенных стояний, вера — это всего-навсего победа эгоцентризма над разумом. Примеры веры и верующих:

  1. Глядя на белое — видеть чёрное, или же и чёрное, и белое, или же, в зависимости от текущей линии партии, видеть любой цвет, звук, запах и вкус (знакомо?).
  2. Неправильно решив математический пример, уверовать, что полученный ответ истинно правильный, а все, кто говорят обратное — еретики; учебник матанализа же — діавольская книга, которую надобно сжечь, аминь.
  3. Не зная ничего в некой предметной области, требовать от людей, ею занимающихся, по выбору верующего: немедленно прекратить ею заниматься, немедленно принять их правильную точку зрения на любой вопрос, касающийся сей предметной области, немедленно покаяться, немедленно совершить 40 (число может варьироваться, необходима консультация специалиста) поясных поклонов.
  4. Столкнувшись с любой сложной этической проблемой, вы будете думать, обсуждать и прочими смехотворными образами терять время, а верующий уже знает её решение! Удивительным образом, оно совпадает (опять же, по выбору верующего): с наиболее удобным для самого верующего, с наиболее приятной для верующего интерпретацией вырванных из исторического контекста фрагментов некоторой (опять же, по выбору верующего) книги, журнала, статьи, надписи на заборе, с мнением богов, выраженном в количеством костей журавля, всплывших на поверхность после пятичасовой варки.
  5. Встретившись с любым мнением, неприятным ему, верующий возопит — "оно оскорбляет мои чувства" (кстати говоря, это отличный индикатор любых верующих — они всегда обижены и оскорблены самим существованием с ними несогласных).
Именно вот это всё вы, дорогие мои, должны уважать, именно к этому вы должны чувствовать священный трепет. Не получается? Не беспокойтесь, скоро получится.

Дадим, на секунду, слово самим верующим: "Но как же пророчества, древние книги, мои прекрасные аргументы, слова бабки Клавы?!". Вы таки не поверите, дорогие верующие, но если в качестве оправдания для всего вышеперечисленного поведения вы опираетесь на некое "доказательство", это уже не вера по определению. Если у вас есть неопровержимые (или ещё не опровергнутые) доказательства чего-то, то это уже не вера — это знание. Но, в таком случае, если ваши аргументы будут разбиты, а доказательства низвергнуты, вам придётся признать ошибочность своего мнения. Если же вы в любом случае считаете, что ваше мнение верно, и продолжите так считать, даже если это противоречит логике, здравому смыслу, фактам и непосредственным ощущениям, — попытки "доказать" что-то априори будут смехотворными и не принесут вам ничего, кроме дополнительных проблем и разочарований.

Что же делать? Я не призываю унижать, дискриминировать или каким-либо другим образом причинять вред верующим. Я считаю, что главная, наиважнейшая задача атеистического сообщества — заниматься образованием окружающих, прививать им любовь к знанию, показывать им, насколько смехотворно и глупо выглядит ни на чём не основанная убеждённость. Мы должны разрушить древний миф про "святость" веры, ибо вера — это всего лишь высшая форма разрушительного эгоизма.


P.S. Для тех, кто не умеет читать (для тебя, да, ты!): я говорю об явлении, называемом "верой", вообще, а не об отдельных, пусть и наиболее вопиющих, проявлениях.