Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -0,0 +1,89 @@
#include <atomic>
#include <chrono>
#include <cmath>
#include <iostream>
#include <mutex>
#include <thread>
using namespace std::chrono_literals;
class Integrator
{
public:
using clock_type = std::chrono::high_resolution_clock;
using dur_t = std::chrono::duration<double>;
using func_t = double(*)(double);
explicit Integrator(func_t f = nullptr);
~Integrator();
void input(func_t new_input);
double output() { return integrate(); }
private:
std::atomic_flag continue_;
std::mutex mutex;
std::thread worker;
func_t func;
double state = 0;
//Improves precision by reducing sin result error on large values
clock_type::time_point const beginning = clock_type::now();
clock_type::time_point t_prev = beginning;
void do_work();
double integrate();
};
Integrator::Integrator(func_t f) : func(f)
{
continue_.test_and_set();
worker = std::thread(&Integrator::do_work, this);
}
Integrator::~Integrator()
{
continue_.clear();
worker.join();
}
void Integrator::input(func_t new_input)
{
integrate();
std::lock_guard<std::mutex> lock(mutex);
func = new_input;
}
void Integrator::do_work()
{
while(continue_.test_and_set()) {
integrate();
std::this_thread::sleep_for(1ms);
}
}
double Integrator::integrate()
{
std::lock_guard<std::mutex> lock(mutex);
auto now = clock_type::now();
dur_t start = t_prev - beginning;
dur_t fin = now - beginning;
if(func)
state += (func(start.count()) + func(fin.count())) * (fin - start).count() / 2;
t_prev = now;
return state;
}
double sine(double time)
{
constexpr double PI = 3.1415926535897932;
return std::sin(2 * PI * 0.5 * time);
}
int main()
{
Integrator foo(sine);
std::this_thread::sleep_for(2s);
foo.input(nullptr);
std::this_thread::sleep_for(500ms);
std::cout << foo.output();
}

View file

@ -0,0 +1,24 @@
coclass 'activeobject'
require'dates'
create=:setinput NB. constructor
T=:3 :0
if. nc<'T0' do. T0=:tsrep 6!:0'' end.
0.001*(tsrep 6!:0'')-T0
)
F=:G=:0:
Zero=:0
setinput=:3 :0
zero=. getoutput''
'`F ignore'=: y,_:`''
G=: F f.d._1
Zero=: zero-G T ''
getoutput''
)
getoutput=:3 :0
Zero+G T''
)

View file

@ -0,0 +1,17 @@
cocurrent 'testrig'
delay=: 6!:3
object=: conew 'activeobject'
setinput__object 1&o.@o.`''
smoutput (T__object,getoutput__object) ''
delay 2
smoutput (T__object,getoutput__object) ''
setinput__object 0:`''
smoutput (T__object,getoutput__object) ''
delay 0.5
smoutput (T__object,getoutput__object) ''

View file

@ -0,0 +1,61 @@
Object subclass:#Integrator
instanceVariableNames:'tickRate input s thread'
classVariableNames:''
poolDictionaries:''
category:'Rosetta'
instance methods:
input:aFunctionOfT
input := aFunctionOfT.
startWithTickRate:r
"setup and start sampling"
tickRate := r.
s := 0.
thread := [ self integrateLoop ] fork.
stop
"stop and return the 'final' output"
thread terminate.
^ s
integrateLoop
"no need for any locks
- the assignment to s is atomic in Smallalk; its either done or not, when terminated, so who cares"
|tBegin tPrev tNow kPrev kNow deltaT delta|
tBegin := tPrev := Timestamp nowWithMilliseconds.
kPrev := input value:0.
[true] whileTrue:[
Delay waitForSeconds: tickRate.
tNow := Timestamp nowWithMilliseconds.
kNow := input value:(tNow millisecondDeltaFrom:tBegin) / 1000.
deltaT := (tNow millisecondDeltaFrom:tPrev) / 1000.
delta := (kPrev + kNow) * deltaT / 2.
s := s + delta.
tPrev := tNow. kPrev := kNow.
].
class methods:
example
#( 0.5 0.1 0.05 0.01 0.005 0.001 0.0005 ) do:[:sampleRate |
|i|
i := Integrator new.
i input:[:t | (2 * Float pi * 0.5 * t) sin].
i startWithTickRate:sampleRate.
Delay waitForSeconds:2.
i input:[:t | 0].
Delay waitForSeconds:0.5.
Transcript
show:'Sample rate: '; showCR:sampleRate;
showCR:(i stop).
].

View file

@ -0,0 +1 @@
Integrator example