<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Unbounded Engineering</title>
		<description>Software Development and Engineering</description>
		<link></link>
		<atom:link href="/feed.xml" rel="self" type="application/rss+xml" />
		
			<item>
				<title>WPF in 2020: Concepts and Responsibilities of MVVM</title>
				<description>&lt;h1 id=&quot;concepts&quot;&gt;Concepts&lt;/h1&gt;
&lt;p&gt;Model-View-ViewModel (MVVM) architecture is a commonly used pattern in XAML frameworks to implement the design principle of Separation of Concerns (SoC). While the number of components will grow compared to a solution which uses the View’s code-behind for everything, each component in an MVVM application will be much simpler and specific. The result is an application that is easier to maintain, test, and develop as the application’s complexity grows. The tradeoff is that MVVM has a learning curve and adds a degree of mostly fixed, one-time complexity cost when starting a project.&lt;/p&gt;

&lt;h1 id=&quot;responsibilities&quot;&gt;Responsibilities&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;/assets/images/wpf-mvvm/MVVM-Flowchart-Large.png&quot; alt=&quot;MVVM Flowchart&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The above image demonstrates the dependency relationships for MVVM: The View knows the ViewModel and the ViewModel knows the Model (or Service Layer). Equally important is that the Model does not know about the View or ViewModel and the ViewModel does not know about the View.&lt;/p&gt;

&lt;h2 id=&quot;view&quot;&gt;View&lt;/h2&gt;
&lt;p&gt;The View includes the visual layout, control behavior, control appearance, control events, and raw user input events. The View is your code/XAML that directly targets a specific GUI framework, any extensions created to establish compatibility with your ViewModels, as well as the GUI framework itself.&lt;/p&gt;

&lt;h2 id=&quot;viewmodel&quot;&gt;ViewModel&lt;/h2&gt;
&lt;p&gt;The ViewModel (VM) is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class&lt;/code&gt; that contains methods to invoke and properties to bind to from the View. The VM also knows how to perform operations on the Model, either directly or indirectly through an application service layer. Ideally, the VM code should strive to look like neutral C# code with three exceptions:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The VM should implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INotifyPropertyChanged&lt;/code&gt;. Most often this is done by inheriting a base class like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PropertyChangedBase&lt;/code&gt; shown later.&lt;/li&gt;
  &lt;li&gt;Properties that are updated from the VM and trigger a View update must raise the &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-implement-property-change-notification&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PropertyChanged&lt;/code&gt;&lt;/a&gt; event.&lt;/li&gt;
  &lt;li&gt;Methods on the VM to be invoked by the View should be wrapped in an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ICommand&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Some MVVM Frameworks such as &lt;a href=&quot;https://github.com/canton7/Stylet&quot;&gt;Stylet&lt;/a&gt; allow you to skip point 3 and write even more neutral VMs.&lt;/p&gt;

&lt;p&gt;Scenarios that are good VM commands:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Pause/Play music&lt;/li&gt;
  &lt;li&gt;Undo/Redo commands with complex changes&lt;/li&gt;
  &lt;li&gt;Removing an item from a collection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Scenarios that are within the View’s responsibility:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;A button was hovered and should be highlighted&lt;/li&gt;
  &lt;li&gt;A mouse click event containing View pixel locations&lt;/li&gt;
  &lt;li&gt;A ListBox event when a selected item has changed (more appropriately solved via bindings)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;model&quot;&gt;Model&lt;/h2&gt;
&lt;p&gt;The Model is the most ambiguously defined component of MVVM. Most often, the Model is regarded a database entity. Other times, they were mixed with DTOs (data transfer objects), domain objects, POCOs (Plain Old CLR Objects), or even the application services layer itself. I prefer a more broadly defined concept of the Model:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;The Model is an external source of truth.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This means that changes made within the View and VM are not realized until the changes are synchronized with the Model. Furthermore, isolating your Model is key to not letting application logic leak into your GUI. Being external to your ViewModel, this approach isolates your core problem solving code into a happy little island that is loosely coupled from the Desktop, Mobile, Console, and Web. Your most vital code will have better testability and survive technology transitions.&lt;/p&gt;

&lt;h1 id=&quot;auxillary-mvvm-components&quot;&gt;Auxillary MVVM Components&lt;/h1&gt;

&lt;h2 id=&quot;inotifypropertychanged&quot;&gt;INotifyPropertyChanged&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifypropertychanged&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INotifyPropertyChanged&lt;/code&gt;&lt;/a&gt; (INPC) is a core concept for all XAML-based frameworks and alerts the View when an update has occurred in the ViewModel. The typical INPC boilerplate is often wrapped into reusable class commonly named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PropertyChangedBase&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewModelBase&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PropertyChangedBase&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INotifyPropertyChanged&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PropertyChangedEventHandler&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;OnPropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CallerMemberName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;propertyName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PropertyChangedEventArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;propertyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SetField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CallerMemberName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;propertyName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EqualityComparer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Equals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;OnPropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;propertyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Usage of this class will be demonstrated in the sample implementations in the next article. The basic idea is to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SetField&lt;/code&gt; within the property setter. Besides the property declarations themselves, properties are used in a natural fashion. The equality check prevents recursive updates that could lead to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StackOverflowException&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;icommand&quot;&gt;ICommand&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.windows.input.icommand&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ICommand&lt;/code&gt;&lt;/a&gt; is another core concept and is how the View executes methods on a ViewModel. Like INPC, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ICommand&lt;/code&gt; boilerplate is also commonly wrapped into reusable classes such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RelayCommand&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RelayCommand&amp;lt;T&amp;gt;&lt;/code&gt; shown below:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RelayCommand&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICommand&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Action&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_execute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_canExecute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EventHandler&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CanExecuteChanged&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CommandManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RequerySuggested&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;remove&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CommandManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RequerySuggested&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RelayCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Action&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;methodToExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;_execute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;methodToExecute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ArgumentNullException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;nameof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;methodToExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RelayCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Action&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;methodToExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canExecuteEvaluator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;methodToExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;_canExecute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canExecuteEvaluator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ArgumentNullException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;nameof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;canExecuteEvaluator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CanExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_canExecute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_canExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DebuggerStepThrough&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nf&quot;&gt;_execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RelayCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICommand&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_execute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Predicate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_canExecute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RelayCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;_execute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ArgumentNullException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;nameof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RelayCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Predicate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;_canExecute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canExecute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ArgumentNullException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;nameof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;canExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CanExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_canExecute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsValueType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_canExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_canExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EventHandler&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CanExecuteChanged&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CommandManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RequerySuggested&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;remove&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CommandManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RequerySuggested&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DebuggerStepThrough&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nf&quot;&gt;_execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;value-converters&quot;&gt;Value Converters&lt;/h2&gt;
&lt;p&gt;Often your ViewModels exposes types that the View does not know how to interpret. Instead of modifying your ViewModel to expose View-friendly properties, Value Converters extend the View to become compatible with the ViewModel. One common built-in WPF converter is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BooleanToVisibilityConverter&lt;/code&gt; which converts a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bool&lt;/code&gt; type exposed by the VM to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Visibility&lt;/code&gt; enum that View controls understand.&lt;/p&gt;

&lt;h2 id=&quot;event-aggregator&quot;&gt;Event Aggregator&lt;/h2&gt;
&lt;p&gt;Most MVVM Frameworks will have an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IEventAggregator&lt;/code&gt; implementation with a subscribe/publish event model to help VMs communicate one-way messages between each other. This is particularly valuable in deeply nested hierarchies to cut across layers where VMs may not easily reference one another.&lt;/p&gt;

&lt;h2 id=&quot;window-manager&quot;&gt;Window Manager&lt;/h2&gt;
&lt;p&gt;Another common MVVM Framework feature is a Window Manager. This component helps allows your ViewModel code to show dialogs and windows without explicitly referencing the View.&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/xamarin/xamarin-forms/enterprise-application-patterns/mvvm&quot;&gt;Xamarin.Forms MVVM&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/Insire/Maple/blob/master/src/Maple.Core/Commands/RelayCommand.cs&quot;&gt;RelayCommand&lt;/a&gt; implementation from &lt;a href=&quot;https://github.com/Insire/Maple&quot;&gt;Maple&lt;/a&gt;&lt;/p&gt;
</description>
				<pubDate>Fri, 14 Aug 2020 20:00:00 +0000</pubDate>
				<link>/2020/08/wpf-2020-part2-mvvm-overview/</link>
				<guid isPermaLink="true">/2020/08/wpf-2020-part2-mvvm-overview/</guid>
			</item>
		
			<item>
				<title>WPF in 2020: .NET GUI Framework Survey</title>
				<description>&lt;p&gt;So it is 2020 and presumably you are a newcomer to C# confused by the myriad of GUI options available to you in the quickly changing .NET ecosystem. Before diving into WPF in future articles, this article will examine the pros and cons of the most viable GUI frameworks and where they work so you can determine if WPF is viable for your project. Finally, I will address the shakeup that Microsoft introduced in Build 2020.&lt;/p&gt;

