How to make a value_of_things function f# - f#

Hey guys let's say I have a function that gets that day's rate of how much something costs, by the pound, and multiplies it by how many pounds a customer wants. i.e
let convert_func (crab_rate, lobster_rate);
//and then on a certain day it is
let (crab_rate, lobster_rate) = convert_fun(3.4, 6.8); // $3.8 a pound for crab, $6.8 a pound for lobster.
// 10 being how many pounds i want.
crab_rate10 ;
Then my out put would be whatever 38 since ($3.8 * 10lbs) = $38
I tried doing if statements so that when the user just wants to find out the total cost of one thing and not both. But I keep getting errors. I can't figure out how to store the rate values in the parameters and then calling the function.
This is what i tried
let crab_rate (pound, rate) = (float pound) * rate;
let lobster_rate (pound, rate) = (float pound) * rate;
let convert_func (crab_rate, lobster_rate)= function (first,second ) ->
if crab_rate then (float pound) * rate;
elif lobster_rate (float pound) * rate;
let (crab_rate, lobster_rate) = convert_fun(3.4, 6.8); // $3.8 a pound for crab, $6.8 a pound for lobster.
// 10 being how many pounds i want.
crab_rate10 ;

I think you should start by making a general function for converting a cost/weight and a weight into a cost. In F#, you can even use units of measure to help you:
[<Measure>] type USD // Unit of measure: US Dollars
[<Measure>] type lb // Unit of measure: lbs
let priceForWeight rate (weight : float<lb>) : float<USD> =
rate * weight
The nice thing about functional languages with curried arguments is that we can easily use partial function application. That means when we have a function that has two arguments, we can choose to supply just one argument and get back a new function from that one remaining argument to the result.
We can therefore define a further pair of functions that use this priceForWeight function.
let crabPriceForWeight weight = priceForWeight 3.8<USD/lb> weight
let lobsterPriceForWeight weight = priceForWeight 6.8<USD/lb> weight
Notice that we've used our original function to define two new functions with fixed rates.
We can then evaluate it like this:
let crabPrice10 = crabPriceForWeight 10.0<lb> // result 38.0<USD>
Of course, you can also define a function that returns both prices together as a tuple for a supplied weight:
let crabAndLobsterPriceForWeight weight =
crabPriceForWeight weight, lobsterPriceForWeight weight

Related

no method matching logpdf when sampling from uniform distribution

