VB.Net Chart Equation and R² Value - excel

Goal
I have a chart in Excel and I'm trying to replicate the same chart in VB.Net. I can get the chart data to be inputted correctly. I don't know how to retrieve the equation and R² value in a VB.Net chart control, as shown in my Excel chart.
Current Problem
Here is the data that is gotten in my Excel graph and Vb.Net chart:
' X Y
'0.895, 120.1
'0.978, 160.1
'1.461, 240.1
'1.918, 320.1
'2.343, 400.2
'2.769, 480.2
'3.131, 560.2
'3.493, 640.3
'3.797, 720.3
'4.089, 800.3
I get the following result from this (Excel):
As you can see, I receive a formula y= 203.83x - 62.797 and R²=0.9949
I'm trying to get the same result in Vb.Net but I am unable to find where this data is stored.
Any ideas?

I finally figured out my issue. Here is the clsTrendline.vb that I fetched using the help of multiple people/threads/conversion websites/Excel help on this site.
Public Class Trendline
#Region "Variables"
Private m_Slope As Decimal
Private m_Intercept As Decimal
Private m_Start As Decimal
Private m_End As Decimal
Private m_RSquared As Decimal
#End Region
#Region "Properties"
Public Property Slope() As Decimal
Get
Return m_Slope
End Get
Private Set
m_Slope = Value
End Set
End Property
Public Property Intercept() As Decimal
Get
Return m_Intercept
End Get
Private Set
m_Intercept = Value
End Set
End Property
Public Property Start() As Decimal
Get
Return m_Start
End Get
Private Set
m_Start = Value
End Set
End Property
Public Property [End]() As Decimal
Get
Return m_End
End Get
Private Set
m_End = Value
End Set
End Property
Public Property RSquared As Decimal
Get
Return m_RSquared
End Get
Set(value As Decimal)
m_RSquared = value
End Set
End Property
#End Region
#Region "New..."
Public Sub New(yAxisValues As IList(Of Decimal), xAxisValues As IList(Of Decimal))
Me.New(yAxisValues.[Select](Function(t, i) New Tuple(Of Decimal, Decimal)(xAxisValues(i), t)))
End Sub
Public Sub New(data As IEnumerable(Of Tuple(Of [Decimal], [Decimal])))
Dim cachedData = data.ToList()
Dim n = cachedData.Count
Dim sumX = cachedData.Sum(Function(x) x.Item1)
Dim sumX2 = cachedData.Sum(Function(x) x.Item1 * x.Item1)
Dim sumY = cachedData.Sum(Function(x) x.Item2)
Dim sumY2 = cachedData.Sum(Function(x) x.Item2 * x.Item2)
Dim sumXY = cachedData.Sum(Function(x) x.Item1 * x.Item2)
'b = (sum(x*y) - sum(x)sum(y)/n)
' / (sum(x^2) - sum(x)^2/n)
Slope = (sumXY - ((sumX * sumY) / n)) / (sumX2 - (sumX * sumX / n))
'a = sum(y)/n - b(sum(x)/n)
Intercept = (sumY / n) - (Slope * (sumX / n))
' r = (n * (Exy) - (Ex * Ey)) / (((n * (Ex2) - (Ex) ^ 2) ^ (1 / 2)) * ((n * (Ey2) - (Ey) ^ 2) ^ (1 / 2)))
RSquared = ((n * (sumXY) - (sumX * sumY)) / (((n * (sumX2) - (sumX) ^ 2) ^ (1 / 2)) * ((n * (sumY2) - (sumY) ^ 2) ^ (1 / 2)))) ^ 2
Start = GetYValue(cachedData.Min(Function(a) a.Item1))
[End] = GetYValue(cachedData.Max(Function(a) a.Item1))
End Sub
#End Region
#Region "Methods / Functions"
Public Function GetYValue(xValue As Decimal) As Decimal
Return Intercept + Slope * xValue
End Function
#End Region
End Class
Hopefully this will help someone!

Related

Rearrange equation to solve for a different variable