&lt;p&gt;I will separate GUI frameworks into two categories: Codegen-based and XAML-based. Web-based approaches such as ASP.NET Core with JS-based frontends (Vue.js, React, Angular) and Blazor will not be discussed here.&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;code-generation-frameworks&quot;&gt;Code Generation Frameworks&lt;/h1&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;windows-forms&quot;&gt;Windows Forms&lt;/h2&gt;
&lt;p&gt;Most newcomers and many college-level C# GUI courses choose this framework when getting started and that is a mistake. While WinForms has the best drag-and-drop GUI editor of all major .NET GUI frameworks, it also has the worst out-of-the-box controls and extensibility. Introduced in 2002, WinForms is an extensive wrapper around Win32API. As such, customization beyond the built-in control features often requires specific Win32API knowledge to change behavior or customize appearance, dealing with flickering issues, or even redrawing the entire control from scratch. Then you may also need to write additional code to support your customization in the WinForms Designer if you want correct visualization in the Designer.&lt;/p&gt;

&lt;h3 id=&quot;compatibility&quot;&gt;Compatibility&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;.NET Framework and .NET Core 3+&lt;/li&gt;
  &lt;li&gt;Windows Desktop&lt;/li&gt;
  &lt;li&gt;Cross-platform with many caveats via Mono&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;pros&quot;&gt;Pros&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Easiest start because of the WinForms Designer&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons&quot;&gt;Cons&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Very difficult to customize&lt;/li&gt;
  &lt;li&gt;Data binding is limited and awkward&lt;/li&gt;
  &lt;li&gt;Encourages code coupling leading to poor testability and poor maintainability&lt;/li&gt;
  &lt;li&gt;Creating dynamic collections of controls in WinForms often requires code and defeats the point of the Designer&lt;/li&gt;
  &lt;li&gt;Poor transparency support and tough to troubleshoot redraw flickering&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;verdict&quot;&gt;Verdict&lt;/h3&gt;
&lt;p&gt;There is only one set of conditions where using WinForms is viable: 1. You don’t care about UI appearance or behavior beyond the limited WinForms controls, 2. You don’t care about maintainability, and 3. You do not have time to go through the learning curve of a better UI framework. I like to say that WinForms makes the first 20% of an application very easy and the last 80% very hard. As your app’s complexity grows, the architecture around WinForms is not up to the task. There are some third-party commercial control libraries to help ease the pain, but they’re not for everybody.&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;xaml-frameworks&quot;&gt;XAML Frameworks&lt;/h1&gt;
&lt;p&gt;These frameworks use an XML-based language called Extensible Application Markup Languages (XAML) to define the view. User interfaces are inherently hierarchical with many parent-child relationships so XAML is a good fit to define the UI as opposed to code generation which is much more flat. Furthermore, XAML allows easy runtime generation of collections of controls through data templates and data binding. Most XAML frameworks have support for Hot Reload which allows you to launch the application via your IDE, edit XAML, and see updates live as your app is running. These features and more have made XAML the mainstay of most .NET GUI offerings.&lt;/p&gt;

&lt;p&gt;Many developers pair XAML Frameworks with the MVVM (Model-View-ViewModel) architecture. This architecture allows the ViewModel, a C# class that contains data to display and executable commands, to be separated from the XAML-based View which contains the UI control hierarchy and styling. With care, these ViewModels have potential portability to other XAML-based frameworks and are unit testable. One common practice is to target desktop with a WPF or UWP project and target mobile with a Xamarin project while using the same ViewModel.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;windows-presentation-foundation&quot;&gt;Windows Presentation Foundation&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/framework/wpf/introduction-to-wpf&quot;&gt;WPF&lt;/a&gt; was released in late 2006 and Microsoft learned from many flaws within WinForms. First, WPF detaches from Win32API and is built from the ground up using DirectX. Second, WPF introduced XAML which is a markup language performing a similar role as HTML in isolating view code. Last, good data binding was introduced to eliminate a significant portion of glue code and data templates solved the problem of writing code to dynamically generate collections of controls.&lt;/p&gt;

&lt;h3 id=&quot;compatibility-1&quot;&gt;Compatibility&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;.NET Framework and .NET Core 3+&lt;/li&gt;
  &lt;li&gt;Windows Desktop only&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;pros-1&quot;&gt;Pros&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Mature ecosystem with many articles and StackOverflow posts&lt;/li&gt;
  &lt;li&gt;Excellent community libraries&lt;/li&gt;
  &lt;li&gt;Flexible customization&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons-1&quot;&gt;Cons&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Restricted to Windows Desktop&lt;/li&gt;
  &lt;li&gt;WPF Designer is a trap and not worth using&lt;/li&gt;
  &lt;li&gt;Steep learning curve with pitfalls&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;verdict-1&quot;&gt;Verdict&lt;/h3&gt;
&lt;p&gt;WPF is a mature, flexible GUI framework that is still good for developing Windows Desktop apps today. There is no uncertainty about the future since WPF is deep into maintenance mode with only bug fixes and minor updates. The default styling may look a bit dated, but excellent styling libraries created by the community have helped modernize its look.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;universal-windows-platform&quot;&gt;Universal Windows Platform&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/windows/uwp/get-started/universal-application-platform-guide&quot;&gt;UWP&lt;/a&gt; for Windows 10 is Microsoft’s successor to WPF. Initially stumbling with its identity and Microsoft’s failed push at Windows 10 Phone, UWP did not capture the Windows developer scene despite its improved offerings in features. Like WPF, it also uses XAML for designing views and has GPU hardware acceleration.&lt;/p&gt;

&lt;h3 id=&quot;compatibility-2&quot;&gt;Compatibility&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;.NET Framework and .NET Core 3+&lt;/li&gt;
  &lt;li&gt;Windows 10: Desktop, Phone, XBox One, HoloLens, IoT&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;pros-2&quot;&gt;Pros&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Improves upon WPF features with Compiled Bindings, XAML Islands, Input Gestures, new controls, and more&lt;/li&gt;
  &lt;li&gt;Modern styling out-of-the-box&lt;/li&gt;
  &lt;li&gt;Simplest path to Microsoft Store&lt;/li&gt;
  &lt;li&gt;Multiple language support: C#, C++, VB, and JS&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons-2&quot;&gt;Cons&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Unclear future&lt;/li&gt;
  &lt;li&gt;Limited to Windows 10&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;verdict-2&quot;&gt;Verdict&lt;/h3&gt;
&lt;p&gt;UWP is, for the time being, the premiere Microsoft offering for Windows Desktop GUI.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;avalonia&quot;&gt;Avalonia&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://avaloniaui.net/&quot;&gt;Avalonia&lt;/a&gt; is a recent community-developed GUI framework. Its main focus is providing cross-platform support.&lt;/p&gt;

&lt;h3 id=&quot;compatibility-3&quot;&gt;Compatibility&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;.NET Framework 4.61+ and .NET Core 2+&lt;/li&gt;
  &lt;li&gt;Windows, Linux, and OSX Desktop&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;pros-3&quot;&gt;Pros&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Cross-Platform&lt;/li&gt;
  &lt;li&gt;Reasonable docs for third-party open source&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons-3&quot;&gt;Cons&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Mobile support still experimental&lt;/li&gt;
  &lt;li&gt;Relative lack of detailed articles and StackOverflow posts compared to WPF and UWP&lt;/li&gt;
  &lt;li&gt;Less options for third-party styling and controls&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;verdict-3&quot;&gt;Verdict&lt;/h3&gt;
&lt;p&gt;Strongly consider Avalonia if your main concern is a cross-platform Desktop GUI.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;xamarinforms&quot;&gt;Xamarin.Forms&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/xamarin/get-started/what-is-xamarin-forms&quot;&gt;Xamarin.Forms&lt;/a&gt; (and Xamarin in general) is Microsoft’s cross-platform offering to primarily target mobile though desktop options are available.&lt;/p&gt;

