homepage
Open menu
Go one level top
  • Train and Certify
    Train and Certify

    Immediately apply the skills and techniques learned in SANS courses, ranges, and summits

    • Overview
    • Courses
      • Overview
      • Full Course List
      • By Focus Areas
        • Cloud Security
        • Cyber Defense
        • Cybersecurity and IT Essentials
        • DFIR
        • Industrial Control Systems
        • Offensive Operations
        • Management, Legal, and Audit
      • By Skill Levels
        • New to Cyber
        • Essentials
        • Advanced
        • Expert
      • Training Formats
        • OnDemand
        • In-Person
        • Live Online
      • Course Demos
    • Training Roadmaps
      • Skills Roadmap
      • Focus Area Job Roles
        • Cyber Defence Job Roles
        • Offensive Operations Job Roles
        • DFIR Job Roles
        • Cloud Job Roles
        • ICS Job Roles
        • Leadership Job Roles
      • NICE Framework
        • Security Provisionals
        • Operate and Maintain
        • Oversee and Govern
        • Protect and Defend
        • Analyze
        • Collect and Operate
        • Investigate
        • Industrial Control Systems
    • GIAC Certifications
    • Training Events & Summits
      • Events Overview
      • Event Locations
        • Asia
        • Australia & New Zealand
        • Latin America
        • Mainland Europe
        • Middle East & Africa
        • Scandinavia
        • United Kingdom & Ireland
        • United States & Canada
      • Summits
    • OnDemand
    • Get Started in Cyber
      • Overview
      • Degree and Certificate Programs
      • Scholarships
    • Cyber Ranges
  • Manage Your Team
    Manage Your Team

    Build a world-class cyber team with our workforce development programs

    • Overview
    • Why Work with SANS
    • Group Purchasing
    • Build Your Team
      • Team Development
      • Assessments
      • Private Training
      • Hire Cyber Professionals
      • By Industry
        • Health Care
        • Industrial Control Systems Security
        • Military
    • Leadership Training
  • Security Awareness
    Security Awareness

    Increase your staff’s cyber awareness, help them change their behaviors, and reduce your organizational risk

    • Overview
    • Products & Services
      • Security Awareness Training
        • EndUser Training
        • Phishing Platform
      • Specialized
        • Developer Training
        • ICS Engineer Training
        • NERC CIP Training
        • IT Administrator
      • Risk Assessments
        • Knowledge Assessment
        • Culture Assessment
        • Behavioral Risk Assessment
    • OUCH! Newsletter
    • Career Development
      • Overview
      • Training & Courses
      • Professional Credential
    • Blog
    • Partners
    • Reports & Case Studies
  • Resources
    Resources

    Enhance your skills with access to thousands of free resources, 150+ instructor-developed tools, and the latest cybersecurity news and analysis

    • Overview
    • Webcasts
    • Free Cybersecurity Events
      • Free Events Overview
      • Summits
      • Solutions Forums
      • Community Nights
    • Content
      • Newsletters
        • NewsBites
        • @RISK
        • OUCH! Newsletter
      • Blog
      • Podcasts
      • Summit Presentations
      • Posters & Cheat Sheets
    • Research
      • White Papers
      • Security Policies
    • Tools
    • Focus Areas
      • Cyber Defense
      • Cloud Security
      • Digital Forensics & Incident Response
      • Industrial Control Systems
      • Cyber Security Leadership
      • Offensive Operations
  • Get Involved
    Get Involved

    Help keep the cyber community one step ahead of threats. Join the SANS community or begin your journey of becoming a SANS Certified Instructor today.

    • Overview
    • Join the Community
    • Work Study
    • Teach for SANS
    • CISO Network
    • Partnerships
    • Sponsorship Opportunities
  • About
    About

    Learn more about how SANS empowers and educates current and future cybersecurity practitioners with knowledge and skills

    • SANS
      • Overview
      • Our Founder
      • Awards
    • Instructors
      • Our Instructors
      • Full Instructor List
    • Mission
      • Our Mission
      • Diversity
      • Scholarships
    • Contact
      • Contact Customer Service
      • Contact Sales
      • Press & Media Enquiries
    • Frequent Asked Questions
    • Customer Reviews
    • Press
    • Careers
  • Contact Sales
  • SANS Sites
    • GIAC Security Certifications
    • Internet Storm Center
    • SANS Technology Institute
    • Security Awareness Training
  • Search
  • Log In
  • Join
    • Account Dashboard
    • Log Out
  1. Home >
  2. Blog >
  3. PowerShell for Math.NET Numerics
370x370_Jason-Fossen.jpg
Jason Fossen

PowerShell for Math.NET Numerics

June 27, 2015

Purpose

PowerShell can utilize the math libraries of Math.NET Numerics and the processor-optimized Intel Math Kernel Library (MKL). To help coders get started, this article is a collection of PowerShell examples using Math.NET with Intel's MKL.

Download The Script

Because source code can be hard to read in a blog, you can download a script with all the examples: get the SEC505 zip file from BlueTeamPowerShell.com, open the zip to the \Day1 folder, and find the Math.NET.Numerics-Examples.ps1 script.

