digital low pass filter output errors

Hi,

I am using a digital lowpass filter fed with random real numbers, and once in awhile the output of the filter will spike to zero for awhile, while the input numbers stay positive. In a 5minute period with a

1200Hz sample rate and 50:1 cutoff ratio (24Hz -3dB output) there are about 10 spikes to zero on the output. Any ideas what could cause the filter to spike like this? I've tried floats and doubles and both cause spikes.

cheers, Jamie

Here is the filter code:

public float lowPassFilter50to1(float next_input_value) { //ie. 1st order, 1kHz -3dB lowpass, 50kHz sampling filter

this.next_input_value = next_input_value; float gain = (float)16.89454484;

xv[0] = xv[1]; xv[1] = next_input_value / gain;

yv[0] = yv[1]; yv[1] = (xv[0] + xv[1]) + ((float)0.8816185924 * yv[0]);

next_output = yv[1];

return next_output;

}
Reply to
Jamie
Loading thread data ...

The most likely cause is that something is trampling over your arrays containing xv and yv. yv is incidentally redundant - you only need to preserve next_output. I would be inclined to test the program with random numbers of the form 17+(rand() % 1000) that way if it ever goes to zero you know that something has trampled over your working memory.

I suspect the problem lies in how the variables have been declared.

Regards, Martin Brown

Reply to
Martin Brown

I can only second that. The structure of the filter is not immediately springing to mind, but it seems odd from here.

And -- Java???

--
www.wescottdesign.com
Reply to
Tim Wescott

Hi,

I think you guys are right, I am using C# (managed code). I did a lot of breakpoint testing, and noticed some strange behaviour when copying one array to another. From experience I'd have to say the odds are still it is a bug on my end though :)

cheers, Jamie

Reply to
Jamie

Hi,

Well after lots of trial and error I found it is a threading error with two threads accessing the same data array. The filter seems to work ok now. I generated the filter from here:

formatting link

cheers, Jamie

Reply to
Jamie

Not a great advert for C#.

You might want to consider using at least a second order filter to get a half way decent attenuation of the high frequencies.

Regards, Martin Brown

Reply to
Martin Brown

And yet one more reason why it shouldn't be called "C-sharp" but rather "C-pound." ;-)

--
Rich Webb     Norfolk, VA
Reply to
Rich Webb

Thread collisions can happen in any language. It's kind of funny that a "C with training wheels" variant like C-pound or Java would fail to be thread-safe.

But if thread safety were easy, practical and convenient, then it would have been widespread since the '70's (And before you say it -- yes, there have been thread safe languages since then. But none have gained widespread acceptance, now have they?)

--
www.wescottdesign.com
Reply to
Tim Wescott

If the OP is going to access the same data array from multiple threads without using serialization or restricting yourself to atomic operations, he's going to have that sort of trouble. Check out mutexes.

Multithread programming is fun, and if you're adequately paranoid, it isn't so hard. It also presents some interesting design challenges, e.g. avoiding deadlocks and so on. There are other local fauna, e.g livelocks, where everything sort of keeps running, but nothing productive happens, usually due to interacting timeouts, and 'thundering herd' problems, when a whole bunch of threads are waiting on some condition, and they all get run at once when it occurs, flattening all the other processes.

Cheers

Phil Hobbs

Reply to
Phil Hobbs

It is indeed. Even stranger is that it would appear from this that it sets variables to zero before storing a new measurement in it.

Multiple thread reads from a variable don't do any harm, but writes or read modify write from more than one thread is always dangerous unless they are protected from each other by mutex or some other mechanism.

Sadly no and the wheel keeps getting reinvented. Some architectures now have indivisible read modify write instructions which do help a bit.

I don't think it is taught properly or to enough people.

Regards, Martin Brown

Reply to
Martin Brown

That sounds like a statement from the 0.99% group of the population.

99% of programmers believe they don't know how to do multi-threaded programming. Of the remaining 1%, 99% actually don't know how to do it :).

The problem with it is you cannot test the reliability - all the testing in the world can be done but the program may still fail in the field, for all but the most simplistic programs at least. MT programs must be correct by design, and there's no way in the world that can be considered "not so hard".

Clifford Heath.

Reply to
Clifford Heath

I guess you've never taken C# for a test drive :) I originally started with C/C++ years ago, which is superior to C# if you need low level hardware access, or performance critical code, however I have been amazed at the elegance of C# for working with complex data structures compared to C/C++.

cheers, Jamie

Reply to
Jamie

Hi,

I'm a noob with multithreading, but am currently working with it, so here is my preliminary idea for "bulletproof" multithreading that should be able to meet most of my future multithreading needs I think. Basically its an asynchronous data driven model where the threads run independently at their required frequency and are scheduled by a dedicated high frequency task manager thread. All data transfers between threads are locked, and for high performance locks that have more than one data consumer there can be a middle-man thread (running synchronous to the data producer thread) to mirror the data (ie. one copy per data consumer) to reduce thread lock delays. All data producing threads lock as short as possible section of code which copies the data into the shared memory.

cheers, Jamie

Reply to
Jamie

You can't test quality into any product whatsoever--hardware or software.

I've been writing multihreaded code since OS/2 2.0 came out, in early