I am looking at VBA code (function) written by someone else.
Here is the code:
Function EuropeanDelta(StrikePrice, MarketPrice, Volatility, InterestRate As Double, PC As String, ValueDate, ExpiryDate As Date, Optional PriceOrYield As String = "P") As Double
Rem Declare our working variables
Dim r As Double
Dim d1 As Double
Dim d2 As Double
Dim t As Double
Dim SqT As Double
Rem End of variable declaration
If PriceOrYield = "Y" Then
MarketPrice = 100 - MarketPrice
StrikePrice = 100 - StrikePrice
If PC = "C" Then
PC = "P"
Else
PC = "C"
End If
End If
Rem Initiase our working variables
t = (ExpiryDate - ValueDate) / 365
SqT = Sqr(t)
r = Application.WorksheetFunction.Ln(1 + InterestRate)
d1 = (Application.WorksheetFunction.Ln(MarketPrice / StrikePrice) + (Volatility * Volatility * 0.5) * t) / (Volatility * SqT)
Rem Quick logic to deal with Calls or Puts
If PC = "C" Then
EuropeanDelta = Exp(-r * t) * Application.WorksheetFunction.NormSDist(d1)
Else
EuropeanDelta = -Exp(-r * t) * Application.WorksheetFunction.NormSDist(-d1)
End If
If PriceOrYield = "Y" Then
EuropeanDelta = EuropeanDelta * -1
End If
End Function
The whole problem is based around the line for "d1". I would like to re-organise to solve for "StrikePrice". I have tried writing it out mathematically and then re-arranging, then swapping back to VBA.
#duffymo is correct, but am giving the answer directly in terms of VBA code
' d1 = (Log(MarketPrice / StrikePrice) + (Volatility * Volatility * 0.5) * t) / (Volatility * Sqr(t))
'
' Volatility * Sqr(t) * d1 = Log(MarketPrice / StrikePrice) + Volatility^2 * t/2
'
' Log(MarketPrice / StrikePrice) = Volatility * Sqr(t) * d1 - Volatility^2 * t/2
'
' MarketPrice / StrikePrice = Exp(Volatility * Sqr(t) * d1 - Volatility^2 * t/2)
'
StrikePrice = MarketPrice / Exp(Volatility * Sqr(t) * d1 - Volatility^2 * t/2)
Other Notes :
For brevity replace Application.WorksheetFunction.Ln() with Log()
There is no need cache SqT = Sqr(t) since it is only used once.
For clarity replace Volatility*Volatility with Volatility^2 as internally it does the same thing.
This is just algebra - high school math.
Take it in steps. Make sure you do the same operation to both sides to make sure that equality still holds.
Here's your starting equation:
d = {ln(m/s) + v*v*t/2}/(v*sqrt(t))
Multiply both sides by the denominator of the RHS:
d*v*sqrt(t) = ln(m/s) + v*v*t/2
Subtract v*v*t/2 from both sides:
(d*v*sqrt(t) - v*v*t/2) = ln(m/s)
Apply the exponential function to both sides, noting that exp(ln(x)) = x:
exp(d*v*sqrt(t) - v*v*t/2) = m/s
Multiply both sides by s:
s*exp(d*v*sqrt(t) - v*v*t/2) = m
Divide both sides by exp(d*v*sqrt(t) - v*v*t/2) to get the desired result:
s = m/exp(d*v*sqrt(t) - v*v*t/2)
Let's see if this function makes sense.
At t = 0 the denominator exp(0) = 1, so the strike price is equal to the market price.
As t -> infinity, we hope that the denominator gets large so s -> zero. L'Hospital's Rule will help here.

visual basic for application Excel

I have written a code in module 1. I get the correct value for the output. But, When I call it in module 2, the output value is zero. I would be thankful, if anyone can help me.
Module 1:
Sub MuAndVuCalculations()
BeamFlangeWidth = Sheets("MuVu").Range("D7")
BeamFlangeThickness = Sheets("MuVu").Range("D8")
BeamWebHeight = Sheets("MuVu").Range("D9")
M3 = (0.5 * BeamFlangeWidth * BeamWebHeight * BeamWebHeight ^ 2)
End Sub
module 2:
Sub Main()
Call MuAndVuCalculations
M = 5 Debug.Print M3 + M
End Sub
In module 2 I can not see M3 in Immediate window and the output of the M3+5 is 5
You have to declare M3 as public to access from the other function.
Add the first line above your code in module1:
Public M3 As Long 'add this line
Sub MuAndVuCalculations()
BeamFlangeWidth = Sheets("Tabelle1").Range("D7")
BeamFlangeThickness = Sheets("Tabelle1").Range("D8")
BeamWebHeight = Sheets("Tabelle1").Range("D9")
M3 = (0.5 * BeamFlangeWidth * BeamWebHeight * BeamWebHeight ^ 2)
End Sub