&lt;h3 id=&quot;compatibility-4&quot;&gt;Compatibility&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;iOS 9+&lt;/li&gt;
  &lt;li&gt;Android 4.4 (API 19)+ or Android 5.0 (API 21)+ recommended&lt;/li&gt;
  &lt;li&gt;Windows 10 UWP&lt;/li&gt;
  &lt;li&gt;GTK#, macOS, and WPF targets under development with mixed levels of support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;pros-4&quot;&gt;Pros&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Transforms UI elements into native controls with native styling&lt;/li&gt;
  &lt;li&gt;Easy to pull in Xamarin.Essentials for mobile system features&lt;/li&gt;
  &lt;li&gt;Allows platform-specific behavior for Android and iOS&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons-4&quot;&gt;Cons&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Requires VS for Mac to target iOS and macOS&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;verdict-4&quot;&gt;Verdict&lt;/h3&gt;
&lt;p&gt;Xamarin.Forms is a good approach when mobile targeting is your primary need, but some Desktop targets are also available. In late 2021, Xamarin.Forms is planned to be transition into (or rebranded as) a part of MAUI.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;uno-platform&quot;&gt;Uno Platform&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://platform.uno/&quot;&gt;Uno Platform&lt;/a&gt; is another relative newcomer developing a cross-platform solution for the .NET GUI ecosystem. Uno achieves non-Windows support by relying upon Xamarin and the Mono-Wasm runtime and supports Windows 10 through UWP/WinUI. I will not discuss Pros and Cons as I’m not familiar enough with Uno.&lt;/p&gt;

&lt;h3 id=&quot;compatibility-5&quot;&gt;Compatibility&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Windows 10 (UWP/WinUI)&lt;/li&gt;
  &lt;li&gt;iOS&lt;/li&gt;
  &lt;li&gt;macOS&lt;/li&gt;
  &lt;li&gt;Android&lt;/li&gt;
  &lt;li&gt;WebAssembly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;verdict-5&quot;&gt;Verdict&lt;/h3&gt;
&lt;p&gt;This is an up-and-coming framework to keep your eye on and experiment with. Has potential to be the broadest targeting GUI framework until MAUI is released.&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id=&quot;abandoned-technologies&quot;&gt;Abandoned Technologies&lt;/h1&gt;
&lt;p&gt;Silverlight and WebForms are no longer being maintained and should never be considered for use.&lt;/p&gt;

&lt;h2 id=&quot;build-2020&quot;&gt;Build 2020&lt;/h2&gt;
&lt;p&gt;During Build 2020, Microsoft announced three major GUI-related projects: &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/apps/winui/winui3/get-started-winui3-for-desktop&quot;&gt;WinUI 3&lt;/a&gt;, &lt;a href=&quot;https://github.com/dotnet/maui&quot;&gt;MAUI&lt;/a&gt;, and &lt;a href=&quot;https://github.com/microsoft/ProjectReunion&quot;&gt;Project Reunion&lt;/a&gt;. WinUI 3 is the next version of native Windows UI controls and isolates controls from UWP to make them available across non-UWP frameworks. MAUI (.NET Multi-platform App UI) will be the successor of Xamarin.Forms, but much more flexible in targeting other platforms in a true cross-platform attempt to compete with non-.NET techs like Flutter and Electron. Project Reunion is Microsoft’s unification of framework-specific APIs, especially from UWP. Microsoft’s plan to decouple these features from OS versions and make them available via NuGet will solve some OS versioning headaches. Older technologies (WinForms, WPF) and non-.NET programming languages will also be able to take advantage of the newest features.&lt;/p&gt;
</description>
				<pubDate>Wed, 12 Aug 2020 08:00:00 +0000</pubDate>
				<link>/2020/08/wpf-2020-part1-survey/</link>
				<guid isPermaLink="true">/2020/08/wpf-2020-part1-survey/</guid>
			</item>
		
			<item>
				<title>Practical Calculation of Daubechies Wavelet and Scaling Functions</title>
				<description>&lt;h1 id=&quot;background&quot;&gt;Background&lt;/h1&gt;
&lt;p&gt;Daubechies Wavelets are a family of orthogonal wavelets which are recursively-defined. They are discrete functions where each level of approximation fills in midpoints between points across calculated from the previous level and, in the infinite limit, becomes continuous. There are two equivalent nomenclatures: DX and dbX. The db4 (D8) wavelet contains 4 vanishing moments and 8 taps (coefficients) over the non-zero interval \( (0, 7) \). These are always related by a factor of 2. From here on, only the dbX nomenclature will be used where the wavelet index is X.&lt;/p&gt;

&lt;h1 id=&quot;approach&quot;&gt;Approach&lt;/h1&gt;
&lt;p&gt;A floating point approach is used for simplicity over the dyadic approach which uses fractional powers of two, \( r = n / {2^L} \), to derive values of r at the next recursion level. A combination of C# and Python were used to generate the figures and data shown. Python was used when necessary for its superior support for matrix solvers. Links to the project’s online source code is provided at the end of the post and is generalized up to at least db10.&lt;/p&gt;

&lt;p&gt;This article aims only to demonstrate the calculation of the wavelet and scaling function which are not well-explained in any of the many sources I’ve read. No theory, mathematical proofs, or description of the related wavelet transform will be given as those are covered elsewhere. The db4 wavelet will serve as the primary example here because the db2 wavelet is the dominant example in the literature. Values for wavelets other than db4 will occasionally be given to serve as an aid to general implementation.&lt;/p&gt;

&lt;h1 id=&quot;symbol-definitions&quot;&gt;Symbol Definitions&lt;/h1&gt;
&lt;p&gt;𝜑(r) - Scaling function at point r&lt;br /&gt;
𝜓(r) - Wavelet function at point r&lt;br /&gt;
N - number of Daubechies cofficients for the given wavelet&lt;br /&gt;
k - coefficient index&lt;br /&gt;
\( a_k \) - kth scaling coefficient&lt;br /&gt;
\( b_k \) - kth wavelet coefficient&lt;br /&gt;
\( L_x \) - xth level of approximation&lt;br /&gt;
\( P_x \) - Number of points at the xth level of approximation&lt;/p&gt;

&lt;h1 id=&quot;core-equations&quot;&gt;Core Equations&lt;/h1&gt;
&lt;p&gt;Initial Values for Scaling Function&lt;br /&gt;
\( \begin{cases}&lt;br /&gt;
𝜑(r) = \sum\limits_{k=0}^{N-1} a_k 𝜑(2r - k) \\&lt;br /&gt;
\sum\vec{𝜑} = 1&lt;br /&gt;
\end{cases}&lt;br /&gt;
\)&lt;/p&gt;

&lt;p&gt;Scaling Function &lt;br /&gt;
\( 𝜑(r) = \sum\limits_{k=0}^{N-1} a_k 𝜑(2r - k) \)&lt;/p&gt;

&lt;p&gt;Wavelet Function&lt;br /&gt;
\( 𝜓(r) = \sum\limits_{k=0}^{N-1} b_k 𝜑(2r - k) \)&lt;/p&gt;

&lt;h1 id=&quot;visualization&quot;&gt;Visualization&lt;/h1&gt;
&lt;p&gt;The images below demonstrate db2 and db4 wavelets being recursively filled from 0 to 8 levels of approximation.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/db2wavelet-dark.webp&quot; alt=&quot;db2&quot; /&gt;&lt;br /&gt;
db2 wavelet and scaling functions&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/db4wavelet-dark.webp&quot; alt=&quot;db4&quot; /&gt;&lt;br /&gt;
 db4 wavelet and scaling functions&lt;/p&gt;

&lt;h2 id=&quot;number-of-points-at-various-levels-of-approximation&quot;&gt;Number of points at various levels of approximation&lt;/h2&gt;
&lt;p&gt;\( P_L = P_0 * 2^L - (2^L - 1) \)&lt;/p&gt;

