In a continuous model, how do I save the minimum value of a variable during the simulation?
When a simulation has finished I want to display a variable T_min with a graphical annotation that shows me the lowest value of a temperature T during the simulation.
For example, if the simulated temperature T was a sine function, the desired result for the value of T_min would be:
In discrete code this would look something like this:
T_min := Modelica.Constants.inf "Start value";
if T < T_min then
T_min := T;
else
T_min := T_min;
end if;
... but I would like a continuous implementation to avoid sampling, high number of events etc.
I'm not sure if Renes solution is optimal. The solution generates many state events generated by the two if conditions. Embedded in the following model:
model globalMinimum2
Real T, T_min;
Boolean is_true;
initial equation
T_min = T;
equation
T =time/10*sin(time);
// if statement ensures that 'T_min' doesn't integrate downwards...
// ... whenever der(T) is negative;
if T < T_min then
der(T_min) = min(0, der(T));
is_true=true;
else
der(T_min) = 0;
is_true=false;
end if;
end globalMinimum2;
The simulation log is the following:
Integration started at T = 0 using integration method DASSL
(DAE multi-step solver (dassl/dasslrt of Petzold modified by Dynasim))
Integration terminated successfully at T = 50
WARNING: You have many state events. It might be due to chattering.
Enable logging of event in Simulation/Setup/Debug/Events during simulation
CPU-time for integration : 0.077 seconds
CPU-time for one GRID interval: 0.154 milli-seconds
Number of result points : 3801
Number of GRID points : 501
Number of (successful) steps : 2519
Number of F-evaluations : 4799
Number of H-evaluations : 18822
Number of Jacobian-evaluations: 2121
Number of (model) time events : 0
Number of (U) time events : 0
Number of state events : 1650
Number of step events : 0
Minimum integration stepsize : 1.44e-005
Maximum integration stepsize : 5.61
Maximum integration order : 3
Perhaps it is better to detect two events as given in the following example:
model unnamed_2
Real T;
Real hold;
Real T_min;
Boolean take_signal;
initial equation
hold=T;
equation
T = time/10*sin(time);
when (T < pre(hold)) then
take_signal = true;
hold = T;
elsewhen (der(T) >=0) then
take_signal = false;
hold = T;
end when;
if (take_signal) then
T_min = T;
else
T_min = hold;
end if;
end unnamed_2;
The simulation log shows that this solutions is more efficient:
Log-file of program ./dymosim
(generated: Tue May 24 14:13:38 2016)
dymosim started
... "dsin.txt" loading (dymosim input file)
... "unnamed_2.mat" creating (simulation result file)
Integration started at T = 0 using integration method DASSL
(DAE multi-step solver (dassl/dasslrt of Petzold modified by Dynasim))
Integration terminated successfully at T = 50
CPU-time for integration : 0.011 seconds
CPU-time for one GRID interval: 0.022 milli-seconds
Number of result points : 549
Number of GRID points : 501
Number of (successful) steps : 398
Number of F-evaluations : 771
Number of H-evaluations : 1238
Number of Jacobian-evaluations: 373
Number of (model) time events : 0
Number of (U) time events : 0
Number of state events : 32
Number of step events : 0
Minimum integration stepsize : 4.65e-006
Maximum integration stepsize : 3.14
Maximum integration order : 1
Calling terminal section
... "dsfinal.txt" creating (final states)
It seems I was able to finde an answer to my own question simply by looking at the figure above
The code is quite simple:
model globalMinimum
Modelica.SIunits.Temperature T, T_min;
initial equation
T_min = T;
equation
// if statement ensures that 'T_min' doesn't integrate downwards...
// ... whenever der(T) is negative;
der(T_min) = if T < T_min then min(0, der(T)) else 0;
end globalMinimum;
Related
I'm building a Redhawk 2.1.2 FEI device and encountering a tolerance check failure when I try to do an allocation through the IDE (haven't tried python interface or anything). The request is for 8 MHz and I get a return value of 7999999.93575246725231409 Hz which is waaaay within the 20% tolerance, but I still get this error:
2017-12-24 11:27:10 DEBUG FrontendTunerDevice:484 - allocateCapacity - SR requested: 8000000.000000 SR got: 7999999.935752
2017-12-24 11:27:10 INFO FrontendTunerDevice:490 - allocateCapacity(0): returned sr 7999999.935752 does not meet tolerance criteria of 20.000000 percent
The offending code from frontendInterfaces/libsrc/cpp/fe_tuner_device.cpp:
// check tolerances
if( (floatingPointCompare(frontend_tuner_allocation.sample_rate,0)!=0) &&
(floatingPointCompare(frontend_tuner_status[tuner_id].sample_rate,frontend_tuner_allocation.sample_rate)<0 ||
floatingPointCompare(frontend_tuner_status[tuner_id].sample_rate,frontend_tuner_allocation.sample_rate+frontend_tuner_allocation.sample_rate * frontend_tuner_allocation.sample_rate_tolerance/100.0)>0 ))
{
std::ostringstream eout;
eout<<std::fixed<<"allocateCapacity("<<int(tuner_id)<<"): returned sr "<<frontend_tuner_status[tuner_id].sample_rate<<" does not meet tolerance criteria of "<<frontend_tuner_allocation.sample_rate_tolerance<<" percent";
LOG_INFO(FrontendTunerDevice<TunerStatusStructType>, eout.str());
throw std::logic_error(eout.str().c_str());
}
And the function from frontendInterfaces/libsrc/cpp/fe_tuner_device.h:
inline double floatingPointCompare(double lhs, double rhs, size_t places = 1){
return round((lhs-rhs)*pow(10,places));
/*if(round((lhs-rhs)*(pow(10,places))) == 0)
return 0; // equal
if(lhs<rhs)
return -1; // lhs < rhs
return 1; // lhs > rhs*/
}
I actually copied into a non-Redhawk C++ program that I use to test the devices interfaces and the checks pass. I broke everything out to find the difference and noticed that in Redhawk the sample rate being returned from the Device (or at least printed to the screen) is slightly different than the one outside Redhawk - by like a tiny fraction of a Hz:
// in Redhawk using cout::precision(17)
Sample Rate: 7999999.93575246725231409
// outside Redhawk using cout::precision(17)
Sample Rate: 7999999.96948242187500000
I don't know why there's a difference in the actual sample rates returned but in the Redhawk version it's just enough to make the second part of the check fail:
floatingPointCompare(7999999.93575246725231409,8000000.00000000000000000)<0
1
Basically because:
double a = 7999999.93575246725231409 - 8000000.00000000000000000; // = -0.06424753274768591
double b = pow(10,1); // = 10.00000000000000000
double c = a*b; // = -0.6424753274
double d = round(c); // = -1.00000000000000000
So if a returned sample rate is less than the request by more than 0.049999 Hz then it will fail the allocation regardless of the tolerance %? Maybe I'm just missing something here.
The tolerance checks are specified to be the minimum amount plus a delta and not a variance (plus or minus) from the requested amount.
There should be a document somewhere that describes this in detail but I went to the FMRdsSimulator device's source.
// For FEI tolerance, it is not a +/- it's give me this or better.
float minAcceptableSampleRate = request.sample_rate;
float maxAcceptableSampleRate = (1 + request.sample_rate_tolerance/100.0) * request.sample_rate;
So that should explain why the allocation was failing.
In the University I'm given this canonical parallel programming problem from "Gregory R. Andrews-Foundations of Multithreaded .... programming": (though I have a newer and Russian edition of the book I found an old English variant and try to convey everything properly)
I was also given task to solve this problem but with m consequently moving cars possible using semaphores To solve that task I was told by the tutor to mimic Reader's behavior from readers-writers task
The One-Lane Bridge. Cars coming from the north and the south arrive at a one-
lane bridge. Cars heading in the same direction can cross the bridge at the same
time, but cars heading in opposite directions cannot.
Develop a solution to this problem. Model the cars as processes, and use a
monitor for synchronization. First specify the monitor invariant, then develop the
body of the monitor.Ensure fairness. (Have cars take tums)
I googled and found solution for analogous task (http://www.cs.cornell.edu/courses/cs4410/2008fa/homework/hw3_soln.pdf) but lecturer said most of it is useless and incorrect I ended up with the following solution:
monitor onelanebridge{
int nb=0,sb=0; //Invar:(nb==0 and sb<=1)or(sb=0 and nb<=1)
cond nbfreetogo,sbfreetogo; //conditional variables
procedure enter_n(){
if(sb!=0andnb==0) wait(nbfreetogo);
nb++;
}
procedure enter_s(){
if(nb!=0andsb==0) wait(sbfreetogo);
sb++;
}
procedure leave_n(){
nb--;
if(nb==0) signal(sbfreetogo);
}
procedure leave_s(){
sb--;
if(sb==0) signal(nbfreetogo);
}
}
I was asked the question "What ensures that no more than one car at a time can cross the bridge?".. And am not even sure whether it's even so... Please help me solve the task correctly. I must use only constructions from the above mentioned book...
Example of readers-writers problem solution from the book:
monitor RW_Controller {
int nr = 0, nw =0; //Invar: (nr == 0 or nw == 0) and nw <= 1
cond oktoread; # recieves signal, when nw == 0
cond oktowrite; # recieves signal, when nr == 0 и nw == 0
procedure request_read() {
while (nw > 0) wait(oktoread);
nr = nr + 1;
}
procedure release_read() {
nr = nr - 1;
if (nr == 0) signal(oktowrite);
# run one writer-process
}
procedure request_write() {
while (nr > 0 || nw > 0) wait(oktowrite);
nw = nw + 1 ;
}
procedure release_ write() {
nw = nw - 1;
signal(oktowrite); # run one writer-process and
signal_all(oktoread); # all reader-processes
}
}
Of course my solution is just a random try. Halp me please to solve the task properly
Note: A variable of "conditional variable" type according to the book is a "wait queue" which has these methods:
wait(cv)//wait at end of queue
wait(cv,rank)//wait in order of increasing value of rank
signal(cv)//awaken process at end of queue then continue
signal_all(cv)//awaken all processes at end of queue then continue
empty(cv) //true if wait queue is empty; false otherwise
minrank(cv) //value of rank of process at front of wait queue
And so I should solve the task probably using some of these
Your monitor onelanebridge is not far off the mark, but it has no notion of fairness. If there was a steady stream of northbound traffic, nothing would trigger a switch to southbound. You need to separate the count of waiting and ‘active’.
A simple fairness would be to alternate, so you could limit the ‘active’ counter at 1; and check whether to switch when it becomes zero.
To avoid inciting road rage, you might choose a limit based on the transit time of the single lane section.
You would now have vehicles waiting in enter_[ns] which had the right direction, but have to wait because of the limit, so your if (cond) wait needs to become while (more complex cond) wait.
Concurrent programming is not natural, but with practise can become ingrained. Try and think of the problem at hand rather than how can I employ these mechanisms.
I'm hoping someone with more VHDL experience can enlighten me! To summarise, I have an LCD entity and a Main entity which instantiates it. The LCD takes an 84-character wide string ("msg"), which seems to cause me huge problems as soon as I index it using a variable or signal. I have no idea what the reason for this is, however, since the string is displaying HEX values, and each clock cycle, I read a 16-bit value... I need to update 4 characters of the string for each nybble of this 16-bit value. This doesn't need to be done in a single clock cycle, since a new value is read after a large number of cycles... however, experimenting with incrementing a "t" variable, and only changing string values one "t" at a time makes no difference for whatever reason.
The error is: "Error (170048): Selected device has 26 RAM location(s) of type M4K" However, the current design needs more than 26 to successfully fit
Here is the compilation report with the problem:
Flow Status Flow Failed - Tue Aug 08 18:49:21 2017
Quartus II 64-Bit Version 13.0.1 Build 232 06/12/2013 SP 1 SJ Web Edition
Revision Name Revision1
Top-level Entity Name Main
Family Cyclone II
Device EP2C5T144C6
Timing Models Final
Total logic elements 6,626 / 4,608 ( 144 % )
Total combinational functions 6,190 / 4,608 ( 134 % )
Dedicated logic registers 1,632 / 4,608 ( 35 % )
Total registers 1632
Total pins 50 / 89 ( 56 % )
Total virtual pins 0
Total memory bits 124,032 / 119,808 ( 104 % )
Embedded Multiplier 9-bit elements 0 / 26 ( 0 % )
Total PLLs 1 / 2 ( 50 % )
The RAM summary table contains 57 rows, of "LCD:display|altsyncram:Mux####_rtl_0|altsyncram_####:auto_generated|ALTSYNCRAM"
Here is the LCD entity:
entity LCD is
generic(
delay_time : integer := 50000;
half_period : integer := 7
);
port(
clk : in std_logic;
SCE : out std_logic := '1';
DC : out std_logic := '1';
RES : out std_logic := '0';
SCLK : out std_logic := '1';
SDIN : out std_logic := '0';
op : in std_logic_vector(2 downto 0);
msg : in string(1 to 84);
jx : in integer range 0 to 255 := 0;
jy : in integer range 0 to 255 := 0;
cx : in integer range 0 to 255 := 0;
cy : in integer range 0 to 255 := 0
);
end entity;
The following code is what causes the problem, where a, b, c and d are variables which are incremented by 4 after each read:
msg(a) <= getHex(data(3 downto 0));
msg(b) <= getHex(data(7 downto 4));
msg(c) <= getHex(data(11 downto 8));
msg(d) <= getHex(data(15 downto 12));
Removing some of these lines causes the memory and logic element usages to both drop, but they still seem absurdly high, and I don't understand the cause.
Replacing a, b, c and d with integers, like 1, 2, 3 and 4 causes the problem to go away completely, with the logic elements at 22%, and RAM usage at 0%!
If anybody has any ideas at all, I'd be very grateful! I will post the full code below in case anybody needs it... but be warned, it's a bit messy, and I feel like the problem could be simple. Many thanks in advance!
Main.vhd
LCD.vhd
There are a few issues here.
The first is that HDL synthesis tools do an awful lot of optimization. What this basically means is if you don't properly connect up input and output parts to/from something it is likely (but not certain) to get eliminated by the optimizer.
The second is you have to be very careful with loops and functions. Basically loops will be unrolled and functions will be inlined, so a small ammount of code can generate an awful lot of logic.
The third is that under some cicumstances arrays will be translated to memory elements.
As pointed out in a comment this loop is the root cause of the large ammounts of memory usage.
for j in 0 to 83 loop
for i in 0 to 5 loop
pixels((j*6) + i) <= getByte(msg(j+1), i);
end loop;
end loop;
This has the potential to use a hell of a lot of memory resources. Each call to "getByte" requires a read port on (parts of) "ram" but blockrams only have two read ports. So "ram" gets duplicated to satisfy the need for more read ports. The inner loop is reading different parts of the same location so basically each iteration of the outer loop needs an independent read port on the ram. So that is about 40 copies of the ram. Reading the cyclone 2 datasheet each copy will require 2 m4k blocks
So why doesn't this happen when you use numbers instead of the variables a,b,c and d?
If the compiler can figure out something is a constant it can compute it at compile time. This would limit the number of calls to "pixels" that have to actually be translated to memory blocks rather that just having their result hardcoded. Still i'm surprised it's dropping to zero.
I notice your code doesn't actually have any inputs other than the clock and a "rx" input that doesn't actually seem to be being used for anything, so it is quite possible that the synthesizer may be figuring out a hell of a lot of stuff at build time. Often eliminating one bit of code can allow another bit to be eliminated until you have nothing left.
I am trying to get the dB level of incoming audio samples. On every video frame, I update the dB level and draw a bar representing a 0 - 100% value (0% being something arbitrary such as -20.0dB and 100% being 0dB.)
gdouble sum, rms;
sum = 0.0;
guint16 *data_16 = (guint16 *)amap.data;
for (gint i = 0; i < amap.size; i = i + 2)
{
gdouble sample = ((guint16)data_16[i]) / 32768.0;
sum += (sample * sample);
}
rms = sqrt(sum / (amap.size / 2));
dB = 10 * log10(rms);
This was adapted to C from a code sample, marked as the answer, from here. I am wondering what it is that I am missing from this very simple equation.
Answered: jacket was correct about the code loosing the sign, so everything ended up being positive. Also the code 10 * log(rms) is incorrect. It should be 20 * log(rms) as I am converting amplitude to decibels (as a measure of outputted power).
The level element is best for this task (as #ensonic already mentioned) its intended for exactly what you need..
So basically you add to your pipe element called "level", then enable the messages triggering.
Level element then emits messages which contains values of RMS Peak and Decay. RMS is what you need.
You can setup callback function connected to such message event:
audio_level = gst_element_factory_make ("level", "audiolevel");
g_object_set(audio_level, "message", TRUE, NULL);
...
g_signal_connect (bus, "message::element", G_CALLBACK (callback_function), this);
bus variable is of type GstBus.. I hope you know how to work with buses
Then in callback function check for the element name and get the RMS like is described here
There is also normalization algorithm with pow() function to convert to value between 0.0 -> 1.0 which you can use to convert to % as you stated in your question.
I'm trying to reproduce ALGOL 60 code written by Dijkstra in the paper titled "Cooperating sequential processes", the code is the first attempt to solve the mutex problem, here is the syntax:
begin integer turn; turn:= 1;
parbegin
process 1: begin Ll: if turn = 2 then goto Ll;
critical section 1;
turn:= 2;
remainder of cycle 1; goto L1
end;
process 2: begin L2: if turn = 1 then goto L2;
critical section 2;
turn:= 1;
remainder of cycle 2; goto L2
end
parend
end
So I tried to reproduce the above code in Promela and here is my code:
#define true 1
#define Aturn true
#define Bturn false
bool turn, status;
active proctype A()
{
L1: (turn == 1);
status = Aturn;
goto L1;
/* critical section */
turn = 1;
}
active proctype B()
{
L2: (turn == 2);
status = Bturn;
goto L2;
/* critical section */
turn = 2;
}
never{ /* ![]p */
if
:: (!status) -> skip
fi;
}
init
{ turn = 1;
run A(); run B();
}
What I'm trying to do is, verify that the fairness property will never hold because the label L1 is running infinitely.
The issue here is that my never claim block is not producing any error, the output I get simply says that my statement was never reached..
here is the actual output from iSpin
spin -a dekker.pml
gcc -DMEMLIM=1024 -O2 -DXUSAFE -DSAFETY -DNOCLAIM -w -o pan pan.c
./pan -m10000
Pid: 46025
(Spin Version 6.2.3 -- 24 October 2012)
+ Partial Order Reduction
Full statespace search for:
never claim - (not selected)
assertion violations +
cycle checks - (disabled by -DSAFETY)
invalid end states +
State-vector 44 byte, depth reached 8, errors: 0
11 states, stored
9 states, matched
20 transitions (= stored+matched)
0 atomic steps
hash conflicts: 0 (resolved)
Stats on memory usage (in Megabytes):
0.001 equivalent memory usage for states (stored*(State-vector + overhead))
0.291 actual memory usage for states
128.000 memory used for hash table (-w24)
0.534 memory used for DFS stack (-m10000)
128.730 total actual memory usage
unreached in proctype A
dekker.pml:13, state 4, "turn = 1"
dekker.pml:15, state 5, "-end-"
(2 of 5 states)
unreached in proctype B
dekker.pml:20, state 2, "status = 0"
dekker.pml:23, state 4, "turn = 2"
dekker.pml:24, state 5, "-end-"
(3 of 5 states)
unreached in claim never_0
dekker.pml:30, state 5, "-end-"
(1 of 5 states)
unreached in init
(0 of 4 states)
pan: elapsed time 0 seconds
No errors found -- did you verify all claims?
I've read all the documentation of spin on the never{..} block but couldn't find my answer (here is the link), also I've tried using ltl{..} blocks as well (link) but that just gave me syntax error, even though its explicitly mentioned in the documentation that it can be outside the init and proctypes, can someone help me correct this code please?
Thank you
You've redefined 'true' which can't possibly be good. I axed that redefinition and the never claim fails. But, the failure is immaterial to your goal - that initial state of 'status' is 'false' and thus the never claim exits, which is a failure.
Also, it is slightly bad form to assign 1 or 0 to a bool; assign true or false instead - or use bit. Why not follow the Dijkstra code more closely - use an 'int' or 'byte'. It is not as if performance will be an issue in this problem.
You don't need 'active' if you are going to call 'run' - just one or the other.
My translation of 'process 1' would be:
proctype A ()
{
L1: turn !=2 ->
/* critical section */
status = Aturn;
turn = 2
/* remainder of cycle 1 */
goto L1;
}
but I could be wrong on that.