Average, StDev with more than 65536 elements?

I'm trying to calculate (in VBA Excel) the Average and StDev of an array with more than 65536 elements. Something like this:
Mitja = worksheetfunction.Average(array())
DesvTip = worksheetfunction.StDev(array())
While the dimension of the array is smaller than 65536 there is no problem but, when it's bigger it gives me an error!
I know that this VBA functions can't work with more than 65536 data so, how can I obtain this parameters in VBA?
Apreciate your comments. Thanks a lot! :))
You can calculate mean and standard deviation without having to store all the values. Just keep a running total of sum, sum of squares, and number of points. You can have as many points as integer number of points will allow that way.
Here's how I'd do it in Java. Feel free to crib.
package statistics;
/**
* Statistics
* #author Michael
* #link http://stackoverflow.com/questions/11978667/online-algorithm-for-calculating-standrd-deviation/11978689#11978689
* #link http://mathworld.wolfram.com/Variance.html
* #since 8/15/12 7:34 PM
*/
public class Statistics {
private int n;
private double sum;
private double sumsq;
public void reset() {
this.n = 0;
this.sum = 0.0;
this.sumsq = 0.0;
}
public synchronized void addValue(double x) {
++this.n;
this.sum += x;
this.sumsq += x*x;
}
public synchronized double calculateMean() {
double mean = 0.0;
if (this.n > 0) {
mean = this.sum/this.n;
}
return mean;
}
public synchronized double calculateVariance() {
double variance = 0.0;
if (this.n > 0) {
variance = Math.sqrt(this.sumsq-this.sum*this.sum/this.n)/this.n;
}
return variance;
}
public synchronized double calculateStandardDeviation() {
double deviation = 0.0;
if (this.n > 1) {
deviation = Math.sqrt((this.sumsq-this.sum*this.sum/this.n)/(this.n-1));
}
return deviation;
}
}
Use the following algorithm if the data is stored in an array x(1 to N, 1 to 1), where N is the number of data points
sum = 0# : sumsq = 0#
for i=1 to N
sum = sum + x(i,1)
sumsq = sumsq + x(i,1)^2
next i
average = sum/N
stddev = Sqr( sumsq/N^2 - sum^2/N^3 )
:Note:
To fill the array use the notation
Dim r as Range, x() as Variant
Set r = Range("A1").Resize(N,1)
x = r.Value
Thanks for both comments. Finally we did something similar. I hope it will be usefull for someone with the same problem. Our code:
sum = 0
sumq = 0
For i = 0 To ((2 * N) - 1)
sum = sum + h_normal(i)
Next i
media = sum / (2 * N)
For j = 0 To ((2 * N) - 1)
sumsq = sumsq + (h_normal(j) - media) ^ 2
Next j
desviaci(h - 1) = Math.Sqr(sumsq / ((2 * N) - 1))

Set VBA macro for Excel to run a series of Linear Equations by taking variable from several rows?