&lt;table class=&quot;left&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;0&lt;/th&gt;
      &lt;th&gt;1&lt;/th&gt;
      &lt;th&gt;2&lt;/th&gt;
      &lt;th&gt;3&lt;/th&gt;
      &lt;th&gt;4&lt;/th&gt;
      &lt;th&gt;5&lt;/th&gt;
      &lt;th&gt;6&lt;/th&gt;
      &lt;th&gt;7&lt;/th&gt;
      &lt;th&gt;8&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;db2&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;7&lt;/td&gt;
      &lt;td&gt;13&lt;/td&gt;
      &lt;td&gt;25&lt;/td&gt;
      &lt;td&gt;49&lt;/td&gt;
      &lt;td&gt;97&lt;/td&gt;
      &lt;td&gt;193&lt;/td&gt;
      &lt;td&gt;385&lt;/td&gt;
      &lt;td&gt;769&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;db3&lt;/td&gt;
      &lt;td&gt;6&lt;/td&gt;
      &lt;td&gt;11&lt;/td&gt;
      &lt;td&gt;21&lt;/td&gt;
      &lt;td&gt;41&lt;/td&gt;
      &lt;td&gt;81&lt;/td&gt;
      &lt;td&gt;161&lt;/td&gt;
      &lt;td&gt;321&lt;/td&gt;
      &lt;td&gt;641&lt;/td&gt;
      &lt;td&gt;1281&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;db4&lt;/td&gt;
      &lt;td&gt;8&lt;/td&gt;
      &lt;td&gt;15&lt;/td&gt;
      &lt;td&gt;29&lt;/td&gt;
      &lt;td&gt;57&lt;/td&gt;
      &lt;td&gt;113&lt;/td&gt;
      &lt;td&gt;225&lt;/td&gt;
      &lt;td&gt;449&lt;/td&gt;
      &lt;td&gt;897&lt;/td&gt;
      &lt;td&gt;1793&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;db5&lt;/td&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;19&lt;/td&gt;
      &lt;td&gt;37&lt;/td&gt;
      &lt;td&gt;73&lt;/td&gt;
      &lt;td&gt;145&lt;/td&gt;
      &lt;td&gt;289&lt;/td&gt;
      &lt;td&gt;577&lt;/td&gt;
      &lt;td&gt;1153&lt;/td&gt;
      &lt;td&gt;2305&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;db6&lt;/td&gt;
      &lt;td&gt;12&lt;/td&gt;
      &lt;td&gt;23&lt;/td&gt;
      &lt;td&gt;45&lt;/td&gt;
      &lt;td&gt;89&lt;/td&gt;
      &lt;td&gt;177&lt;/td&gt;
      &lt;td&gt;353&lt;/td&gt;
      &lt;td&gt;705&lt;/td&gt;
      &lt;td&gt;1409&lt;/td&gt;
      &lt;td&gt;2817&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;evaluating-via-c&quot;&gt;Evaluating via C#&lt;/h2&gt;
