I have the below function that I am using to enter 2 initial parameters, rho and V, and based on minimized sum of squared errors, I want it to return the estimated parameters, rho and V.
Public Function RhoAndV(params, MktStrike, MktVol, Vol, Fwd, Tau, Beta)
Dim rho, V, Alpha As Double
Dim i As Integer, L As Integer
Dim sqdError() As Double, ModelVol() As Double
rho = params(1)
V = params(2)
Alpha = AFn(Fwd, Fwd, Tau, Vol, Beta, rho, V)
'MsgBox ("Alpha=" & Alpha)
L = MktVol.Cells.Count
ReDim ModelVol(L) As Double, sqdError(L) As Double
For i = 1 To L
ModelVol(i) = Vfn(Alpha, Beta, rho, V, Fwd, MktStrike(i), Tau)
'MsgBox ("ModelVol(i)=" & ModelVol(i))
sqdError(i) = (ModelVol(i) - MktVol(i)) ^ 2
Next i
RhoAndV = Application.SUM(sqdError)
End Function
I have rho and V in cells A1:A2 with values 0.1 and 0.1, so I select A1:A2 as params.
In cells C3:C6, I have MktStrike with values
30
31
32
33
In cells D3:D6, I have MktVol with values
0.23
0.24
0.25
0.26
This function now returns the sumof squared errors (I run it in Excel as =RhoAndV(A1:A3,C3:C6,D3:D6,0.25,10,1,0.5) and it returns .003. However, I want it to return the estimated parameters, rho and V. Can anyone please tell me how to fix this function to do so?
You'd modify your original function to something like the example below. How you return the values depends on whether you want to return them to a row (eg D3:E3) or column (eg. D3:D4)
Function RhoAndV(params, MktStrike, MktVol, Vol, Fwd, Tau, Beta)
'rest of your code
'RhoAndV = Array(rho, V) 'returning to a row
RhoAndV = Application.Transpose(Array(rho, V)) 'returning to a column
End Function
Related
Currently, I am working on a program that integrates x + x^2 + e^x + 2cos(x/2) - 1 with three input variables, a, b, and n. What I need returned is the numerical integral from a to b with n increments. The function also has to return trapezoids for each n as a column vector. Thus, the integral value as a scalar, and a vector of values.
I've gotten to a point where the function int_f_1 is undefined for some reason, and I have no idea why. I thought by nesting that function under the test function, it would help. But it does not, and I don't know why that is. Any suggestions?
function [y] = test_function_1(x);
y = x + x.^2 + exp(x) + 2*cos(x/2) - 1
end
function [int_f, increment] = int_f_1 (a, b, n);
f = #test_function_1;
h = a + b ./ n
increments = h
int_f = integral(h, f)
end
How can I make a function with a vector as input and a matrix as an output?
I have to write a function that will convert cubic meters to liters and English gallons. The input should be a vector containing volume values in m ^ 3 to be converted. The result should be a matrix in which the first column contains the result in m ^ 3, the second liter, the third English gallon.
I tried this:
function [liter, gallon] = function1 (x=[a, b, c, d]);
liter= a-10+d-c;
gallon= b+15+c;
endfunction
You're almost there.
The x=[a,b,c,d] part is superfluous, your argument should be just x.
function [liter, gallon] = function1 (x);
a = x(1); b = x(2); c = x(3); d = x(4);
liter = a - 10 + d - c;
gallon = b + 15 + c;
endfunction
If you want your code to be safe and guard against improper inputs, you can perform such checks manually inside the function, e.g.
assert( nargin < 1 || nargin > 4, "Wrong number of inputs supplied");
The syntax x=[a,b,c,d] does not apply to octave; this is reserved for setting up default arguments, in which case a, b, c, and d should be given specific values that you'd want as the defaults. if you had said something like x = [1,2,3,4], then this would be fine, and it would mean that if you called the function without an argument, it would set x up to this default value.
Here is the Main Program:
PROGRAM integration
EXTERNAL funct
DOUBLE PRECISION funct, a , b, sum, h
INTEGER n, i
REAL s
PARAMETER (a = 0, b = 10, n = 200)
h = (b-a)/n
sum = 0.0
DO i = 1, n
sum = sum+funct(i*h+a)
END DO
sum = h*(sum-0.5*(funct(a)+funct(b)))
PRINT *,sum
CONTAINS
END
And below is the Function funct(x)
DOUBLE PRECISION FUNCTION funct(x)
IMPLICIT NONE
DOUBLE PRECISION x
INTEGER K
Do k = 1,10
funct = x ** 2 * k
End Do
PRINT *, 'Value of funct is', funct
RETURN
END
I would like the 'Sum' in the Main Program to print 10 different sums over 10 different values of k in Function funct(x).
I have tried the above program but it just compiles the last value of Funct() instead of 10 different values in sum.
Array results require an explicit interface. You would also need to adjust funct and sum to actually be arrays using the dimension statement. Using an explicit interface requires Fortran 90+ (thanks for the hints by #francescalus and #VladimirF) and is quite tedious:
PROGRAM integration
INTERFACE funct
FUNCTION funct(x) result(r)
IMPLICIT NONE
DOUBLE PRECISION r
DIMENSION r( 10 )
DOUBLE PRECISION x
END FUNCTION
END INTERFACE
DOUBLE PRECISION a , b, sum, h
DIMENSION sum( 10)
INTEGER n, i
PARAMETER (a = 0, b = 10, n = 200)
h = (b-a)/n
sum = 0.0
DO i = 1, n
sum = sum+funct(i*h+a)
END DO
sum = h*(sum-0.5*(funct(a)+funct(b)))
PRINT *,sum
END
FUNCTION funct(x)
IMPLICIT NONE
DOUBLE PRECISION funct
DIMENSION funct( 10)
DOUBLE PRECISION x
INTEGER K
Do k = 1,10
funct(k) = x ** 2 * k
End Do
PRINT *, 'Value of funct is', funct
RETURN
END
If you can, you should switch to a more modern Standard such as Fortran 90+, and use modules. These provide interfaces automatically, which makes the code much simpler.
Alternatively, you could take the loop over k out of the function, and perform the sum element-wise. This would be valid FORTRAN 77:
PROGRAM integration
c ...
DIMENSION sum( 10)
c ...
INTEGER K
c ...
DO i = 1, n
Do k = 1,10
sum(k)= sum(k)+funct(i*h+a, k)
End Do
END DO
c ...
Notice that I pass k to the function. It needs to be adjusted accordingly:
DOUBLE PRECISION FUNCTION funct(x,k)
IMPLICIT NONE
DOUBLE PRECISION x
INTEGER K
funct = x ** 2 * k
PRINT *, 'Value of funct is', funct
RETURN
END
This version just returns a scalar and fills the array in the main program.
Apart from that I'm not sure it is wise to use a variable called sum. There is an intrinsic function with the same name. This could lead to some confusion...
I've been searching everywhere and found nothing. Is there any way of performing a weighted sample in Octave?
That is, if we have two vectors e and v, where sum(v) = 1, a way of sampling n elements from e with probabilies v.
You want to determine an index according to probability in vector 'v' then pick the corresponding index into 'e'. Thus, you need to use a Inverse transform sampling. A simple way to do it is for instance:
clear
close all
e = [10 20 30 40 50];
v = [0.1 0.2 0.5 0.1 0.1];
cdf = cumsum(v);
n = 1000;
E = [];
for i=1:n
r = rand;
idx = find(cdf>r);
E = [E e( idx(1) )];
end
hist(E)
I have the following code and I get the following error:
Compile error, variable not found (it is not able to find j)
Also, even though I provide MktVol as a vector of length 4, the message box returns N=0
Can you please help me fix my mistake.
Public Function EstimateAllParameters(params, MktStrike, MktVol, F, T, b)
Dim R As Double, a As Double, V As Double, N As Integer
Dim j as integer 'stops the compile error but the function returns #VALUE!
Dim ModelVol() As Double, sqdError() As Double
R = params(1)
V = params(2)
a = params(3)
N = MktVol.Length
MsgBox ("N= " & N)
For j = 1 To N
ModelVol(j) = Svol(a, b, R, V, F, MktStrike(j), T)
sqdError(j) = (ModelVol(j) - MktVol(j)) ^ 2
Next j
EstimateAllParameters = Sum(sqdError)
End Function
MktStrike has the following values in cells E5:E8
12
13
14
15
and MktVol has the following values in cells F5:F8
0.234
0.236
0.242
0.249
Obvious issue is J hasn't been Dim'd
I would change:
Dim R As Double, a As Double, V As Double, N As Integer
To
Dim R As Double, a As Double, V As Double, N As Integer, J as Integer