I've got a set of equations which I'd like to be repeated taking variables from the next row down for each of the columns at which each variable is located. I am a beginner, so my coding is probably not to scratch:
Sub Iteration()
Dim al, ab, ae As Double
Dim as1, as2 As Double
'etc
as1 = Range("CG7")
as2 = Range("CG8")
aA1 = Range("BQ7")
'etc
intCounter = 0
For intCounter = 1 To 10000
Let x = ((aN1 * 1000) - (as1 * aA1) + (as2 * aA2)) / (al * fc * ae * ab)
Let x2 = ((aN12 * 1000) - (as12 * aA12) + (as22 * aA22)) / (al2 * fc2 * ae2 * ab2)
Next
Sheets("Sheet1").Range("CJ7").Value = x
End Sub
I've done this for several variables which I've set as the range relative to each variable value. And then for the next row I've had to redo the whole equation and set the variables again for the next row down. Is there any way to set the variables (possibly with a relative cell reference?) which will skip to the cell in the next row for the next calculation? Consider also that there are 36 rows for calculation and about 9 variables!
If I understand you correctly, how about something like this:
Sub Iteration()
Dim al, ab, ae As Double
Dim as1, as2 As Double
'etc
intCounter = 0
For intCounter = 0 To 10000
as1 = Range("CG7").Offset(intCounter)
as2 = Range("CG8").Offset(intCounter)
aA1 = Range("BQ7").Offset(intCounter)
'etc
Let x = ((aN1 * 1000) - (as1 * aA1) + (as2 * aA2)) / (al * fc * ae * ab)
Let x2 = ((aN12 * 1000) - (as12 * aA12) + (as22 * aA22)) / (al2 * fc2 * ae2 * ab2)
Next
Sheets("Sheet1").Range("CJ7").Value = x
End Sub

SQLite full-text search relevance ranking