&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PointsAtLevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zeroLevelPoints&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;zeroLevelPoints&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;daubechies-coefficients&quot;&gt;Daubechies Coefficients&lt;/h1&gt;
&lt;p&gt;Daubechies coefficients for the scaling function are frequently given in texts and are given here as a table. The calculation of the scaling coefficients may be covered in a future blog. Briefly, the calculation involves a matrix solver with multiple constraints (&lt;a href=&quot;https://simple.wikipedia.org/wiki/Daubechies_wavelet&quot;&gt;example&lt;/a&gt;) and yields multiple solutions. The final constraint is the convention that the chosen solution is the one which has the largest values front-loaded. This is known as the extremal phase. The sum of coefficients for a given wavelet index is often normalized to 1 and this is the case here.&lt;/p&gt;

&lt;h2 id=&quot;scaling-function-coefficients&quot;&gt;Scaling function coefficients&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;\(a_0\)&lt;/th&gt;
      &lt;th&gt;\(a_1\)&lt;/th&gt;
      &lt;th&gt;\(a_2\)&lt;/th&gt;
      &lt;th&gt;\(a_3\)&lt;/th&gt;
      &lt;th&gt;\(a_4\)&lt;/th&gt;
      &lt;th&gt;\(a_5\)&lt;/th&gt;
      &lt;th&gt;\(a_6\)&lt;/th&gt;
      &lt;th&gt;\(a_7\)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;db2&lt;/td&gt;
      &lt;td&gt;0.6830127&lt;/td&gt;
      &lt;td&gt;1.1830127&lt;/td&gt;
      &lt;td&gt;0.3169873&lt;/td&gt;
      &lt;td&gt;-0.1830127&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;db3&lt;/td&gt;
      &lt;td&gt;0.47046721&lt;/td&gt;
      &lt;td&gt;1.14111692&lt;/td&gt;
      &lt;td&gt;0.650365&lt;/td&gt;
      &lt;td&gt;-0.19093442&lt;/td&gt;
      &lt;td&gt;-0.12083221&lt;/td&gt;
      &lt;td&gt;0.0498175&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;db4&lt;/td&gt;
      &lt;td&gt;0.32580343&lt;/td&gt;
      &lt;td&gt;1.01094572&lt;/td&gt;
      &lt;td&gt;0.89220014&lt;/td&gt;
      &lt;td&gt;-0.03957503&lt;/td&gt;
      &lt;td&gt;-0.26450717&lt;/td&gt;
      &lt;td&gt;0.0436163&lt;/td&gt;
      &lt;td&gt;0.0465036&lt;/td&gt;
      &lt;td&gt;-0.01498699&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;wavelet-function-coefficients&quot;&gt;Wavelet function coefficients&lt;/h2&gt;
&lt;p&gt;Wavelet function coefficients are directly derived from the scaling function coefficients via the relationship \( b_k = (-1)^k * a_{N-1-k} \)&lt;/p&gt;

&lt;p&gt;The db4 wavelet coefficients calculations in detail:&lt;/p&gt;

&lt;p&gt;\(b_0 = (-1)^0 * a_{8-1-0} = 1 * a_7 = -0.01498699\)&lt;br /&gt;
\(b_1 = (-1)^1 * a_{8-1-1} = -1 * a_6 = -0.0465036\)&lt;br /&gt;
\(b_2 = (-1)^2 * a_{8-1-2} = 1 * a_5 = 0.0436163\)&lt;br /&gt;
\(b_3 = (-1)^3 * a_{8-1-3} = -1 * a_4 = 0.26450717\)&lt;br /&gt;
\(b_4 = (-1)^4 * a_{8-1-4} = 1 * a_3 = -0.03957503\)&lt;br /&gt;
\(b_5 = (-1)^5 * a_{8-1-5} = -1 * a_2 = -0.89220014\)&lt;br /&gt;
\(b_6 = (-1)^6 * a_{8-1-6} = 1 * a_1 = 1.01094572\)&lt;br /&gt;
\(b_7 = (-1)^7 * a_{8-1-7} = -1 * a_0 = -0.32580343\)&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;\(b_0\)&lt;/th&gt;
      &lt;th&gt;\(b_1\)&lt;/th&gt;
      &lt;th&gt;\(b_2\)&lt;/th&gt;
      &lt;th&gt;\(b_3\)&lt;/th&gt;
      &lt;th&gt;\(b_4\)&lt;/th&gt;
      &lt;th&gt;\(b_5\)&lt;/th&gt;
      &lt;th&gt;\(b_6\)&lt;/th&gt;
      &lt;th&gt;\(b_7\)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;db2&lt;/td&gt;
      &lt;td&gt;-0.1830127&lt;/td&gt;
      &lt;td&gt;-0.3169873&lt;/td&gt;
      &lt;td&gt;1.1830127&lt;/td&gt;
      &lt;td&gt;-0.6830127&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;db3&lt;/td&gt;
      &lt;td&gt;0.0498175&lt;/td&gt;
      &lt;td&gt;0.12083221&lt;/td&gt;
      &lt;td&gt;-0.19093442&lt;/td&gt;
      &lt;td&gt;-0.650365&lt;/td&gt;
      &lt;td&gt;1.14111692&lt;/td&gt;
      &lt;td&gt;-0.4704672&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;db4&lt;/td&gt;
      &lt;td&gt;-0.01498699&lt;/td&gt;
      &lt;td&gt;-0.0465036&lt;/td&gt;
      &lt;td&gt;0.0436163&lt;/td&gt;
      &lt;td&gt;0.26450717&lt;/td&gt;
      &lt;td&gt;-0.03957503&lt;/td&gt;
      &lt;td&gt;-0.8922001&lt;/td&gt;
      &lt;td&gt;1.01094568&lt;/td&gt;
      &lt;td&gt;-0.325803429&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ToWaveletCoefficients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scalingCoefficients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;scalingCoefficients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coef&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;calculation-of-scaling-function-initial-values&quot;&gt;Calculation of Scaling Function Initial Values&lt;/h1&gt;
&lt;p&gt;The scaling function requires values at integer values of r within the wavelet’s range of [0, N-1] with each end of the interval being zero (\(𝜑(0) = 0, 𝜑(N-1) = 0\)) and all values outside of the interval also being zero. These initial values, \( L_0 \), are calculated by producing a system of linear equations which can be solved by a constrained matrix solver.&lt;/p&gt;

&lt;p&gt;\(𝜑(r) = \sum\limits_{k=0}^{N-1} a_k 𝜑(2r - k)\)&lt;/p&gt;

&lt;p&gt;And yields the following system of equations for db4:&lt;br /&gt;
\(𝜑(0) = a_0 𝜑(2 * 0 - 0) + a_1 𝜑(2 * 0 - 1) + a_2 𝜑(2 * 0 - 2) + a_3 𝜑(2 * 0 - 3) + a_4 𝜑(2 * 0 - 4) + a_5 𝜑(2 * 0 - 5) + a_6 𝜑(2 * 0 - 6) + a_7 𝜑(2 * 0 - 7)\)&lt;br /&gt;
\(𝜑(1) = a_0 𝜑(2 * 1 - 0) + a_1 𝜑(2 * 1 - 1) + a_2 𝜑(2 * 1 - 2) + a_3 𝜑(2 * 1 - 3) + a_4 𝜑(2 * 1 - 4) + a_5 𝜑(2 * 1 - 5) + a_6 𝜑(2 * 1 - 6) + a_7 𝜑(2 * 1 - 7)\)&lt;br /&gt;
\(𝜑(2) = a_0 𝜑(2 * 2 - 0) + a_1 𝜑(2 * 2 - 1) + a_2 𝜑(2 * 2 - 2) + a_3 𝜑(2 * 2 - 3) + a_4 𝜑(2 * 2 - 4) + a_5 𝜑(2 * 2 - 5) + a_6 𝜑(2 * 2 - 6) + a_7 𝜑(2 * 2 - 7)\)&lt;br /&gt;
\(𝜑(3) = a_0 𝜑(2 * 3 - 0) + a_1 𝜑(2 * 3 - 1) + a_2 𝜑(2 * 3 - 2) + a_3 𝜑(2 * 3 - 3) + a_4 𝜑(2 * 3 - 4) + a_5 𝜑(2 * 3 - 5) + a_6 𝜑(2 * 3 - 6) + a_7 𝜑(2 * 3 - 7)\)&lt;br /&gt;
\(𝜑(4) = a_0 𝜑(2 * 4 - 0) + a_1 𝜑(2 * 4 - 1) + a_2 𝜑(2 * 4 - 2) + a_3 𝜑(2 * 4 - 3) + a_4 𝜑(2 * 4 - 4) + a_5 𝜑(2 * 4 - 5) + a_6 𝜑(2 * 4 - 6) + a_7 𝜑(2 * 4 - 7)\)&lt;br /&gt;
\(𝜑(5) = a_0 𝜑(2 * 5 - 0) + a_1 𝜑(2 * 5 - 1) + a_2 𝜑(2 * 5 - 2) + a_3 𝜑(2 * 5 - 3) + a_4 𝜑(2 * 5 - 4) + a_5 𝜑(2 * 5 - 5) + a_6 𝜑(2 * 5 - 6) + a_7 𝜑(2 * 5 - 7)\)&lt;br /&gt;
\(𝜑(6) = a_0 𝜑(2 * 6 - 0) + a_1 𝜑(2 * 6 - 1) + a_2 𝜑(2 * 6 - 2) + a_3 𝜑(2 * 6 - 3) + a_4 𝜑(2 * 6 - 4) + a_5 𝜑(2 * 6 - 5) + a_6 𝜑(2 * 6 - 6) + a_7 𝜑(2 * 6 - 7)\)&lt;br /&gt;
\(𝜑(7) = a_0 𝜑(2 * 7 - 0) + a_1 𝜑(2 * 7 - 1) + a_2 𝜑(2 * 7 - 2) + a_3 𝜑(2 * 7 - 3) + a_4 𝜑(2 * 7 - 4) + a_5 𝜑(2 * 7 - 5) + a_6 𝜑(2 * 7 - 6) + a_7 𝜑(2 * 7 - 7)\)&lt;/p&gt;

&lt;p&gt;This system can be greatly simplified, given that many values are zero. The endpoints and all other zero values will be removed:&lt;br /&gt;
\(𝜑(1) = a_0 𝜑(2) + a_1 𝜑(1)\)&lt;br /&gt;
\(𝜑(2) = a_0 𝜑(4) + a_1 𝜑(3) + a_2 𝜑(2) + a_3 𝜑(1)\)&lt;br /&gt;
\(𝜑(3) = a_0 𝜑(6) + a_1 𝜑(5) + a_2 𝜑(4) + a_3 𝜑(3) + a_4 𝜑(2) + a_5 𝜑(1)\)&lt;br /&gt;
\(𝜑(4) = a_2 𝜑(6) + a_3 𝜑(5) + a_4 𝜑(4) + a_5 𝜑(3) + a_6 𝜑(2) + a_7 𝜑(1)\)&lt;br /&gt;
\(𝜑(5) = a_4 𝜑(6) + a_5 𝜑(5) + a_6 𝜑(4) + a_7 𝜑(3)\)&lt;br /&gt;
\(𝜑(6) = a_6 𝜑(6) + a_7 𝜑(5)\)&lt;/p&gt;

&lt;p&gt;Next, a matrix equation can be written of the form \((\mathbf{A} - \mathbf{I})\vec{𝜑} = \vec{0}\) where \(\mathbf{I}\) is the identity matrix:&lt;/p&gt;

&lt;p&gt;\[ \begin{pmatrix}&lt;br /&gt;
a_1-1 &amp;amp; a_0   &amp;amp;   0   &amp;amp;   0   &amp;amp;   0   &amp;amp;   0 \\&lt;br /&gt;
a_3   &amp;amp; a_2-1 &amp;amp; a_1   &amp;amp; a_0   &amp;amp;   0   &amp;amp;   0 \\&lt;br /&gt;
a_5   &amp;amp; a_4   &amp;amp; a_3-1 &amp;amp; a_2   &amp;amp; a_1   &amp;amp; a_0 \\&lt;br /&gt;
a_7   &amp;amp; a_6   &amp;amp; a_5   &amp;amp; a_4-1 &amp;amp; a_3   &amp;amp; a_2 \\&lt;br /&gt;
  0   &amp;amp;   0   &amp;amp; a_7   &amp;amp; a_6   &amp;amp; a_5-1 &amp;amp; a_4 \\&lt;br /&gt;
  0   &amp;amp;   0   &amp;amp;   0   &amp;amp;   0   &amp;amp; a_7   &amp;amp; a_6-1 \\&lt;br /&gt;
\end{pmatrix} * \begin{pmatrix}&lt;br /&gt;
𝜑(1) \\ 𝜑(2) \\ 𝜑(3) \\ 𝜑(4) \\ 𝜑(5) \\ 𝜑(6)&lt;br /&gt;
\end{pmatrix} = \begin{pmatrix}&lt;br /&gt;
0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\]&lt;/p&gt;

&lt;h2 id=&quot;solving-for-initial-values-via-python&quot;&gt;Solving for Initial Values via Python&lt;/h2&gt;

&lt;p&gt;This matrix equation is solved with the constraint that \(\sum\vec{𝜑} = 1\) to find a valid solution. This result also ensures that the integral of the entire scaling function is 1, \(\int\limits_{\mathbb {R}}𝜑 = 1\). Below, we solve the constrained matrix equation with the &lt;strong&gt;scipy.optimize&lt;/strong&gt; method.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Helper method for minimization: ||Ax||^2
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# maps 0 or coefficient values to matrix A
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;map_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# db4 scaling coefficients
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aVector&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.32580343&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.01094572&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.89220014&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.03957503&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.26450717&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0436163&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0465036&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.01498699&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aVector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;A_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aVector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;col&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;identity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;A: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;zeroVector&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;type&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;eq&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;fun&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minimize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zeroVector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;SLSQP&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;constraints&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cons&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;disp&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;xbest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;x&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;db4 initial values: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xbest&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;sum of initial values: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xbest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;table-of-initial-values&quot;&gt;Table of Initial Values&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;0&lt;/th&gt;
      &lt;th&gt;1&lt;/th&gt;
      &lt;th&gt;2&lt;/th&gt;
      &lt;th&gt;3&lt;/th&gt;
      &lt;th&gt;4&lt;/th&gt;
      &lt;th&gt;5&lt;/th&gt;
      &lt;th&gt;6&lt;/th&gt;
      &lt;th&gt;7&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;db2&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;1.36602544&lt;/td&gt;
      &lt;td&gt;-0.36602544&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;db3&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;1.28653824&lt;/td&gt;
      &lt;td&gt;-0.38600335&lt;/td&gt;
      &lt;td&gt;0.09525722&lt;/td&gt;
      &lt;td&gt;0.00420788&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;db4&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;1.00716450&lt;/td&gt;
      &lt;td&gt;-3.38492330e-2&lt;/td&gt;
      &lt;td&gt;3.96088947e-2&lt;/td&gt;
      &lt;td&gt;-1.17337313e-2&lt;/td&gt;
      &lt;td&gt;-1.25087227e-3&lt;/td&gt;
      &lt;td&gt;6.04419105e-5&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h1 id=&quot;calculation-of-scaling-function&quot;&gt;Calculation of Scaling Function&lt;/h1&gt;
&lt;p&gt;The scaling function, 𝜑(r), is recursively-defined and requires the initial values from the previous step as well as the Daubechies coefficients. As mentioned in the intro, the function is not continuous until an infinite level of approximations are calculated, so we must settle for a discrete solution.&lt;/p&gt;

&lt;p&gt;\[ 𝜑(r) = \sum_{k=0}^{N-1} a_k 𝜑(2r - k) \]&lt;/p&gt;

&lt;p&gt;The calculation begins by initializing the initial level, \( L_0 \), by setting all whole integer values to the initial values:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;𝜑(0)&lt;/th&gt;
      &lt;th&gt;𝜑(1)&lt;/th&gt;
      &lt;th&gt;𝜑(2)&lt;/th&gt;
      &lt;th&gt;𝜑(3)&lt;/th&gt;
      &lt;th&gt;𝜑(4)&lt;/th&gt;
      &lt;th&gt;𝜑(5)&lt;/th&gt;
      &lt;th&gt;𝜑(6)&lt;/th&gt;
      &lt;th&gt;𝜑(7)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;1.00716450&lt;/td&gt;
      &lt;td&gt;-3.38492330e-2&lt;/td&gt;
      &lt;td&gt;3.96088947e-2&lt;/td&gt;
      &lt;td&gt;-1.17337313e-2&lt;/td&gt;
      &lt;td&gt;-1.25087227e-3&lt;/td&gt;
      &lt;td&gt;6.04419105e-5&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Next, we calculate the values for \( L_1 \) at the half-integer values:&lt;/p&gt;

&lt;p&gt;\( 𝜑(0.5) = a_0 𝜑(1 - 0) + a_1 𝜑(1 - 1) + a_2 𝜑(1 - 2) + a_3 𝜑(1 - 3)+  a_4 𝜑(1 - 4) + a_5 𝜑(1 - 5) + a_6 𝜑(1 - 6) + a_7 𝜑(1 - 7) \)&lt;br /&gt;
\( 𝜑(1.5) = a_0 𝜑(3 - 0) + a_1 𝜑(3 - 1) + a_2 𝜑(3 - 2) + a_3 𝜑(3 - 3)+  a_4 𝜑(3 - 4) + a_5 𝜑(3 - 5) + a_6 𝜑(3 - 6) + a_7 𝜑(3 - 7) \)&lt;br /&gt;
\( 𝜑(2.5) = a_0 𝜑(5 - 0) + a_1 𝜑(5 - 1) + a_2 𝜑(5 - 2) + a_3 𝜑(5 - 3)+  a_4 𝜑(5 - 4) + a_5 𝜑(5 - 5) + a_6 𝜑(5 - 6) + a_7 𝜑(5 - 7) \)&lt;br /&gt;
\( 𝜑(3.5) = a_0 𝜑(7 - 0) + a_1 𝜑(7 - 1) + a_2 𝜑(7 - 2) + a_3 𝜑(7 - 3)+  a_4 𝜑(7 - 4) + a_5 𝜑(7 - 5) + a_6 𝜑(7 - 6) + a_7 𝜑(7 - 7) \)&lt;br /&gt;
\( 𝜑(4.5) = a_0 𝜑(9 - 0) + a_1 𝜑(9 - 1) + a_2 𝜑(9 - 2) + a_3 𝜑(9 - 3)+  a_4 𝜑(9 - 4) + a_5 𝜑(9 - 5) + a_6 𝜑(9 - 6) + a_7 𝜑(9 - 7) \)&lt;br /&gt;
\( 𝜑(5.5) = a_0 𝜑(11 - 0) + a_1 𝜑(11 - 1) + a_2 𝜑(11 - 2) + a_3 𝜑(11 - 3)+  a_4 𝜑(11 - 4) + a_5 𝜑(11 - 5) + a_6 𝜑(11 - 6) + a_7 𝜑(11 - 7) \)&lt;br /&gt;
\( 𝜑(6.5) = a_0 𝜑(13 - 0) + a_1 𝜑(13 - 1) + a_2 𝜑(13 - 2) + a_3 𝜑(13 - 3)+  a_4 𝜑(13 - 4) + a_5 𝜑(13 - 5) + a_6 𝜑(13 - 6) + a_7 𝜑(13 - 7) \)&lt;/p&gt;

&lt;p&gt;Simplify with the knowledge that for db4, \(𝜑(r) = 0\) when \(r \leq 0, r \geq 7\):&lt;br /&gt;
\( 𝜑(0.5) = a_0 𝜑(1) = 0.3281 \)&lt;br /&gt;
\( 𝜑(1.5) = a_0 𝜑(3) + a_1 𝜑(2) + a_2 𝜑(1) = 0.8773 \)&lt;br /&gt;
\( 𝜑(2.5) = a_0 𝜑(5) + a_1 𝜑(4) + a_2 𝜑(3) + a_3 𝜑(2)+  a_4 𝜑(1) = -0.2420 \)&lt;br /&gt;
\( 𝜑(3.5) = a_1 𝜑(6) + a_2 𝜑(5) + a_3 𝜑(4)+  a_4 𝜑(3) + a_5 𝜑(2) + a_6 𝜑(1) = 0.0343 \)&lt;br /&gt;
\( 𝜑(4.5) = a_3 𝜑(6)+  a_4 𝜑(5) + a_5 𝜑(4) + a_6 𝜑(3) + a_7 𝜑(2) = 0.0022 \)&lt;br /&gt;
\( 𝜑(5.5) = a_5 𝜑(6) + a_6 𝜑(5) + a_7 𝜑(4) = 1.203e-4 \)&lt;br /&gt;
\( 𝜑(6.5) = a_7 𝜑(6) = 9.058e-7 \)&lt;/p&gt;

&lt;p&gt;Note that the right-hand side contains known values of 𝜑(r) from the \( L_0 \) initial values. We will repeat the recursion one additional level to the \( L_2 \) quarter-integer values:&lt;/p&gt;

&lt;p&gt;\( 𝜑(0.25) = a_0 𝜑(0.5 - 0) + a_1 𝜑(0.5 - 1) + a_2 𝜑(0.5 - 2) + a_3 𝜑(0.5 - 3) + a_4 𝜑(0.5 - 4) + a_5 𝜑(0.5 - 5) + a_6 𝜑(0.5 - 6) + a_7 𝜑(0.5 - 7) \)&lt;br /&gt;
\( 𝜑(0.75) = a_0 𝜑(1.5 - 0) + a_1 𝜑(1.5 - 1) + a_2 𝜑(1.5 - 2) + a_3 𝜑(1.5 - 3) + a_4 𝜑(1.5 - 4) + a_5 𝜑(1.5 - 5) + a_6 𝜑(1.5 - 6) + a_7 𝜑(1.5 - 7) \)&lt;br /&gt;
\( 𝜑(1.25) = a_0 𝜑(2.5 - 0) + a_1 𝜑(2.5 - 1) + a_2 𝜑(2.5 - 2) + a_3 𝜑(2.5 - 3) + a_4 𝜑(2.5 - 4) + a_5 𝜑(2.5 - 5) + a_6 𝜑(2.5 - 6) + a_7 𝜑(2.5 - 7) \)&lt;br /&gt;
\( 𝜑(1.75) = a_0 𝜑(3.5 - 0) + a_1 𝜑(3.5 - 1) + a_2 𝜑(3.5 - 2) + a_3 𝜑(3.5 - 3) + a_4 𝜑(3.5 - 4) + a_5 𝜑(3.5 - 5) + a_6 𝜑(3.5 - 6) + a_7 𝜑(3.5 - 7) \)&lt;br /&gt;
\( 𝜑(2.25) = a_0 𝜑(4.5 - 0) + a_1 𝜑(4.5 - 1) + a_2 𝜑(4.5 - 2) + a_3 𝜑(4.5 - 3) + a_4 𝜑(4.5 - 4) + a_5 𝜑(4.5 - 5) + a_6 𝜑(4.5 - 6) + a_7 𝜑(4.5 - 7) \)&lt;br /&gt;
\( 𝜑(2.75) = a_0 𝜑(5.5 - 0) + a_1 𝜑(5.5 - 1) + a_2 𝜑(5.5 - 2) + a_3 𝜑(5.5 - 3) + a_4 𝜑(5.5 - 4) + a_5 𝜑(5.5 - 5) + a_6 𝜑(5.5 - 6) + a_7 𝜑(5.5 - 7) \)&lt;br /&gt;
\( 𝜑(3.25) = a_0 𝜑(6.5 - 0) + a_1 𝜑(6.5 - 1) + a_2 𝜑(6.5 - 2) + a_3 𝜑(6.5 - 3) + a_4 𝜑(6.5 - 4) + a_5 𝜑(6.5 - 5) + a_6 𝜑(6.5 - 6) + a_7 𝜑(6.5 - 7) \)&lt;br /&gt;
\( 𝜑(3.75) = a_0 𝜑(7.5 - 0) + a_1 𝜑(7.5 - 1) + a_2 𝜑(7.5 - 2) + a_3 𝜑(7.5 - 3) + a_4 𝜑(7.5 - 4) + a_5 𝜑(7.5 - 5) + a_6 𝜑(7.5 - 6) + a_7 𝜑(7.5 - 7) \)&lt;br /&gt;
\( 𝜑(4.25) = a_0 𝜑(8.5 - 0) + a_1 𝜑(8.5 - 1) + a_2 𝜑(8.5 - 2) + a_3 𝜑(8.5 - 3) + a_4 𝜑(8.5 - 4) + a_5 𝜑(8.5 - 5) + a_6 𝜑(8.5 - 6) + a_7 𝜑(8.5 - 7) \)&lt;br /&gt;
\( 𝜑(4.75) = a_0 𝜑(9.5 - 0) + a_1 𝜑(9.5 - 1) + a_2 𝜑(9.5 - 2) + a_3 𝜑(9.5 - 3) + a_4 𝜑(9.5 - 4) + a_5 𝜑(9.5 - 5) + a_6 𝜑(9.5 - 6) + a_7 𝜑(9.5 - 7) \)&lt;br /&gt;
\( 𝜑(5.25) = a_0 𝜑(10.5 - 0) + a_1 𝜑(10.5 - 1) + a_2 𝜑(10.5 - 2) + a_3 𝜑(10.5 - 3) + a_4 𝜑(10.5 - 4) + a_5 𝜑(10.5 - 5) + a_6 𝜑(10.5 - 6) + a_7 𝜑(10.5 - 7) \)&lt;br /&gt;
\( 𝜑(5.75) = a_0 𝜑(11.5 - 0) + a_1 𝜑(11.5 - 1) + a_2 𝜑(11.5 - 2) + a_3 𝜑(11.5 - 3) + a_4 𝜑(11.5 - 4) + a_5 𝜑(11.5 - 5) + a_6 𝜑(11.5 - 6) + a_7 𝜑(11.5 - 7) \)&lt;br /&gt;
\( 𝜑(6.25) = a_0 𝜑(12.5 - 0) + a_1 𝜑(12.5 - 1) + a_2 𝜑(12.5 - 2) + a_3 𝜑(12.5 - 3) + a_4 𝜑(12.5 - 4) + a_5 𝜑(12.5 - 5) + a_6 𝜑(12.5 - 6) + a_7 𝜑(12.5 - 7) \)&lt;br /&gt;
\( 𝜑(6.75) = a_0 𝜑(13.5 - 0) + a_1 𝜑(13.5 - 1) + a_2 𝜑(13.5 - 2) + a_3 𝜑(13.5 - 3) + a_4 𝜑(13.5 - 4) + a_5 𝜑(13.5 - 5) + a_6 𝜑(13.5 - 6) + a_7 𝜑(13.5 - 7) \)&lt;/p&gt;

&lt;p&gt;Then simplify:&lt;/p&gt;

&lt;p&gt;\( 𝜑(0.25) = a_0 𝜑(0.5)  \)&lt;br /&gt;
\( 𝜑(0.75) = a_0 𝜑(1.5) + a_1 𝜑(0.5) \)&lt;br /&gt;
\( 𝜑(1.25) = a_0 𝜑(2.5) + a_1 𝜑(1.5) + a_2 𝜑(0.5) \)&lt;br /&gt;
\( 𝜑(1.75) = a_0 𝜑(3.5) + a_1 𝜑(2.5) + a_2 𝜑(1.5) + a_3 𝜑(0.5) \)&lt;br /&gt;
\( 𝜑(2.25) = a_0 𝜑(4.5) + a_1 𝜑(3.5) + a_2 𝜑(2.5) + a_3 𝜑(1.5) + a_4 𝜑(0.5) \)&lt;br /&gt;
\( 𝜑(2.75) = a_0 𝜑(5.5) + a_1 𝜑(4.5) + a_2 𝜑(3.5) + a_3 𝜑(2.5) + a_4 𝜑(1.5) + a_5 𝜑(0.5) \)&lt;br /&gt;
\( 𝜑(3.25) = a_0 𝜑(6.5) + a_1 𝜑(5.5) + a_2 𝜑(4.5) + a_3 𝜑(3.5) + a_4 𝜑(2.5) + a_5 𝜑(1.5) + a_6 𝜑(0.5) \)&lt;br /&gt;
\( 𝜑(3.75) = a_1 𝜑(6.5) + a_2 𝜑(5.5) + a_3 𝜑(4.5)+  a_4 𝜑(3.5) + a_5 𝜑(2.5) + a_6 𝜑(1.5) + a_7 𝜑(0.5) \)&lt;br /&gt;
\( 𝜑(4.25) = a_2 𝜑(6.5) + a_3 𝜑(5.5)+  a_4 𝜑(4.5) + a_5 𝜑(3.5) + a_6 𝜑(2.5) + a_7 𝜑(1.5) \)&lt;br /&gt;
\( 𝜑(4.75) = a_3 𝜑(6.5)+  a_4 𝜑(5.5) + a_5 𝜑(4.5) + a_6 𝜑(3.5) + a_7 𝜑(2.5) \)&lt;br /&gt;
\( 𝜑(5.25) = a_4 𝜑(6.5) + a_5 𝜑(5.5) + a_6 𝜑(4.5) + a_7 𝜑(3.5) \)&lt;br /&gt;
\( 𝜑(5.75) = a_5 𝜑(6.5) + a_6 𝜑(5.5) + a_7 𝜑(4.5) \)&lt;br /&gt;
\( 𝜑(6.25) = a_6 𝜑(6.5) + a_7 𝜑(5.5) \)&lt;br /&gt;
\( 𝜑(6.75) = a_7 𝜑(6.5) \)&lt;/p&gt;

&lt;p&gt;Once again, all of the values of 𝜑(r) required to evaluate the right-hand side were calculated during the previous step. The solutions for \( L_0 \) to \( L_2 \) are compiled in the following tables:&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜑(0)&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(2.5)&lt;/td&gt;
      &lt;td&gt;-0.2420&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(5)&lt;/td&gt;
      &lt;td&gt;-1.251e-3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜑(0.25)&lt;/td&gt;
      &lt;td&gt;0.1069&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(2.75)&lt;/td&gt;
      &lt;td&gt;-0.1753&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(5.25)&lt;/td&gt;
      &lt;td&gt;-4.077e-4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜑(0.5)&lt;/td&gt;
      &lt;td&gt;0.3281&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(3)&lt;/td&gt;
      &lt;td&gt;0.0396&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(5.5)&lt;/td&gt;
      &lt;td&gt;1.203e-4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜑(0.75)&lt;/td&gt;
      &lt;td&gt;0.6175&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(3.25)&lt;/td&gt;
      &lt;td&gt;0.1182&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(5.75)&lt;/td&gt;
      &lt;td&gt;-2.691e-5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜑(1)&lt;/td&gt;
      &lt;td&gt;1.0072&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(3.5)&lt;/td&gt;
      &lt;td&gt;0.0343&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(6)&lt;/td&gt;
      &lt;td&gt;6.044e-5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜑(1.25)&lt;/td&gt;
      &lt;td&gt;1.1008&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(3.75)&lt;/td&gt;
      &lt;td&gt;0.0163&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(6.25)&lt;/td&gt;
      &lt;td&gt;-1.845e-6&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜑(1.5)&lt;/td&gt;
      &lt;td&gt;0.8773&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(4)&lt;/td&gt;
      &lt;td&gt;-0.0117&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(6.5)&lt;/td&gt;
      &lt;td&gt;-9.058e-7&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜑(1.75)&lt;/td&gt;
      &lt;td&gt;0.5363&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(4.25)&lt;/td&gt;
      &lt;td&gt;-0.0235&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(6.75)&lt;/td&gt;
      &lt;td&gt;1.358e-8&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜑(2)&lt;/td&gt;
      &lt;td&gt;-0.0338&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(4.5)&lt;/td&gt;
      &lt;td&gt;2.166e-3&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(7)&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜑(2.25)&lt;/td&gt;
      &lt;td&gt;-0.3020&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜑(4.75)&lt;/td&gt;
      &lt;td&gt;5.284e-3&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;evaluating-the-scaling-function-via-c&quot;&gt;Evaluating the Scaling Function via C#&lt;/h2&gt;
&lt;p&gt;An iterative approach is used here rather than a true recursive method. The following method calculates the scaling function’s next level of approximation and is valid for \( L \gt 0 \). \( L_0 \) must be separately calculated as described by the Initial Values section.&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Vector2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetScalingLevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Vector2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;previous&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scalingCoefs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaling&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Vector2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PointsAtLevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scalingCoefs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)];&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxRange&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scalingCoefs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;distancePerIndex&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxRange&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;previous&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scalingCoefs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;++)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rPrevious&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rIndex&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MathF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rPrevious&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;distancePerIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rPrevious&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rPrevious&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scalingCoefs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Vector2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;calculation-of-wavelet-function&quot;&gt;Calculation of Wavelet Function&lt;/h1&gt;
&lt;p&gt;The wavelet function, 𝜓(r), is more straightforward once the scaling function has been calculated. Its equation is given by:&lt;/p&gt;