(In the zip file you'll find over a hundred other PowerShell scripts, all in the public domain, used in my SANS course Securing Windows and PowerShell Automation [SEC505].)

Background

Math.NET (www.MathDotNet.com) is a set of open source mathematical toolkits optimized for ease of use and performance. The Math.NET libraries are compatible with the Microsoft .NET Framework and the Mono project, which makes them accessible to PowerShell too. The toolkits are available for free under the MIT/X11 license, which is even more liberal than the GNU Public License (except for the Intel MKL, which has its own license, but it is still free for your own use when obtained with Math.NET).

One part of the Math.NET project is Math.NET Numerics, which is especially useful for math computations in science and engineering. It includes methods for statistics, probability, random numbers, linear algebra, interpolation, regression, optimization problems, and more. The project includes hardware-optimized native libraries to maximize performance on x64 or x86 processors, such as Intel's Math Kernel Library (MKL).

The majority of computers used by scientists and engineers worldwide run Microsoft Windows. PowerShell is built into Windows and is relatively easy to learn. Think of PowerShell as "simplified C#" for use in a command shell and in scripts. Just like C#, PowerShell can access the .NET Framework; in fact, PowerShell itself is a .NET Framework application.

Why PowerShell?

For scientists and engineers, PowerShell is great for:

  • utilizing the Intel Math Kernel Library (MKL) through Math.NET Numerics,
  • managing long-running, complex compute jobs and scheduled tasks,
  • orchestrating large-scale parallel MATLAB workloads in Azure,
  • managing Machine Learning experiments in Azure,
  • managing tasks on remote Linux boxes using a PowerShell port of ssh,
  • programmatically interacting with REST/SOAP/XML/JSON web applications,
  • doing quick-and-dirty distributed computing with Workflows and Remoting,
  • running processes concurrently with RunSpaces or background jobs,
  • importing/exporting data with Excel spreadsheets,
  • quickly prototyping new ideas which could then be later ported to C# because of the similarities between PowerShell and C#,
  • playing nice with the built-in support for Ubuntu bash on Windows 10 and later,
  • and using the Posh-Git PowerShell module with GitHub Desktop.

For data visualization, PowerShell and Math.NET can export data for display in MATLAB or Excel, or you could script it yourself using the built-in .NET classes for visualization.

As an uncompiled and dynamically-typed language, PowerShell will never come close to the performance of C/C++, but with Math.NET and the Intel MKL provider, this might be less of an issue. On the other hand, C/C++ will never match the convenience (and fun) of using PowerShell with Math.NET or Python with NumPy. Can PowerShell script code be compiled? Yes and no: in some cases, parts of the script are compiled automatically on-the-fly, but we don't have much control over the JIT-ing when it occurs.

Math.NET Installation

See the main Math.NET Numerics project site, the source of all the examples: http://numerics.mathdotnet.com

If you do not have PowerShell 5.0 or later, get the NUGET.EXE package installer: http://docs.nuget.org/consume/installing-nuget

If you do have PowerShell 5.0 or later, create an appropriate parent folder (perhaps C:\Program Files\MathNet), then install the binaries there:

Install-Package -ProviderName NuGet -Name MathNet.Numerics -Destination C:\SomeFolder -Force

Or, if you are using NUGET.EXE, create an appropriate parent folder, then install the Math.NET Numerics binaries there:

cd C:\SomeFolder
.\nuget.exe install MathNet.Numerics

Optionally, install the Intel MKL Native Provider. For simplicity, you can copy the two MKL DLLs (libiomp5md.dll and MathNet.Numerics.MKL.dll) from the package's Content folder into the same folder as your PowerShell scripts, but see this page for the use of other default paths instead. While the installation of the Intel MKL is, strictly speaking, optional, it will greatly accelerate linear algebra tasks.

Using PowerShell 5.0 or later, install the Intel MKL Native Provider:

Install-Package -ProviderName NuGet -Name MathNet.Numerics.MKL.Win-x64 -Destination C:\SomeFolder -Force

Or, do the same with NUGET.EXE:

.\nuget.exe install MathNet.Numerics.MKL.Win-x64

Optionally, install the MathNet.Numerics.Data.Text package for TSV/CSV files and NIST Matrix Market files:

Install-Package -ProviderName NuGet -Name MathNet.Numerics.Data.Text -Destination C:\SomeFolder -Force
.\nuget.exe install MathNet.Numerics.Data.Text

Optionally, install support for MATLAB Level-5 MAT files:

Install-Package -ProviderName NuGet -Name MathNet.Numerics.Data.Matlab -Destination C:\SomeFolder -Force
.\nuget.exe install MathNet.Numerics.Data.Matlab

Add Types and Create Accelerators

At the beginning of your script, you would load the Math.NET modules and create "solution accelerators", which are just short aliases for longer commands. In all the examples in this article, you will see aliases with names like "[M]" and "[V]" for creating matrices or vectors using Math.NET. These are using the accelerators defined here.

# Switch to the folder where you installed the Math.NET package(s) for
# your version of the .NET Framework (your folder will be different):
cd F:\Temp\Hashing\MathNet.Numerics.3.11.1\lib\net40

# Load the Math.NET Numerics DLL (nearly always required):
 Add-Type -Path .\MathNet.Numerics.dll

# Load the MathNet.Numerics.Data.Text DLL (optional):
 Add-Type -Path .\MathNet.Numerics.Data.Text.dll

# [M]: Create an accelerator shortcut [M] for use of Math.NET matrices:
 psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Add('M','MathNet.Numerics.LinearAlgebra.Matrix[Double]')

# [V]: Create an accelerator shortcut [V] for use of Math.NET vectors:
 [psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Add('V','MathNet.Numerics.LinearAlgebra.Vector[Double]')

# [STAT]: Create an accelerator shortcut [STAT] for use of MathNet statistics:
 [psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Add('STAT','MathNet.Numerics.Statistics.Statistics')

# [FUNC]: Create an accelerator shortcut [FUNC] for use of MathNet special functions:
 [psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Add('FUNC','MathNet.Numerics.SpecialFunctions')

You can also simply assign the classes to variables instead of using accelerators:

$MATRIX = [MathNet.Numerics.LinearAlgebra.Matrix[Double]]
$VECTOR = [MathNet.Numerics.LinearAlgebra.Vector[Double]]
$STAT = [MathNet.Numerics.Statistics.Statistics]
$FUNC = [MathNet.Numerics.SpecialFunctions]


Intel Math Kernel Library (MKL) Native Provider

# Enable the use of Intel MKL for linear algebra:
[MathNet.Numerics.Control]::UseNativeMKL("Auto")

# Confirm the switch from "Managed" to "Intel MKL":
 [MathNet.Numerics.Control]::LinearAlgebraProvider

# If you want to switch back to the default, slower, managed .NET code:
 [MathNet.Numerics.Control]::UseManaged()


Intel MKL Performance Testing

Below are the results of some tests using Math.NET with the Intel MKL provider. The goal is to offload the heavy number crunching from PowerShell and the .NET Framework to compiled modules which have been hand-tuned for maximum performance. It's the same strategy used by Python and NumPy. You can also embed C# code inside your PowerShell script, if necessary, and have it compiled on-the-fly to maximize performance for that part of the script (it's not unusual for a script or application to spend 90% of its time in a fast loop or in another task that only represents a small number of lines of code in the overall script or app).

Here are the test system specs for reference:

  • Intel MKL x64 libiomp5md.dll file version 5.0.2015.609 (Sept 2015)
  • Intel Core i7-4790 CPU @ 3.60GHz
  • 32GB Memory (DDR3 1600)
  • Windows 10 Pro (Build 10.0.10586.122)
  • PowerShell 5.0.10586.122
  • CLR Version 4.0.30319.42000

Multiply two 2000×2000 matrices of random doubles:
With Default: 4720.48ms average
With Intel MKL: 350.09ms average
MKL Increase: 13.5X

1..10 | ForEach { Measure-Command -Expression { [M]::Build.Random(2000,2000) * [M]::Build.Random(2000,2000) } } | Measure-Object -Property TotalMilliseconds -Average

Compute eigenvalues and eigenvectors on a 1000×1000 matrix of random doubles:
With Default: 12554.58ms average
With Intel MKL: 694.03ms average
MKL Increase: 18.1X

1..10 | ForEach { Measure-Command -Expression { ([M]::Build.Random(1000,1000)).Evd() } } | Measure-Object -Property TotalMilliseconds -Average

Compute single value decomposition on a 1000×1000 matrix of random doubles:
With Default: 11167.04ms average
With Intel MKL: 362.52ms average
MKL Increase: 30.8X

 1..10 | ForEach { Measure-Command -Expression { ([M]::Build.Random(1000,1000)).Svd() } } | Measure-Object -Property TotalMilliseconds -Average

Compute the inverse of a 1000×1000 matrix of random doubles:
With Default: 14536.91ms average
With Intel MKL: 64.10ms average
MKL Increase: 226.8X

1..10 | ForEach { Measure-Command -Expression { ([M]::Build.Random(1000,1000)).Inverse() } } | Measure-Object -Property TotalMilliseconds -Average

Compute the determinant of a 1000×1000 matrix of random doubles:
With Default: 371.14ms average
With Intel MKL: 39.61ms average
MKL Increase: 9.4X

1..10 | ForEach { Measure-Command -Expression { ([M]::Build.Random(1000,1000)).Determinant() } } | Measure-Object -Property TotalMilliseconds -Average


Constants

[MathNet.Numerics.Constants] | Get-Member -Static

[MathNet.Numerics.Constants]::Pi
 [MathNet.Numerics.Constants]::Avogadro
 [MathNet.Numerics.Constants]::ProtonMass


Creating Matrices

# Create a dense matrix of random numbers(3 rows, 4 columns):
$matrix = [MathNet.Numerics.LinearAlgebra.Matrix[Double]]::Build.Random(3, 4)

# Create a dense zero-vector of length ten as [Double[]]:
 $vector = [MathNet.Numerics.LinearAlgebra.Vector[Double]]::Build.Dense(10)

# Create a dense matrix of random numbers(3 rows, 4 columns):
 [M]::Build.Random(3, 4)

# Create a dense zero-vector of length ten:
 [V]::Build.Dense(10)

# 3x4 dense matrix filled with zeros:
 [M]::Build.Dense(3, 4)

# 3x4 dense matrix filled with 1.0:
 [M]::Build.Dense(3, 4, 1.0)

# 3x4 dense matrix where each field is initialized using a function:
 function myfunc ($i, $j){ (100 * $i) + $j }
 [M]::Build.Dense(3, 4, (myfunc -i 3 -j 1) )

# 3x4 square dense matrix with each diagonal value set to 2.0:
 [M]::Build.DenseDiagonal(3, 4, 2.0)

# 3x3 dense identity matrix:
 [M]::Build.DenseIdentity(3)

# 3x4 dense random matrix sampled from a Gamma distribution:
 $gammadist = [MathNet.Numerics.Distributions.Gamma]::Sample( 1.0, 5.0 )
 [M]::Build.Random(3, 4, $gammadist )

# Create a matrix in column major order (column by column):
 [Double[]] $array = @( 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12 )
 [M]::Build.DenseOfColumnMajor(3,4,$array)

# Create a matrix from arrays representing columns:
 [Double[]] $d1 = @( 1,4,7 )
 [Double[]] $d2 = @( 2,5,8 )
 [Double[]] $d3 = @( 3,6,9 )
 [M]::Build.DenseOfColumnArrays( @($d1,$d1,$d3) )

# Create a matrix of column vectors:
 [M]::Build.DenseOfColumnVectors( [V]::Build.Random(3), [V]::Build.Random(3) )
 


Creating Vectors

# Create a standard-distributed random vector of length 10:[V]::Build.Random(10)

# Create an all-zero vector of length 10:
 [V]::Build.Dense(10)

# Create a vector where each field is initialized using a function:
 function myfunc ($i){ $i * $i }
 [V]::Build.Dense(10, (myfunc -i 3) )

# Create a vector from an array of Double:
 [Double[]] $d1 = @( 1,2,3,4,5 )
 [V]::Build.DenseOfArray( $d1 )


Matrix and Vector Arithmetic

# Create a matrix and vector to play around with:
[Double[]] $d1 = @( 1,4,7 )
[Double[]] $d2 = @( 2,5,8 )
[Double[]] $d3 = @( 3,6,9 )
[Double[]] $d4 = @( 10,20,30 )
$m = [M]::Build.DenseOfColumnArrays( @($d1,$d1,$d3) )
$v = [V]::Build.DenseOfArray( $d4 )

# Common arithmetic operators:
 $m * $v
 $m + (2 * $m)

# Instance methods:
 $m | Get-Member
 $m.Multiply( $v )
 $m.Add( $m.Multiply(2) )
 $m.Transpose()
 $m.Inverse()
 $m.Nullity()
 $m.Kernel()
 $v.Sum()

# Instance methods for in-place operations:
 $m.Multiply( $v, $v ) #Second arg captures output
 $m.Multiply( 3, $m ) #Value of $m changes


Manipulating Matrices and Vectors

$m[0,0] # Returns row 0, column 0
$m[2,0] # Returns row 2, column 0
$m[0,2] # Returns row 0, column 2
$m[0,2] = -1.0 # Assigns row 0, column 2 to -1.0

$m.Column(2) # Returns entire 3rd column
 $m.Row(1) # Returns entire 2nd row

$m.SubMatrix(1,2,1,2) # Returns new matrix from an existing one

$m.ClearColumn(2) # Set 3rd column to all zeros
 $m.Clear() # Set all columns to all zeros


Displaying Matrix and Vector Data

$m.RowCount # Returns count of rows
$m.ColumnCount # Returns count of columns

$m.ToColumnArrays() # Emits an array of all values by column
 $m.ToRowArrays() # Emits an array of all values by row

$m.ToMatrixString() # A 2D matrix as a string for printing

$v = [V]::Build.Random(30) # Fill a vector to have something to display
 $v.Count # Returns total number of items in vector
 $v.ToArray() # Returns array of items
 $v # Same as $v.ToArray()
 $v.ToString(5,80) # max per column = 5, max columns = 80


Generating Data

# List the generator functions supported:
[MathNet.Numerics.Generate] | Get-Member -Static

# Generate a range from 1..15, stepping by 1:
 [MathNet.Numerics.Generate]::LinearRange(1,1,15)

# Generate a range from 100..2000, stepping by 50:
 [MathNet.Numerics.Generate]::LinearRange(100,50,2000)

# Generate a sine wave of a given length, sampling rate, frequency, and amplitude:
 [MathNet.Numerics.Generate]::Sinusoidal(15, 1000, 100, 10)

# Generate 100 random numbers, uniformly distributed between 0 and 1:
 [MathNet.Numerics.Generate]::Uniform(100)


Random Numbers

# Generate 1000 random numbers between 0 and 1 using the
# System.Security.Cryptography.RandomNumberGenerator class:
[Double[]] $samples = [MathNet.Numerics.Random.CryptoRandomSource]::Doubles(1000)

# Overwrite the $samples array with new random numbers:
 [MathNet.Numerics.Random.CryptoRandomSource]::Doubles($samples)

# Generate an infinite sequence of random numbers:
 ForEach ( $num in [MathNet.Numerics.Random.CryptoRandomSource]::DoubleSequence() ){ $num }

# Fill an array of Byte[] with random bytes using the System.Random class:
 [System.Byte[]] $buffer = 1..100
 $rng = [MathNet.Numerics.Random.SystemRandomSource]::Default
 $rng.NextBytes( $buffer )
 $buffer -join ','

# Fill an array of Int32[] with random numbers between 4 and 999:
 [Int32[]] $buffer = 1..100
 $rng = [MathNet.Numerics.Random.SystemRandomSource]::Default
 $rng.NextInt32s( $buffer, 4, 999 )
 $buffer -join ','

# Generate a random seed using System.Security.Cryptography.RandomNumberGenerator:
 [MathNet.Numerics.Random.RandomSeed]::Robust()

# Generate five random Doubles using 42 as a seed:
 [MathNet.Numerics.Random.SystemRandomSource]::Doubles( 5, 42 )

# With Mersenne Twister 19937 generator, make five Doubles with a seed of 42:
 [MathNet.Numerics.Random.MersenneTwister]::Doubles( 5, 42 )

# With Multiply-with-Carry XOR-Shift generator, make five Doubles with a seed
 # of 42 and a=9, c=6, x1=11, x2=12:
 [MathNet.Numerics.Random.Xorshift]::Doubles( 5, 42, 9, 6, 11, 12 )


Distance Metrics

# Sum of Absolute Difference (SAD):
[MathNet.Numerics.Distance]::SAD( [Double] 44, [Double] 55 )

# Sum of Squared Difference (SSD):
 [MathNet.Numerics.Distance]::SSD( [Double] 44, [Double] 55 )

# Euclidean Distance:
 [MathNet.Numerics.Distance]::Euclidean( [Double] 44, [Double] 55 )

# Hamming Distance:
 [MathNet.Numerics.Distance]::Hamming( [Double] 44, [Double] 55 )

Descriptive Statistics

# There are four main classes with static methods for statistics:
[MathNet.Numerics.Statistics.Statistics] | Get-Member -Static

# Optimized for single-dimensional arrays:
 [MathNet.Numerics.Statistics.ArrayStatistics] | Get-Member -Static

# Optimized for very large data sets:
 [MathNet.Numerics.Statistics.StreamingStatistics] | Get-Member -Static

# Optimized for sorted arrays:
 [MathNet.Numerics.Statistics.SortedArrayStatistics] | Get-Member -Static

# Generate some Double[] data for the examples below:
 [Double[]] $data = [MathNet.Numerics.Random.CryptoRandomSource]::Doubles(1000)

# Create an accelerator shortcut [STAT] for use of MathNet.Numerics.Statistics.Statistics:
 [psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Add('STAT','MathNet.Numerics.Statistics.Statistics')

# Common statistical calculations with unsorted data:
 [MathNet.Numerics.Statistics.Statistics]::Mean($data) #Mean or average, using full class name
 [STAT]::Mean($data) #Mean or average, but using the solution accelerator
 [STAT]::Median($data) #Median
 [STAT]::Minimum($data) #Minimum
 [STAT]::Maximum($data) #Maximum
 [STAT]::PopulationVariance($data) #Variance
 [STAT]::PopulationStandardDeviation($data) #Standard Deviation
 [STAT]::Covariance($data, $data) #Covariance

# Compute both mean and standard deviation simultaneously for efficiency:
 $both = [MathNet.Numerics.Statistics.ArrayStatistics]::MeanStandardDeviation($data)
 $both.Item1 #mean
 $both.Item2 #standard deviation

# When $data is sorted ascending, use SortedArrayStatistics instead:
 [MathNet.Numerics.Statistics.SortedArrayStatistics]::Median($data)

# Create a histogram of $data with 10 buckets:
 $hist = New-Object -TypeName MathNet.Numerics.Statistics.Histogram -ArgumentList $data,10
 $hist.BucketCount
 $hist.Item(0) #First bucket
 $hist.Item(9) #Tenth bucket
 $hist.Item(0).Count
 $hist.Item(0).LowerBound
 $hist.Item(0).UpperBound
 $hist.Item(0).Width

# Output each bucket from histogram with properties (get the script with better formatting):
 function Get-Bucket ( $Histogram )
 {
 $bucket = ' ' | select BucketIndex,Count,LowerBound,UpperBound,Width
 $lastbucket = $Histogram.BucketCount
 for ($i = 0 ; $i -lt $lastbucket ; $i++)
 {
 $bucket.BucketIndex = $i
 $bucket.Count = $Histogram.Item($i).Count
 $bucket.LowerBound = $Histogram.Item($i).LowerBound
 $bucket.UpperBound = $Histogram.Item($i).UpperBound
 $bucket.Width = $Histogram.Item($i).Width
 $bucket
 }
 }

#Example using the function:
 Get-Bucket -Histogram $hist | Format-Table -AutoSize

Probability Distributions

# Create a parameterized instance and show its distribution properties:
$gamma = New-Object -TypeName MathNet.Numerics.Distributions.Gamma -ArgumentList 2.0,1.5
$gamma

# Distribution functions:
 [Double] $a = $gamma.Density(2.3) # PDF
 [Double] $b = $gamma.DensityLn(2.3) # ln(PDF)
 [Double] $c = $gamma.CumulativeDistribution(0.7) # CDF

# Fill an array:
 [Double[]] $data = 1..1000
 $gamma.Samples($data)

Special Functions and Trigonometry

# Special Functions and the [FUNC] accelerator (see above on accelerators):
[MathNet.Numerics.SpecialFunctions]::Factorial(13)
[MathNet.Numerics.SpecialFunctions]::FactorialLn(31) #Log
[MathNet.Numerics.SpecialFunctions]::Binomial(15,7)
[MathNet.Numerics.SpecialFunctions]::BinomialLn(15,7) #Log
[MathNet.Numerics.SpecialFunctions]::Gamma(33)
[MathNet.Numerics.SpecialFunctions]::GammaLn(33) #Log

# Create an accelerator shortcut [FUNC] for use of MathNet.Numerics.SpecialFunctions:
 [psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Add('FUNC','MathNet.Numerics.SpecialFunctions')

[FUNC]::ExponentialIntegral(17,4)
 [FUNC]::Beta(17,2)
 [FUNC]::Erf(0.9)
 [FUNC]::Harmonic(37)

# Trigonometry
 [MathNet.Numerics.Trig]::Cos(36)
 [MathNet.Numerics.Trig]::Tan(12)
 [MathNet.Numerics.Trig]::DegreeToRadian(360)


Euclid and Number Theory

[MathNet.Numerics.Euclid]::GreatestCommonDivisor(99,33)
[MathNet.Numerics.Euclid]::LeastCommonMultiple(3,5,6)
[MathNet.Numerics.Euclid]::IsPowerOfTwo(1024)
[MathNet.Numerics.Euclid]::Remainder(7,3)
[MathNet.Numerics.Euclid]::Modulus(-5,3)

Curve Fitting: Linear Regression

# Compute intercept and slope using least squares fit:
[Double[]] $xdata = @(10,20,30,40,50)
[Double[]] $ydata = @(15,25,35,45,55)
$Line = [MathNet.Numerics.Fit]::Line($xdata, $ydata)
$Line.Item1 #Intercept
$Line.Item2 #Slope

# Compute coefficient of determination:
 [MathNet.Numerics.GoodnessOfFit]::RSquared($xdata, $ydata)

# Polynomial regression of order 3:
 [MathNet.Numerics.Fit]::Polynomial($xdata,$ydata,3)

# Multiple regression with QR decomposition:
 [Double[][]] $xy = @( [Double[]]@(1,4), [Double[]]@(2,5), [Double[]]@(3,2) )
 [Double[]] $z = @(15,20,10)
 $QR = [MathNet.Numerics.LinearRegression.DirectRegressionMethod]::QR
 [MathNet.Numerics.Fit]::MultiDim( $xy, $z, $true, $QR )

Loading and Saving Data

# Load the MathNet.Numerics.Data.Text DLL before calling the functions:
Add-Type -Path .\MathNet.Numerics.Data.Text.dll

# Function to save a matrix to a file, and download the script to see proper formatting:
 # (Defaults to tab-delimited Double[] data with no column headers.)
 Function Export-MatrixToFile
 {
 [CmdletBinding()] Param
 (
 [Parameter(Mandatory = $true)] $FilePath,
 [Parameter(Mandatory = $true)] $Matrix,
 $DataType = "Double",
 $Delimeter = "`t",
 $ColumnHeaders = $Null,
 $Format = $Null,
 $FormatProvider = $Null,
 $MissingValue = $Null
 )

#If $FilePath is not explicit, assume present working directory:
 if ( ($FilePath -like '.\*') -or ($FilePath -notlike '*\*'))
 { $FilePath = "$pwd\$FilePath" }

$Methods = [MathNet.Numerics.Data.Text.DelimitedWriter].GetMethods() | Where { $_.IsStatic -and $_.IsPublic -and $_.Name -eq 'Write' }

ForEach ($Method in $Methods)
 {
 if ($Method.GetParameters() | Where {$_.Name -eq 'filePath'})
 {
 $Generic = $Method.MakeGenericMethod($DataType)
 $Generic.Invoke( [MathNet.Numerics.Data.Text.DelimitedWriter], @($FilePath, $Matrix, $Delimeter, $ColumnHeaders, $Format, $FormatProvider, $MissingValue))
 Return
 }
 }
 }


# Example of calling the function:
 $Matrix = [MathNet.Numerics.LinearAlgebra.Matrix[Double]]::Build.Random(500,500)
 Export-MatrixToFile -FilePath "output.tsv" -Matrix $matrix

# Function to load a matrix from a file:
 # (Defaults to tab-delimited Double[] data with no column headers.)
 Function Import-MatrixFromFile
 {
 [CmdletBinding()] Param
 (
 [Parameter(Mandatory = $true)] $FilePath,
 $DataType = "Double",
 $Sparse = $false,
 $Delimeter = "`t",
 $HasHeaders = $false,
 $FormatProvider = $Null,
 $MissingValue = $Null
 )

#Get full path to $FilePath
 $FilePath = @(dir $FilePath)[0].FullName

$Methods = [MathNet.Numerics.Data.Text.DelimitedReader].GetMethods() | Where { $_.IsStatic -and $_.IsPublic -and $_.Name -eq 'Read' }

ForEach ($Method in $Methods)
 {
 if ($Method.GetParameters() | Where {$_.Name -eq 'filePath'})
 {
 $Generic = $Method.MakeGenericMethod($DataType)
 $Generic.Invoke( [MathNet.Numerics.Data.Text.DelimitedReader], @($FilePath, $Sparse, $Delimeter, $HasHeaders, $FormatProvider, $MissingValue))
 Return
 }
 }
 }

# Example of calling the function:
 Import-MatrixFromFile -FilePath "output.tsv"

NIST Matrix Market Text Files

# Load the MathNet.Numerics.Data.Text DLL:
Add-Type -Path .\MathNet.Numerics.Data.Text.dll

# Function to load a NIST Matrix Market file:
 # (Defaults to uncompressed, matrix of Double[], not vectors.)
 Function Import-NistMatrixMarketFile
 {
 [CmdletBinding()] Param
 (
 [Parameter(Mandatory = $true)] $FilePath,
 $DataType = "Double",
 [Switch] $IsVector,
 [Switch] $IsCompressed
 )

#Assume file contains a matrix
 if ($IsVector){$Name = 'ReadVector'} else {$Name = 'ReadMatrix'}

#Assume file is not compressed
 if ($IsCompressed){ $Compression = [MathNet.Numerics.Data.Text.Compression]::GZip }
 else { $Compression = [MathNet.Numerics.Data.Text.Compression]::Uncompressed }

#Get full path to $FilePath
 $FilePath = @(dir $FilePath)[0].FullName

$Methods = [MathNet.Numerics.Data.Text.MatrixMarketReader].GetMethods() | Where { $_.IsStatic -and $_.IsPublic -and $_.Name -eq $Name }

ForEach ($Method in $Methods)
 {
 if ($Method.GetParameters() | Where {$_.Name -eq 'filePath'})
 {
 $Generic = $Method.MakeGenericMethod($DataType)
 $Generic.Invoke( [MathNet.Numerics.Data.Text.MatrixMarketReader], @($FilePath, $Compression))
 Return
 }
 }
 }
# Example of calling the function:
 Import-NistMatrixMarketFile -FilePath "matrixmarket.mtx"

# Function to save a NIST Matrix Market file:
 # (Defaults to matrix of Double[], not vector.)
 Function Export-NistMatrixMarketFile
 {
 [CmdletBinding()] Param
 (
 [Parameter(Mandatory = $true)] $FilePath,
 [Parameter(Mandatory = $true)] $Matrix,
 $DataType = "Double",
 [Switch] $IsVector,
 [Switch] $IsCompressed
 )

#Assume file will contain a matrix
 if ($IsVector){$Name = 'WriteVector'} else {$Name = 'WriteMatrix'}

#Assume file is not compressed
 if ($IsCompressed){ $Compression = [MathNet.Numerics.Data.Text.Compression]::GZip }
 else { $Compression = [MathNet.Numerics.Data.Text.Compression]::Uncompressed }

#If $FilePath is not explicit, assume present working directory:
 if ( ($FilePath -like '.\*') -or ($FilePath -notlike '*\*'))
 { $FilePath = "$pwd\$FilePath" }

$Methods = [MathNet.Numerics.Data.Text.MatrixMarketWriter].GetMethods() | Where { $_.IsStatic -and $_.IsPublic -and $_.Name -eq $Name }

ForEach ($Method in $Methods)
 {
 if ($Method.GetParameters() | Where {$_.Name -eq 'filePath'})
 {
 $Generic = $Method.MakeGenericMethod($DataType)
 $Generic.Invoke( [MathNet.Numerics.Data.Text.MatrixMarketWriter], @($FilePath, $Matrix, $Compression))
 Return
 }
 }
 }
# Examples of calling the function:
 $Matrix = [MathNet.Numerics.LinearAlgebra.Matrix[Double]]::Build.Random(500,500)
 Export-NistMatrixMarketFile -FilePath "matrixmarket2.mtx" -Matrix $Matrix

$Vector = [MathNet.Numerics.LinearAlgebra.Vector[Double]]::Build.Random(1000)
 Export-NistMatrixMarketFile -FilePath "matrixmarket3.mtx" -Matrix $Vector -IsVector

Loading and Saving Data Using PowerShell Cmdlets

# Create a matrix to save and restore and add the [M] accelerator:
$OriginalMatrix = [MathNet.Numerics.LinearAlgebra.Matrix[Double]]::Build.Random(5000,5000)
[psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Add('M','MathNet.Numerics.LinearAlgebra.Matrix[Double]')

# Save as XML with UTF-8 encoding to reduce file size (creates a 1GB file):
 $OriginalMatrix | Export-Clixml -Encoding UTF8 -Path .\Matrix-5000x5000.xml

# Restore the original matrix from XML using accelerator:
 [Double[]] $RestoredValues = (Import-Clixml -Path .\Matrix-5000x5000.xml).Values
 $RestoredMatrix = [M]::Build.DenseOfColumnMajor(5000,5000,$RestoredValues)
 

Remember, too, that data can simply be saved to a CSV text file (using Export-Csv) and then opened directly in Excel.

Update History

26.Jun.2015: Original.
28.Jun.2015: Added functions for importing/exporting data.
29.Jun.2015: Added some Intel MKL performance test results.
22.May.2016: Updated test results for PoSh 5.0 and latest Intel MKL version.
17.May.2021: Updated scripts download link.

Share:
TwitterLinkedInFacebook
Copy url Url was copied to clipboard
Subscribe to SANS Newsletters
Receive curated news, vulnerabilities, & security awareness tips
United States
Canada
United Kingdom
Spain
Belgium
Denmark
Norway
Netherlands
Australia
India
Japan
Singapore
Afghanistan
Aland Islands
Albania
Algeria
American Samoa
Andorra
Angola
Anguilla
Antarctica
Antigua and Barbuda
Argentina
Armenia
Aruba
Austria
Azerbaijan
Bahamas
Bahrain
Bangladesh
Barbados
Belarus
Belize
Benin
Bermuda
Bhutan
Bolivia
Bonaire, Sint Eustatius, and Saba
Bosnia And Herzegovina
Botswana
Bouvet Island
Brazil
British Indian Ocean Territory
Brunei Darussalam
Bulgaria
Burkina Faso
Burundi
Cambodia
Cameroon
Cape Verde
Cayman Islands
Central African Republic
Chad
Chile
China
Christmas Island
Cocos (Keeling) Islands
Colombia
Comoros
Cook Islands
Costa Rica
Croatia (Local Name: Hrvatska)
Curacao
Cyprus
Czech Republic
Democratic Republic of the Congo
Djibouti
Dominica
Dominican Republic
East Timor
East Timor
Ecuador
Egypt
El Salvador
Equatorial Guinea
Eritrea
Estonia
Ethiopia
Falkland Islands (Malvinas)
Faroe Islands
Fiji
Finland
France
French Guiana
French Polynesia
French Southern Territories
Gabon
Gambia
Georgia
Germany
Ghana
Gibraltar
Greece
Greenland
Grenada
Guadeloupe
Guam
Guatemala
Guernsey
Guinea
Guinea-Bissau
Guyana
Haiti
Heard And McDonald Islands
Honduras
Hong Kong
Hungary
Iceland
Indonesia
Iraq
Ireland
Isle of Man
Israel
Italy
Jamaica
Jersey
Jordan
Kazakhstan
Kenya
Kiribati
Korea, Republic Of
Kosovo
Kuwait
Kyrgyzstan
Lao People's Democratic Republic
Latvia
Lebanon
Lesotho
Liberia
Liechtenstein
Lithuania
Luxembourg
Macau
Macedonia
Madagascar
Malawi
Malaysia
Maldives
Mali
Malta
Marshall Islands
Martinique
Mauritania
Mauritius
Mayotte
Mexico
Micronesia, Federated States Of
Moldova, Republic Of
Monaco
Mongolia
Montenegro
Montserrat
Morocco
Mozambique
Myanmar
Namibia
Nauru
Nepal
Netherlands Antilles
New Caledonia
New Zealand
Nicaragua
Niger
Nigeria
Niue
Norfolk Island
Northern Mariana Islands
Oman
Pakistan
Palau
Palestine
Panama
Papua New Guinea
Paraguay
Peru
Philippines
Pitcairn
Poland
Portugal
Puerto Rico
Qatar
Reunion
Romania
Russian Federation
Rwanda
Saint Bartholemy
Saint Kitts And Nevis
Saint Lucia
Saint Martin
Saint Vincent And The Grenadines
Samoa
San Marino
Sao Tome And Principe
Saudi Arabia
Senegal
Serbia
Seychelles
Sierra Leone
Sint Maarten
Slovakia
Slovenia
Solomon Islands
South Africa
South Georgia and the South Sandwich Islands
South Sudan
Sri Lanka
St. Helena
St. Pierre And Miquelon
Suriname
Svalbard And Jan Mayen Islands
Swaziland
Sweden
Switzerland
Taiwan
Tajikistan
Tanzania
Thailand
Togo
Tokelau
Tonga
Trinidad And Tobago
Tunisia
Turkey
Turkmenistan
Turks And Caicos Islands
Tuvalu
Uganda
Ukraine
United Arab Emirates
United States Minor Outlying Islands
Uruguay
Uzbekistan
Vanuatu
Vatican City
Venezuela
Vietnam
Virgin Islands (British)
Virgin Islands (U.S.)
Wallis And Futuna Islands
Western Sahara
Yemen
Yugoslavia
Zambia
Zimbabwe

By providing this information, you agree to the processing of your personal data by SANS as described in our Privacy Policy.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Tags:
  • Cybersecurity and IT Essentials

Related Content

Blog
Penetration Testing and Red Teaming, Cybersecurity and IT Essentials
January 4, 2023
Cloud Scanning for Vulnerability Discovery
In this article we'll look at the step-by-step process of scanning a cloud provider's network for target enumeration.
370x370_Joshua-Wright.jpg
Joshua Wright
read more
Blog
Untitled_design-43.png
Digital Forensics and Incident Response, Cybersecurity and IT Essentials, Industrial Control Systems Security, Purple Team, Open-Source Intelligence (OSINT), Penetration Testing and Red Teaming, Cyber Defense, Cloud Security, Security Management, Legal, and Audit
December 8, 2021
Good News: SANS Virtual Summits Will Remain FREE for the Community in 2022
They’re virtual. They’re global. They’re free.
370x370-person-placeholder.png
Emily Blades
read more
Blog
Cybersecurity and IT Essentials
April 3, 2020
Instructor Spotlight: Keith Palmgren, SANS Senior Instructor
Meet Keith Palmgren, a cybersecurity professional with over 30 years of experience, specializing in the IT Security field.
SANS_Filler_Avatar.jpg
SANS Institute
read more
  • Register to Learn
  • Courses
  • Certifications
  • Degree Programs
  • Cyber Ranges
  • Job Tools
  • Security Policy Project
  • Posters & Cheat Sheets
  • White Papers
  • Focus Areas
  • Cyber Defense
  • Cloud Security
  • Cybersecurity Leadership
  • Digital Forensics
  • Industrial Control Systems
  • Offensive Operations
Subscribe to SANS Newsletters
Receive curated news, vulnerabilities, & security awareness tips
United States
Canada
United Kingdom
Spain
Belgium
Denmark
Norway
Netherlands
Australia
India
Japan
Singapore
Afghanistan
Aland Islands
Albania
Algeria
American Samoa
Andorra
Angola
Anguilla
Antarctica
Antigua and Barbuda
Argentina
Armenia
Aruba
Austria
Azerbaijan
Bahamas
Bahrain
Bangladesh
Barbados
Belarus
Belize
Benin
Bermuda
Bhutan
Bolivia
Bonaire, Sint Eustatius, and Saba
Bosnia And Herzegovina
Botswana
Bouvet Island
Brazil
British Indian Ocean Territory
Brunei Darussalam
Bulgaria
Burkina Faso
Burundi
Cambodia
Cameroon
Cape Verde
Cayman Islands
Central African Republic
Chad
Chile
China
Christmas Island
Cocos (Keeling) Islands
Colombia
Comoros
Cook Islands
Costa Rica
Croatia (Local Name: Hrvatska)
Curacao
Cyprus
Czech Republic
Democratic Republic of the Congo
Djibouti
Dominica
Dominican Republic
East Timor
East Timor
Ecuador
Egypt
El Salvador
Equatorial Guinea
Eritrea
Estonia
Ethiopia
Falkland Islands (Malvinas)
Faroe Islands
Fiji
Finland
France
French Guiana
French Polynesia
French Southern Territories
Gabon
Gambia
Georgia
Germany
Ghana
Gibraltar
Greece
Greenland
Grenada
Guadeloupe
Guam
Guatemala
Guernsey
Guinea
Guinea-Bissau
Guyana
Haiti
Heard And McDonald Islands
Honduras
Hong Kong
Hungary
Iceland
Indonesia
Iraq
Ireland
Isle of Man
Israel
Italy
Jamaica
Jersey
Jordan
Kazakhstan
Kenya
Kiribati
Korea, Republic Of
Kosovo
Kuwait
Kyrgyzstan
Lao People's Democratic Republic
Latvia
Lebanon
Lesotho
Liberia
Liechtenstein
Lithuania
Luxembourg
Macau
Macedonia
Madagascar
Malawi
Malaysia
Maldives
Mali
Malta
Marshall Islands
Martinique
Mauritania
Mauritius
Mayotte
Mexico
Micronesia, Federated States Of
Moldova, Republic Of
Monaco
Mongolia
Montenegro
Montserrat
Morocco
Mozambique
Myanmar
Namibia
Nauru
Nepal
Netherlands Antilles
New Caledonia
New Zealand
Nicaragua
Niger
Nigeria
Niue
Norfolk Island
Northern Mariana Islands
Oman
Pakistan
Palau
Palestine
Panama
Papua New Guinea
Paraguay
Peru
Philippines
Pitcairn
Poland
Portugal
Puerto Rico
Qatar
Reunion
Romania
Russian Federation
Rwanda
Saint Bartholemy
Saint Kitts And Nevis
Saint Lucia
Saint Martin
Saint Vincent And The Grenadines
Samoa
San Marino
Sao Tome And Principe
Saudi Arabia
Senegal
Serbia
Seychelles
Sierra Leone
Sint Maarten
Slovakia
Slovenia
Solomon Islands
South Africa
South Georgia and the South Sandwich Islands
South Sudan
Sri Lanka
St. Helena
St. Pierre And Miquelon
Suriname
Svalbard And Jan Mayen Islands
Swaziland
Sweden
Switzerland
Taiwan
Tajikistan
Tanzania
Thailand
Togo
Tokelau
Tonga
Trinidad And Tobago
Tunisia
Turkey
Turkmenistan
Turks And Caicos Islands
Tuvalu
Uganda
Ukraine
United Arab Emirates
United States Minor Outlying Islands
Uruguay
Uzbekistan
Vanuatu
Vatican City
Venezuela
Vietnam
Virgin Islands (British)
Virgin Islands (U.S.)
Wallis And Futuna Islands
Western Sahara
Yemen
Yugoslavia
Zambia
Zimbabwe

By providing this information, you agree to the processing of your personal data by SANS as described in our Privacy Policy.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
  • © 2023 SANS™ Institute
  • Privacy Policy
  • Contact
  • Careers
  • Twitter
  • Facebook
  • Youtube
  • LinkedIn