I am trying to use reinforcement learning in julia to teach a car that is constantly being accelerated backwards (but with a positive initial velocity) to apply brakes so that it gets as close to a target distance as possible before moving backwards.
To do this, I am making use of POMDPs.jl and crux.jl which has many solvers (I'm using DQN). I will list what I believe to be the relevant parts of the script first, and then more of it towards the end.
To define the MDP, I set the initial position, velocity, and force from the brakes as a uniform distribution over some values.
#with_kw struct SliderMDP <: MDP{Array{Float32}, Array{Float32}}
x0 = Distributions.Uniform(0., 80.)# Distribution to sample initial position
v0 = Distributions.Uniform(0., 25.) # Distribution to sample initial velocity
d0 = Distributions.Uniform(0., 2.) # Distribution to sample brake force
...
end
My state holds the values of (position, velocity, brake force), and the initial state is given as:
function POMDPs.initialstate(mdp::SliderMDP)
ImplicitDistribution((rng) -> Float32.([rand(rng, mdp.x0), rand(rng, mdp.v0), rand(rng, mdp.d0)]))
end
Then, I set up my DQN solver using crux.jl and called a function to solve for the policy
solver_dqn = DQN(π=Q_network(), S=s, N=30000)
policy_dqn = solve(solver_dqn, mdp)
calling solve() gives me the error MethodError: no method matching logpdf(::Distributions.Categorical{Float64, Vector{Float64}}, ::Nothing). I am quite sure that this comes from the initial state sampling, but I am not sure why or how to fix it. I have only been learning RL from various books and online lectures for a very short time, so any help regarding the error or my the model I set up (or anything else I'm oblivious to) would be appreciated.
More comprehensive code:
Packages:
using POMDPs
using POMDPModelTools
using POMDPPolicies
using POMDPSimulators
using Parameters
using Random
using Crux
using Flux
using Distributions
Rest of it:
#with_kw struct SliderMDP <: MDP{Array{Float32}, Array{Float32}}
x0 = Distributions.Uniform(0., 80.)# Distribution to sample initial position
v0 = Distributions.Uniform(0., 25.) # Distribution to sample initial velocity
d0 = Distributions.Uniform(0., 2.) # Distribution to sample brake force
m::Float64 = 1.
tension::Float64 = 3.
dmax::Float64 = 2.
target::Float64 = 80.
dt::Float64 = .05
γ::Float32 = 1.
actions::Vector{Float64} = [-.1, 0., .1]
end
function POMDPs.gen(env::SliderMDP, s, a, rng::AbstractRNG = Random.GLOBAL_RNG)
x, ẋ, d = s
if x >= env.target
a = .1
end
if d+a >= env.dmax || d+a <= 0
a = 0.
end
force = (d + env.tension) * -1
ẍ = force/env.m
# Simulation
x_ = x + env.dt * ẋ
ẋ_ = ẋ + env.dt * ẍ
d_ = d + a
sp = vcat(x_, ẋ_, d_)
reward = abs(env.target - x) * -1
return (sp=sp, r=reward)
end
function POMDPs.initialstate(mdp::SliderMDP)
ImplicitDistribution((rng) -> Float32.([rand(rng, mdp.x0), rand(rng, mdp.v0), rand(rng, mdp.d0)]))
end
POMDPs.isterminal(mdp::SliderMDP, s) = s[2] <= 0
POMDPs.discount(mdp::SliderMDP) = mdp.γ
mdp = SliderMDP();
s = state_space(mdp); # Using Crux.jl
function Q_network()
layer1 = Dense(3, 64, relu)
layer2 = Dense(64, 64, relu)
layer3 = Dense(64, length(3))
return DiscreteNetwork(Chain(layer1, layer2, layer3), [-.1, 0, .1])
end
solver_dqn = DQN(π=Q_network(), S=s, N=30000) # Using Crux.jl
policy_dqn = solve(solver_dqn, mdp) # Error comes here
Stacktrace:
policy_dqn
MethodError: no method matching logpdf(::Distributions.Categorical{Float64, Vector{Float64}}, ::Nothing)
Closest candidates are:
logpdf(::Distributions.DiscreteNonParametric, !Matched::Real) at C:\Users\name\.julia\packages\Distributions\Xrm9e\src\univariate\discrete\discretenonparametric.jl:106
logpdf(::Distributions.UnivariateDistribution{S} where S<:Distributions.ValueSupport, !Matched::AbstractArray) at deprecated.jl:70
logpdf(!Matched::POMDPPolicies.PlaybackPolicy, ::Any) at C:\Users\name\.julia\packages\POMDPPolicies\wMOK3\src\playback.jl:34
...
logpdf(::Crux.ObjectCategorical, ::Float32)#utils.jl:16
logpdf(::Crux.DistributionPolicy, ::Vector{Float64}, ::Float32)#policies.jl:305
var"#exploration#133"(::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(Crux.exploration), ::Crux.DistributionPolicy, ::Vector{Float64})#policies.jl:302
exploration#policies.jl:297[inlined]
action(::Crux.DistributionPolicy, ::Vector{Float64})#policies.jl:294
var"#exploration#136"(::Crux.DiscreteNetwork, ::Int64, ::typeof(Crux.exploration), ::Crux.MixedPolicy, ::Vector{Float64})#policies.jl:326
var"#step!#173"(::Bool, ::Int64, ::typeof(Crux.step!), ::Dict{Symbol, Array}, ::Int64, ::Crux.Sampler{Main.workspace#2.SliderMDP, Vector{Float32}, Crux.DiscreteNetwork, Crux.ContinuousSpace{Tuple{Int64}}, Crux.DiscreteSpace})#sampler.jl:55
var"#steps!#174"(::Int64, ::Bool, ::Int64, ::Bool, ::Bool, ::Bool, ::typeof(Crux.steps!), ::Crux.Sampler{Main.workspace#2.SliderMDP, Vector{Float32}, Crux.DiscreteNetwork, Crux.ContinuousSpace{Tuple{Int64}}, Crux.DiscreteSpace})#sampler.jl:108
var"#fillto!#177"(::Int64, ::Bool, ::typeof(Crux.fillto!), ::Crux.ExperienceBuffer{Array}, ::Crux.Sampler{Main.workspace#2.SliderMDP, Vector{Float32}, Crux.DiscreteNetwork, Crux.ContinuousSpace{Tuple{Int64}}, Crux.DiscreteSpace}, ::Int64)#sampler.jl:156
solve(::Crux.OffPolicySolver, ::Main.workspace#2.SliderMDP)#off_policy.jl:86
top-level scope#Local: 1[inlined]
Short answer:
Change your output vector to Float32 i.e. Float32[-.1, 0, .1].
Long answer:
Crux creates a Distribution over your network's output values, and at some point (policies.jl:298) samples a random value from it. It then converts this value to a Float32. Later (utils.jl:15) it does a findfirst to find the index of this value in the original output array (stored as objs within the distribution), but because the original array is still Float64, this fails and returns a nothing. Hence the error.
I believe this (converting the sampled value but not the objs array and/or not using approximate equality check i.e. findfirst(isapprox(x), d.objs)) to be a bug in the package, and would encourage you to raise this as an issue on Github.

Open trade in different symbol than the one the EA runs in MQL4

So I want to open trades depending on multiple criteria with my EA... Doesn't really matter TBH...
The problem is that EAs run in one window. So naturally, I'd like for an EA to open assess conditions and open all the trades within one chart. Everything's fine except...
Broker won't allow an EA that runs in a chart open a trade on a different one.... It is surely that. I eliminated any other case.
Inputs just for this example:
input double LotSize = 0.01;
input int Slippage = 10;
input double StopLoss = 1000.0;
input double TakeProfit = 1000.0;
input const string SymbolA = "EURUSD";
input const string SymbolB = "GBPUSD";
The commands I use (I have them copy-pasted from another EA that works just fine so I am certain they work as well, plus I used extreme TP/SL to surpass any restrictions that brokers might have) :
TicketA = OrderSend(SymbolA,OP_SELL,LotSize,Bid,Slippage,Bid+StopLoss*Point,Bid-TakeProfit*Point,EAComment,OrderTicket(),0,clrDarkRed);
Sleep(1000);
TicketB = OrderSend(SymbolB,OP_BUY,LotSize,Ask,Slippage,Ask-StopLoss*Point,Ask+TakeProfit*Point,EAComment,OrderTicket(),0,clrDarkBlue);
Error (EURUSD one opens normal as the EA runs in the EURUSD chart):
2020.12.18 01:01:45.318 '22644076': order buy market 0.01 GBPUSD sl: 1.21670 tp: 1.23670
2020.12.18 01:01:45.528 '22644076': order buy 0.01 GBPUSD opening at market sl: 1.21670 tp: 1.23670 failed [Invalid S/L or T/P]
Any suggestion how can I fix/bypass this?
Thanks in advance!
Obviously, you have to set a different open price, stop-loss, and take-profit for another symbol. So, if you are calling for the current (SymbolA) this sell:
TicketA = OrderSend(SymbolA,OP_SELL,LotSize,Bid,Slippage,Bid+StopLoss*Point,Bid-TakeProfit*Point,EAComment,OrderTicket(),0,clrDarkRed);
Then for a SymbolB (a different symbol), you have to first construct the price values:
double Ask_B = SymbolInfoDouble(SymbolB, SYMBOL_ASK);
double Point_B = SymbolInfoDouble(SymbolB, SYMBOL_POINT);
int Digits_B = SymbolInfoInteger(SymbolB, SYMBOL_DIGITS);
double SL_B = NormalizeDouble(Ask_B - StopLoss * Point_B, Digits_B);
double TP_B = NormalizeDouble(Ask_B + StopLoss * Point_B, Digits_B);
And only then call something like this:
TicketB = OrderSend(SymbolB,OP_BUY,LotSize,Ask_B,Slippage,SL_B,TP_B,EAComment,OrderTicket(),0,clrDarkBlue);

Approach for Linearizing Nonlinear System around Decision Variables (x, u) from MathematicalProgram at each discrete point in time

This is a follow up question on the same system from the following post (for additional context). I describe a nonlinear system as a LeafSystem_[T] (using templates) with two input ports and one output port. Then, I essentially would like to perform direct transcription using MathematicalProgram with an additional cost function that is dependent on the linearized dynamics at each time step (and hence linearized around the decision variables). I use two input ports as it seemed the most straightforward way for obtaining the linearized dynamics of the form from this paper on DIRTREL (if I can take the Jacobian with respect to input ports)
δxi+1 ≈ Aiδx + Biδu + Giw
where i is the timestep, x is the state, the first input port can encapsulate u, and the second input port can model w which may be disturbance, uncertainty, etc.
My main question is what would be the most suitable set of methods to obtain the linearized dynamics around the decision variables at each time step using automatic differentation? I was recommended trying automatic differentiation after attempting a symbolic approach in the previous post, but am not familiar with the setup for doing so. I have experimented with
using primitives.Linearize() (calling it twice, once for each input port) which feels rather clunky and I am not sure whether it is possible to pass in decision variables into context
perhaps converting my system into a multibody and making use of multibody.tree.JacobianWrtVariable()
or formatting my system dynamics so that I can pass them in as the function argument for forwarddiff.jacobian
but have met limited success.
The easiest way to get Ai, Bi is to instantiate your system with AutoDiffXd, namely LeafSystem<AutoDiffXd>. The following code will give you Ai, Bi
MyLeafSystem<AutoDiffXd> my_system;
Eigen::VectorXd x_val = ...
Eigen::VectorXd u_val = ...
Eigen::VectorXd w_val = ...
// xuw_val concantenate x_val, u_val and w_val
Eigen::VectorXd xuw_val(x_val.rows() + u_val.rows() + w_val.rows());
xuw_val.head(x_val.rows()) = x_val;
xuw_val.segment(x_val.rows(), u_val.rows()) = u_val;
xuw_val.segment(w_val.rows()) = w_val;
// xuw_autodiff stores xuw_val in its value(), and an identity matrix in its gradient()
AutoDiffVecXd xuw_autodiff = math::initializeAutoDiff(xuw_val);
AutoDiffVecXd x_autodiff = xuw_autodiff.head(x_val.rows());
AutoDiffVecXd u_autodiff = xuw_autodiff.segment(x_val.rows(), u_val.rows());
AutoDiffVecXd w_autodiff = xuw_autodiff.tail(u_val.rows());
// I suppose you have a function x[n+1] = dynamics(system, x[n], u[n], w[n]). This dynamics function could be a wrapper of CalcUnrestrictedUpdate function.
AutoDiffVecXd x_next_autodiff = dynamics(my_system, x_autodiff, u_autodiff, w_autodiff);
Eigen::MatrixXd x_next_gradient = math::autoDiffToGradientMatrix(x_next_autodiff);
Eigen::MatrixXd Ai = x_next_gradient.block(0, 0, x_val.rows(), x_val.rows());
Eigen::MatrixXd Bi = x_next_gradient.block(0, x_val.rows(), x_val.rows(), u_val.rows());
Eigen::MatrixXd Gi = x_next_gradient.block(0, x_val.rows() + u_val.rows(), x_val.rows(), w_val.rows());
So you get the value of Ai, Bi, Gi in the end.
If you need to write a cost function, you will need to create a subclass of solvers::Cost. Inside the Eval function of this derived class, you will implement your code to first compute Ai, Bi, Gi, and then integrate the Riccati equation.
But I think since your cost function depends on Ai, Bi, Gi, the gradient of your cost function will depend on the gradient of Ai, Bi, Gi. Currently we don't provide the function to compute the second order gradient of the dynamics.
How complicated is your dynamical system? Is it possible to write down the dynamics by hand? If so, there are some shortcuts we can do to generate the second order gradient of your dynamics.
#sherm or other Drake dynamics folks, it would be great to get your opinion on how to get the second order gradient (assuming Phil could confirm he does need the second order gradient.)
Sorry for my belated reply.
Since your dynamics can be written by hand, then I would suggest to create a templated function to compute Ai, Bi, Gi as
template <typename T>
void ComputeLinearizedDynamics(
const LeafSystem<T>& my_system,
const Eigen::Ref<const drake::VectorX<T>>& x,
const Eigen::Ref<const drake::VectorX<T>>& u,
drake::MatrixX<T>* Ai,
drake::MatrixX<T>* Bi,
drake::MatrixX<T>* Gi) const;
You will need to write down the matrix Ai, Bi, Gi by hand within this function. Then when you instantiate your LeafSystem with T=AutoDiffXd, this function will compute Ai, Bi, Gi with its gradient, given the state x, input u and disturbance w.
Then in the cost function, you could consider to create a sub-class of Cost class as
class MyCost {
public:
MyCost(const LeafSystem<AutoDiffXd>& my_system) : my_system_{&my_system} {}
protected:
void DoEval(const Eigen::Ref<const Eigen::VectorXd>& x_input, Eigen::VectorXd* y) const {
// The computation here is inefficient, as we need to cast
// x_input to Eigen vector of AutoDiffXd, and then call
// DoEval with AutoDiffXd version, and then convert the
// result back to double. But it is easy to implement.
const AutoDiffVecXd x_autodiff = math::initializeAutoDiff(x_input);
AutoDiffVecXd y_autodiff;
this->DoEval(x_autodiff, &y_autodiff);
*y = math::autodiffToValueMatrix(y_autodiff);
}
void DoEval(const Eigen::Ref<const drake::AutoDiffVecXd>& x_input, drake::AutoDiffVecXd* y) const {
// x_input here contains all the state and control sequence The authors need to first partition x_input into x, u
drake::VectorX<T> x_all = x_input.head(num_x_ * nT_);
drake::VectorX<T> u_all = x_input.tail(num_u_ * nT_);
y->resize(1);
y(0) = 0;
// I assume S_final_ is stored in this class.
Eigen::MatrixXd S = S_final_;
for (int i = nT-1; i >= 0; --i) {
drake::MatrixX<AutoDiffXd> Ai, Bi, Gi;
ComputeLinearizedDynamics(
*my_system_,
x_all.segment(num_x_ * i, num_x_),
u_all.segment(num_u_ * i, num_u_),
&Ai, &B_i, &Gi);
S = Ai.T*S + S*Ai + ... // This is the Riccati equation.
// Now compute your cost with this S
...
}
}
void DoEval(const Eigen::Ref<const VectorX<symbolic::Variable>& x, VectorX<symbolic::Expression>* y) const {
// You don't need the symbolic version of the cost in nonlinear optimization.
throw std::runtime_error("Not implemented yet");
}
private:
LeafSystem<AutoDiffXd>* my_system_;
};
The DoEval function with autodiff version will compute the gradient of the cost for you automatically. Then you will need to call AddCost function in MathematicalProgram to add this cost together with all of x, u as the associated variable of this cost.

Functional Programming Exercise

As a functional programming exercise, I thought I'd write a little program to rank crafting recipes in an mmo by profitability.
In an OO language, I'd make strategy objects for each recipe, with Cost(), ExpectedRevenue(), and Volume() as members. I'd then put all the objects in a list and sort them by a profitability/time function.
Trying to accomplish the same result in F#, but I'm not certain how to go about it. I have some disjointed cost functions, for example:
let cPM (ss,marble) = (15.0 * ss + 10.0 * marble + 0.031) / 5.0
let cTRef (tear,clay) = (tear + 10.0 * clay + 0.031) / 5.0
and then revenue and volume definitions like:
let rPM = 1.05
let vPM = 50
but I'm not sure what to do now. Make a list of tuples that look like
(name: string, cost:double, revenue:double, volume:int)
and then sort the list? It feels like I'm missing something- still thinking in OO, not to mention adding new recipes in this fashion will be rather awkward.
Has anyone any tips to use the functional concepts in a better way? It seemed like this type of calculation problem would be a good fit for the functional style.
Much appreciated.
This is a fairly complex question with multiple possible answers. Also, it is quite hard to guess anything about your domain (I don't know what game you're playing :-)), so I'll try to make something up, based on the example.
The basic functional approach would be to model the different recipes using a discriminated union.
type Recipe =
| FancySword of gold:float * steel:float // Sword can be created from gold & steel
| MagicalStone of frogLegs:float // Magical stone requires some number of frog legs
Also, we need to know the prices of things in the game:
type Prices = { Gold : float; Steel : float; FrogLegs : float }
Now you can write functions to calculate the cost and expected revenue of the recipes:
let cost prices recipe =
match recipe with
| FancySword(g, s) ->
// To create a sword, we need 2 pieces of gold and 15 pieces of steel
2.0 * g * prices.Gold + s * 15.0 * prices.Steel
| MagicalStone(l) -> l * prices.FrogLeg
This takes the record with all the prices and it takes a recipe that you want to evaluate.
The example should give you some idea - starting with a discriminated union to model the problem domain (different recipes) and then writing a function with pattern matching in it is usually a good way to get started - but it's hard to say more with the limited information in your question.
In functional languages you can do anything only with functions. Here you can define common profitability function and sort your recipes with it and List.sortBy:
// recipe type with constants for Revenue, Volume and (ss,marble)
type recipe = {r: float; v: float; smth: float * float}
// list of recipes
let recipes = [
{r = 1.08; v = 47.0; smth = (28.0, 97.0)};
{r = 1.05; v = 50.0; smth = (34.0, 56.0)} ]
// cost function
let cPM (ss,marble) = (15.0 * ss + 10.0 * marble + 0.031) / 5.0
// profitability function with custom coefficients
let profitability recipe = recipe.r * 2.0 + recipe.v * 3.0 + cPM recipe.smth
// sort recipes by profitability
let sortedRecipes =
List.sortBy profitability recipes
// note: it's reordered now
printfn "%A" sortedRecipes
The accepted answer is a little lacking in type safety, I think - you already stated that a FancySword is made of gold and steel, so you shouldn't have to remember to correctly pair the gold quantity with the gold price! The type system ought to check that for you, and prevent an accidental g * prices.Steel mistake.
If the set of possible resource types is fixed, then this is a nice use-case for Units of Measure.
[<Measure>] type Gold
[<Measure>] type Steel
[<Measure>] type FrogLegs
[<Measure>] type GameMoney
type Recipe = {
goldQty : float<Gold>
steelQty : float<Steel>
frogLegsQty : int<FrogLegs>
}
type Prices = {
goldPrice : float<GameMoney/Gold>
steelPrice : float<GameMoney/Steel>
frogLegsPrice : float<GameMoney/FrogLegs>
}
let recipeCost prices recipe =
prices.goldPrice * recipe.goldQty +
prices.steelPrice * recipe.steelQty +
// frog legs must be converted to float while preserving UoM
prices.frogLegsPrice * (recipe.frogLegsQty |> float |> LanguagePrimitives.FloatWithMeasure)
let currentPrices = {goldPrice = 100.0<GameMoney/Gold>; steelPrice = 50.0<GameMoney/Steel>; frogLegsPrice = 2.5<GameMoney/FrogLegs> }
let currentCost = recipeCost currentPrices
let fancySwordRecipe = {goldQty = 25.4<Gold>; steelQty = 76.4<Steel>; frogLegsQty = 0<FrogLegs>}
let fancySwordCost = currentCost fancySwordRecipe
The compiler will now ensure that all calculations check out. In the recipeCost function, for example, it ensures that the total is a float<GameMoney>.
Since you mentioned volume, I think you can see how you can replicate the same pattern to write type-safe functions that will calculate total recipe volumes as a value of type int<InventoryVolume>.

Real FFT output

I have implemented fft into at32ucb series ucontroller using kiss fft library and currently struggling with the output of the fft.
My intention is to analyse sound coming from piezo speaker.
Currently, the frequency of the sounder is 420Hz which I successfully got from the fft output (cross checked with an oscilloscope). However, the output frequency is just half of expected if I put function generator waveform into the system.
I suspect its the frequency bin calculation formula which I got wrong; currently using, fft_peak_magnitude_index*sampling frequency / fft_size.
My input is real and doing real fft. (output samples = N/2)
And also doing iir filtering and windowing before fft.
Any suggestion would be a great help!
// IIR filter calculation, n = 256 fft points
for (ctr=0; ctr<n; ctr++)
{
// filter calculation
y[ctr] = num_coef[0]*x[ctr];
y[ctr] += (num_coef[1]*x[ctr-1]) - (den_coef[1]*y[ctr-1]);
y[ctr] += (num_coef[2]*x[ctr-2]) - (den_coef[2]*y[ctr-2]);
y1[ctr] = y[ctr] - 510; //eliminate dc offset
// hamming window
hamming[ctr] = (0.54-((0.46) * cos(2*M_PI*ctr/n)));
window[ctr] = hamming[ctr]*y1[ctr];
fft_input[ctr].r = window[ctr];
fft_input[ctr].i = 0;
fft_output[ctr].r = 0;
fft_output[ctr].i = 0;
}
kiss_fftr_cfg fftConfig = kiss_fftr_alloc(n,0,NULL,NULL);
kiss_fftr(fftConfig, (kiss_fft_scalar * )fft_input, fft_output);
peak = 0;
freq_bin = 0;
for (ctr=0; ctr<n1; ctr++)
{
fft_mag[ctr] = 10*(sqrt((fft_output[ctr].r * fft_output[ctr].r) + (fft_output[ctr].i * fft_output[ctr].i)))/(0.5*n);
if(fft_mag[ctr] > peak)
{
peak = fft_mag[ctr];
freq_bin = ctr;
}
frequency = (freq_bin*(10989/n)); // 10989 is the sampling freq
//************************************
//Usart write
char filtResult[10];
//sprintf(filtResult, "%04d %04d %04d\n", (int)peak, (int)freq_bin, (int)frequency);
sprintf(filtResult, "%04d %04d %04d\n", (int)x[ctr], (int)fft_mag[ctr], (int)frequency);
char c;
char *ptr = &filtResult[0];
do
{
c = *ptr;
ptr++;
usart_bw_write_char(&AVR32_USART2, (int)c);
// sendByte(c);
} while (c != '\n');
}
The main problem is likely to be how you declared fft_input.
Based on your previous question, you are allocating fft_input as an array of kiss_fft_cpx. The function kiss_fftr on the other hand expect an array of scalar. By casting the input array into a kiss_fft_scalar with:
kiss_fftr(fftConfig, (kiss_fft_scalar * )fft_input, fft_output);
KissFFT essentially sees an array of real-valued data which contains zeros every second sample (what you filled in as imaginary parts). This is effectively an upsampled version (although without interpolation) of your original signal, i.e. a signal with effectively twice the sampling rate (which is not accounted for in your freq_bin to frequency conversion). To fix this, I suggest you pack your data into a kiss_fft_scalar array:
kiss_fft_scalar fft_input[n];
...
for (ctr=0; ctr<n; ctr++)
{
...
fft_input[ctr] = window[ctr];
...
}
kiss_fftr_cfg fftConfig = kiss_fftr_alloc(n,0,NULL,NULL);
kiss_fftr(fftConfig, fft_input, fft_output);
Note also that while looking for the peak magnitude, you probably are only interested in the final largest peak, instead of the running maximum. As such, you could limit the loop to only computing the peak (using freq_bin instead of ctr as an array index in the following sprintf statements if needed):
for (ctr=0; ctr<n1; ctr++)
{
fft_mag[ctr] = 10*(sqrt((fft_output[ctr].r * fft_output[ctr].r) + (fft_output[ctr].i * fft_output[ctr].i)))/(0.5*n);
if(fft_mag[ctr] > peak)
{
peak = fft_mag[ctr];
freq_bin = ctr;
}
} // close the loop here before computing "frequency"
Finally, when computing the frequency associated with the bin with the largest magnitude, you need the ensure the computation is done using floating point arithmetic. If as I suspect n is an integer, your formula would be performing the 10989/n factor using integer arithmetic resulting in truncation. This can be simply remedied with:
frequency = (freq_bin*(10989.0/n)); // 10989 is the sampling freq

Resources