&lt;p&gt;\[ 𝜓(r) = \sum_{k=0}^{N-1} b_k 𝜑(2r - k) \]&lt;/p&gt;

&lt;p&gt;Given that \( L_2 \) was previously calculated for the scaling function, the same values of r can be evaluated for the wavelet function at \( L_2 \):&lt;/p&gt;

&lt;p&gt;\( 𝜓(0.25) = b_0 𝜑(0.5 - 0) + b_1 𝜑(0.5 - 1) + b_2 𝜑(0.5 - 2) + b_3 𝜑(0.5 - 3) + b_4 𝜑(0.5 - 4) + b_5 𝜑(0.5 - 5) + b_6 𝜑(0.5 - 6) + b_7 𝜑(0.5 - 7) \)&lt;br /&gt;
\( 𝜓(0.5) = b_0 𝜑(1 - 0) + b_1 𝜑(1 - 1) + b_2 𝜑(1 - 2) + b_3 𝜑(1 - 3) + b_4 𝜑(1 - 4) + b_5 𝜑(1 - 5) + b_6 𝜑(1 -6) + b_7 𝜑(1 - 7) \)&lt;br /&gt;
\( 𝜓(0.75) = b_0 𝜑(1.5 - 0) + b_1 𝜑(1.5 - 1) + b_2 𝜑(1.5 - 2) + b_3 𝜑(1.5 - 3) + b_4 𝜑(1.5 - 4) + b_5 𝜑(1.5 - 5) + b_6 𝜑(1.5 - 6) + b_7 𝜑(1.5 - 7) \)&lt;br /&gt;
\( 𝜓(1) = b_0 𝜑(2 - 0) + b_1 𝜑(2 - 1) + b_2 𝜑(2 - 2) + b_3 𝜑(2 - 3) + b_4 𝜑(2 - 4) + b_5 𝜑(2 - 5) + b_6 𝜑(2 -6) + b_7 𝜑(2 - 7) \)&lt;br /&gt;
…&lt;br /&gt;
\( 𝜓(6.5) = b_0 𝜑(13 - 0) + b_1 𝜑(13 - 1) + b_2 𝜑(13 - 2) + b_3 𝜑(13 - 3) + b_4 𝜑(13 - 4) + b_5 𝜑(13 - 5) + b_6 𝜑(13 - 6) + b_7 𝜑(13 - 7) \)&lt;br /&gt;
\( 𝜓(6.75) = b_0 𝜑(13.5 - 0) + b_1 𝜑(13.5 - 1) + b_2 𝜑(13.5 - 2) + b_3 𝜑(13.5 - 3) + b_4 𝜑(13.5 - 4) + b_5 𝜑(13.5 - 5) + b_6 𝜑(13.5 - 6) + b_7 𝜑(13.5 - 7) \)&lt;/p&gt;