I am using the fts4 extension of sqlite3 to enable full-text indexing and searching of text data. This it working great, but I've noticed that the results are not relevance-ranked at all. I guess I am too used to Lucene. I've seen some brief suggestions to write a custom rank method using the matchinfo() results, but it's not clear to me how this is done, or whether there are any sophisticated examples out there. How have others dealt with this?
There's a complete example in the documentation, look at the end of appendix a. You'll need to do slightly more work to get a good relevance ranking as the function provided is good only for getting started. For example, with matchinfo(table,'pcnalx') there's enough information to implement Okapi BM25.
There seems to be a distinct lack of documentation on how to implement Okapi BM25 in C and it seems it is an unspoken thing that the implementation is left as an exercise for the user.
Well I found the bro of a programmer "Radford 'rads' Smith" who chucked this up on GitHub
https://github.com/rads/sqlite-okapi-bm25
It only implements BM25 although I'm looking into BM25F tweaks now....
....and here it is.
https://github.com/neozenith/sqlite-okapi-bm25
For FTS5, according to SQLite FTS5 Extension,
FTS5 has no matchinfo().
FTS5 supports ORDER BY rank
So very simply, something like
SELECT * FROM email WHERE email MATCH 'fts5' ORDER BY rank;
without DESC works.
Here is an implementation of Okapi BM25. Using this in combination with the suggestions at SQLite.org will help you generate a relevance-ranked MATCH query. This was written all in VB.Net and the query was called using System.Data.SQLite functions. The custom SQLiteFunction at the end can be called from the SQL code without issue, as long as the SQL code is called using System.Data.SQLite functions.
Public Class MatchInfo
Property matchablePhrases As Integer
Property userDefinedColumns As Integer
Property totalDocuments As Integer
Private _int32HitData As List(Of Integer)
Private _longestSubsequencePhraseMatches As New List(Of Integer)
Private _tokensInDocument As New List(Of Integer)
Private _averageTokensInDocument As New List(Of Integer)
Private _max_hits_this_row As Integer?
Public ReadOnly Property max_hits_this_row As Integer
Get
If _max_hits_this_row Is Nothing Then
_max_hits_this_row = 0
For p = 0 To matchablePhrases - 1
For c = 0 To userDefinedColumns - 1
Dim myHitsThisRow As Integer = hits_this_row(p, c)
If myHitsThisRow > _max_hits_this_row Then
_max_hits_this_row = myHitsThisRow
End If
Next
Next
End If
Return _max_hits_this_row
End Get
End Property
Private _max_hits_all_rows As Integer?
Public ReadOnly Property max_hits_all_rows As Integer
Get
If _max_hits_all_rows Is Nothing Then
_max_hits_all_rows = 0
For p = 0 To matchablePhrases - 1
For c = 0 To userDefinedColumns - 1
Dim myHitsAllRows As Integer = hits_all_rows(p, c)
If myHitsAllRows > _max_hits_all_rows Then
_max_hits_all_rows = myHitsAllRows
End If
Next
Next
End If
Return _max_hits_all_rows
End Get
End Property
Private _max_docs_with_hits As Integer?
Public ReadOnly Property max_docs_with_hits As Integer
Get
If _max_docs_with_hits Is Nothing Then
_max_docs_with_hits = 0
For p = 0 To matchablePhrases - 1
For c = 0 To userDefinedColumns - 1
Dim myDocsWithHits As Integer = docs_with_hits(p, c)
If myDocsWithHits > _max_docs_with_hits Then
_max_docs_with_hits = myDocsWithHits
End If
Next
Next
End If
Return _max_docs_with_hits
End Get
End Property
Private _BM25Rank As Double?
Public ReadOnly Property BM25Rank As Double
Get
If _BM25Rank Is Nothing Then
_BM25Rank = 0
'calculate BM25 Rank
'http://en.wikipedia.org/wiki/Okapi_BM25
'k1, calibrates the document term frequency scaling. Having k1 as 0 corresponds to a binary model – no term frequency. Increasing k1 will give rare words more boost.
'b, calibrates the scaling by document length, and can take values from 0 to 1, where having 0 means no length normalization and having 1 corresponds to fully scaling the term weight by the document length.
Dim k1 As Double = 1.2
Dim b As Double = 0.75
For column = 0 To userDefinedColumns - 1
For phrase = 0 To matchablePhrases - 1
Dim IDF As Double = Math.Log((totalDocuments - hits_all_rows(phrase, column) + 0.5) / (hits_all_rows(phrase, column) + 0.5))
Dim score As Double = (IDF * ((hits_this_row(phrase, column) * (k1 + 1)) / (hits_this_row(phrase, column) + k1 * (1 - b + b * _tokensInDocument(column) / _averageTokensInDocument(column)))))
If score < 0 Then
score = 0
End If
_BM25Rank += score
Next
Next
End If
Return _BM25Rank
End Get
End Property
Public Sub New(raw_pcnalsx_MatchInfo As Byte())
Dim int32_pcsx_MatchInfo As New List(Of Integer)
For i = 0 To raw_pcnalsx_MatchInfo.Length - 1 Step 4
int32_pcsx_MatchInfo.Add(BitConverter.ToUInt32(raw_pcnalsx_MatchInfo, i))
Next
'take the raw data and parse it out
Me.matchablePhrases = int32_pcsx_MatchInfo(0)
int32_pcsx_MatchInfo.RemoveAt(0)
Me.userDefinedColumns = int32_pcsx_MatchInfo(0)
int32_pcsx_MatchInfo.RemoveAt(0)
Me.totalDocuments = int32_pcsx_MatchInfo(0)
int32_pcsx_MatchInfo.RemoveAt(0)
'remember that the columns are 0-based
For i = 0 To userDefinedColumns - 1
_averageTokensInDocument.Add(int32_pcsx_MatchInfo(0))
int32_pcsx_MatchInfo.RemoveAt(0)
Next
For i = 0 To userDefinedColumns - 1
_tokensInDocument.Add(int32_pcsx_MatchInfo(0))
int32_pcsx_MatchInfo.RemoveAt(0)
Next
For i = 0 To userDefinedColumns - 1
_longestSubsequencePhraseMatches.Add(int32_pcsx_MatchInfo(0))
int32_pcsx_MatchInfo.RemoveAt(0)
Next
_int32HitData = New List(Of Integer)(int32_pcsx_MatchInfo)
End Sub
Public Function hits_this_row(phrase As Integer, column As Integer) As Integer
Return _int32HitData(3 * (column + phrase * userDefinedColumns) + 0)
End Function
Public Function hits_all_rows(phrase As Integer, column As Integer) As Integer
Return _int32HitData(3 * (column + phrase * userDefinedColumns) + 1)
End Function
Public Function docs_with_hits(phrase As Integer, column As Integer) As Integer
Return _int32HitData(3 * (column + phrase * userDefinedColumns) + 2)
End Function
End Class
<SQLiteFunction("Rank", 1, FunctionType.Scalar)>
Public Class Rank
Inherits SQLiteFunction
Public Overrides Function Invoke(args() As Object) As Object
Return New MatchInfo(args(0)).BM25Rank
End Function
End Class

Resources