1992, so I've been round the block a few times. I've also written a large clusterized electromagnetic simulator that runs with a heterogeneous collection of cluster hosts, Windows as well as Linux. Multithreaded code on one machine is a lot easier to get right than cluster code.

Besides the correctness issues you raise, cluster code also has a lot of subtleties connected with network latency, and there aren't a lot of good debugging and profiling tools available. I used the Rocks Linux distribution, which had a bunch of instrumentation included, e.g. Ganglia.

But you can get it right if you're willing to work at it, and your management has the patience. I was blessed with patient management for more than 20 years at IBM--I don't know that I would have been able to do some of that stuff otherwise.

Cheers

Phil Hobbs

--
Dr Philip C D Hobbs
Principal Consultant
ElectroOptical Innovations LLC
Optics, Electro-optics, Photonics, Analog Electronics

160 North State Road #203
Briarcliff Manor NY 10510
845-480-2058

hobbs at electrooptical dot net
http://electrooptical.net
Reply to
Phil Hobbs

No. But some of the BDD/TDD practices got a long way, if for no other reason than that they force you to come up with a definition of correctness before writing the code - and ensure that the code continues to meet that definition. It doesn't mean that it's the right definition, or that the code won't exhibit "Heisenbugs", but it helps. A lot. You hardware types discovered that a long way before the software world did :).

You're right, it can be done. But the number of applications that actually need it is much smaller than the number of people who don't know that :). It's a good thing some folk can get it right, or we wouldn't have any real operating systems of DBMS, and only poor web servers... but despite the relentless move to parallel hardware, there won't be a wholesale move to parallel software any time soon.

Clifford Heath.

Reply to
Clifford Heath

I'd put that number today that 90% admit to not knowing how to MT :(

And it is more serious now because most machines now are multicore and multithreaded (often used rather badly with race conditions present).

It is amazing just how long a few cycles of thread vulnerability in a large program can last in a pre-emptive multitasking environment without ever being hit. However, when it finally does happen the chaos that it can cause is serious since the data is no longer trustworthy.

It isn't quite so hard if you design for cooperative multitasking (with the emphasis on *design*) or have a paranoid defensive approach to save and restore everything on all context switches. It is much harder in pre-emptive multitasking when a task switch may occur at any time and Murphy's Law applies (eventually).

I recall one early compiler library on OS/2 with a failure to store FPU settings in one system thread that would sometimes randomise the rounding causing interesting intermittent drift of unmodified GUI numeric values (and as a result made complex numerical code give non standard answers when compared to the reference text based system).

And even when you have all the realtime MT aspects right you can still get fun and games in a memory constrained system with long term fragmentation of available memory into blocks that are "just too small".

Regards, Martin Brown

Reply to
Martin Brown

Clifford Heath expounded in news:4e377410$0$22473$ snipped-for-privacy@news.optusnet.com.au:

That is why "tasks" were built _into_ the language Ada, with standard (task) thread-safe operations. It is still possible to get it wrong but you have to work harder at it. It is far superior safety wise to Java, C# etc.

So for applications where life and limb are on the line (flight control etc.), the Ada subset SPARK (with added restrictions) are used so that they can actually _prove_ that the code is correct. All of this is regularly discussed over in comp.lang.ada.

Warren

Reply to
Warren

Multithreaded and parallel are not the same thing, though. For instance, you always want to write GUI programs with at least two threads, one for the UI and one for the crunching. It's very poor design to let the UI response time depend on how busy the back end is. Having the UI thread block on a slow network socket is especially irritating--Firefox and Thunderbird can both do that when you're trying to print, for instance.

There are also lots of cases where it makes a lot of sense to encapsulate threads in objects. I have a serial port class that I've used for instrument control for the last million years that does that--it has a near real-time thread inside it, so that comms supervision happens invisibly.

In firmware you often use an interrupt handler for that sort of stuff, but in user code you can't do that so easily--in a GUI program you can use a timer message, but it's a lot cleaner to use threads. You can partition the work much the way you'd do it with multiple small MCUs, but getting that right is a design issue too.

Being paranoid about serialization gets you most of the way there. Valgrind and mudflap are a help with the stuff that gets through the cracks.

Cheers

Phil Hobbs

--
Dr Philip C D Hobbs
Principal Consultant
ElectroOptical Innovations LLC
Optics, Electro-optics, Photonics, Analog Electronics

160 North State Road #203
Briarcliff Manor NY 10510
845-480-2058

hobbs at electrooptical dot net
http://electrooptical.net
Reply to
Phil Hobbs

Management still hasn't learned. We're lucky if there is a spec by the end of the program. If something doesn't work as product management decides it should (whenever they decide how is should work), guess who gets the blame?

*Some* hardware types have discovered that it's useful to decide what you're building before...

I sure hope not. Let them get in-line code working first.

Reply to
krw

I studied with a bloke who got his masters degree proving a program correct (a Pascal pretty-printer, for reference). He got his degree despite the proven program crashing when fed its own executable as input.

His program was fine, but the case statement implementation by the compiler didn't take account of sign extension in characters, so as soon as it got a -ve char, it indexed backwards off the start of the jump table.

You're right that some languages make it easy for ignorant folk to do harm, but ignorant folk always will anyhow. Good languages merely add succinctness and clarity, not really relevant safeguards, which are easy to create in any language.

Reply to
Clifford Heath

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.