&lt;p&gt;And simplifies to:&lt;/p&gt;

&lt;p&gt;\( 𝜓(0.25) = b_0 𝜑(0.5) \)&lt;br /&gt;
\( 𝜓(0.5) = b_0 𝜑(1) \)&lt;br /&gt;
\( 𝜓(0.75) = b_0 𝜑(1.5) + b_1 𝜑(0.5) \)&lt;br /&gt;
\( 𝜓(1) = b_0 𝜑(2) + b_1 𝜑(1) \)&lt;br /&gt;
…&lt;br /&gt;
\( 𝜓(6.5) = b_7 𝜑(6) \)&lt;br /&gt;
\( 𝜓(6.75) = b_7 𝜑(6.5) \)&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜓(0)&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(2.5)&lt;/td&gt;
      &lt;td&gt;-0.0465&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(5)&lt;/td&gt;
      &lt;td&gt;-0.0237&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜓(0.25)&lt;/td&gt;
      &lt;td&gt;-4.918e-3&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(2.75)&lt;/td&gt;
      &lt;td&gt;-0.3901&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(5.25)&lt;/td&gt;
      &lt;td&gt;-9.0904e-3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜓(0.5)&lt;/td&gt;
      &lt;td&gt;-0.0151&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(3)&lt;/td&gt;
      &lt;td&gt;-0.8872&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(5.5)&lt;/td&gt;
      &lt;td&gt;2.5044e-3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜓(0.75)&lt;/td&gt;
      &lt;td&gt;-0.0284&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(3.25)&lt;/td&gt;
      &lt;td&gt;-0.4322&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(5.75)&lt;/td&gt;
      &lt;td&gt;5.8323e-4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜓(1)&lt;/td&gt;
      &lt;td&gt;-0.0463&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(3.5)&lt;/td&gt;
      &lt;td&gt;1.0437&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(6)&lt;/td&gt;
      &lt;td&gt;4.6864e-4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜓(1.25)&lt;/td&gt;
      &lt;td&gt;-0.0229&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(3.75)&lt;/td&gt;
      &lt;td&gt;0.9951&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(6.25)&lt;/td&gt;
      &lt;td&gt;-4.0116e-5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜓(1.5)&lt;/td&gt;
      &lt;td&gt;0.0449&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(4)&lt;/td&gt;
      &lt;td&gt;-0.3976&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(6.5)&lt;/td&gt;
      &lt;td&gt;-1.9692e-5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜓(1.75)&lt;/td&gt;
      &lt;td&gt;0.1358&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(4.25)&lt;/td&gt;
      &lt;td&gt;-0.5611&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(6.75)&lt;/td&gt;
      &lt;td&gt;-2.9513e-7&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜓(2)&lt;/td&gt;
      &lt;td&gt;0.2633&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(4.5)&lt;/td&gt;
      &lt;td&gt;0.0616&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(7)&lt;/td&gt;
      &lt;td&gt;0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;𝜓(2.25)&lt;/td&gt;
      &lt;td&gt;0.2069&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;𝜓(4.75)&lt;/td&gt;
      &lt;td&gt;0.1116&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;evaluating-the-wavelet-function-via-c&quot;&gt;Evaluating the Wavelet Function via C#&lt;/h2&gt;
&lt;p&gt;The wavelet function code is very similar to the scaling function code. The level is baked into scaling and isn’t required.&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Vector2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetWaveletLevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Vector2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;waveletCoefs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wavelet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Vector2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxRange&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;waveletCoefs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;distancePerPoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxRange&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wavelet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wavelet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;++)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;distancePerPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;waveletCoefs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;++)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rPrevious&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rIndex&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MathF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rPrevious&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;distancePerPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rPrevious&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rPrevious&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;waveletCoefs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;wavelet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Vector2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wavelet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;source-code&quot;&gt;Source Code&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/stevemonaco/SignalsPlayground&quot;&gt;Main Project&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/stevemonaco/SignalsPlayground/blob/master/SignalsPlayground.Domain/DaubechiesWavelet.cs&quot;&gt;Scaling and Wavelet Function (C#))&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/stevemonaco/SignalsPlayground/blob/master/SignalsPlayground.Python/db_initial_values.py&quot;&gt;Initial Scaling Values (Python)&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;Wavelets Made Easy - Yves Nievergelt (2001)&lt;br /&gt;
&lt;a href=&quot;http://wavelets.pybytes.com/wavelet/&quot;&gt;Wavelet Browser&lt;/a&gt; - PyWavelets&lt;/p&gt;
</description>
				<pubDate>Sat, 27 Jun 2020 23:00:00 +0000</pubDate>
				<link>/2020/06/daubechies-wavelets/</link>
				<guid isPermaLink="true">/2020/06/daubechies-wavelets/</guid>
			</item>
		
			<item>
				<title>Launch</title>
				<description>&lt;p&gt;Finally launched, this blog is where I will discuss topics relevant to programming and engineering. Programming-oriented material in the areas of medicine, chemistry, and machine learning may also be occasionally covered.&lt;/p&gt;
</description>
				<pubDate>Thu, 25 Jun 2020 20:27:00 +0000</pubDate>
				<link>/2020/06/blog-launch/</link>
				<guid isPermaLink="true">/2020/06/blog-launch/</guid>
			</item>
		
	</channel>
</rss>
