PID in scilab without using blocks diagrams - scilab

I'm trying to create a PID regulator on scilab without using xcos and blocks diagrams (because it sucks). On matlab there's a function that does this by itself but not on scilab.
Here's what I tried without success:
PID = Kp + Ki/z + (Kd*z/(TF(1,3)+1))
fb = PID /. TF(1,3)
[y13, x13]=csim(v,t, fb)
Where fb is the feedback applied over the transfer function and Kp, Ki and Kd are the gains.

Related

Optimization in R: Levenberg-Marquardt using nls.lm in minpack.lm: resetting `maxiter' to 1024

I am trying to learn how to work with nls.lm in the R library minpack.lm by using the Rosenbrock function to see if the algorithm converges to the global minimum at f(x,y) = (1,1). I do so both with and without the analytic Jacobian. In both instances, I get a warning telling me that the algorithm has decided to revert the maximum number of iterations specified in the call to nls.lm to 1024:
Warning messages:
1: In nls.lm(par = initpar, fn = objective_rosenbrock, jac = gradient_rosenbrock, :
resetting `maxiter' to 1024!
2: In nls.lm(par = initpar, fn = objective_rosenbrock, jac = gradient_rosenbrock, :
lmder: info = -1. Number of iterations has reached `maxiter' == 1024.
The algorithm never quite reaches (1,1) as a result given my initial guess of (-1.2, 1.0). I found the source code for the library on GitHub and the following lines of code are pertinent here:
https://github.com/cran/minpack.lm/blob/master/src/nls_lm.c
OS->maxiter = INTEGER_VALUE(getListElement(control, "maxiter"));
if(OS->maxiter > 1024) {
OS->maxiter = 1024;
warning("resetting `maxiter' to 1024!");
}
Is there any logic to why the maximum number of iterations is capped to 1024? Something with bits and 2^10? I would like to use the library for a different application, but this cap on iterations might prevent that. Any insight would be appreciated.
Git blame says that this code limiting the max iterations was introduced in version 1.1-0, in 2008. The NEWS file for the package only goes back as far as version 1.1-6. I can't find the code in any public repo other than the one you point to (which is only a CRAN mirror; it doesn't contain any comments/commit messages/etc. from developers that might give us clues.)
Other than contacting the maintainer I think it's going to be hard to figure out what the rationale is for this limit.
I do have some guesses though.
The only places that maxiter is actually used in the code are here and here - in R code, not Fortran or C code, so it seems extremely unlikely that we are dealing with something like a 10-bit unsigned integer type (which seems an unlikely choice in any case). I think the limitation is there because we also have a buffer defined for holding trace information here:
double rsstrace[1024];
which, as you can see, is hard-coded to a length of 1024. Presumably bad things would happen if we tried to stuff 1025 iterations'-worth of tracing information into this array ...
My suggestions:
change all instances of '1024' in the code to something larger and see what happens. There are only four:
$ find . -type f -exec grep -Hn 1024 {} \;
./src/nls_lm.c:141: if(OS->maxiter > 1024) {
./src/nls_lm.c:142: OS->maxiter = 1024;
./src/nls_lm.c:143: warning("resetting `maxiter' to 1024!");
./src/minpack_lm.h:20: double rsstrace[1024];
it would be best to #define MAXITER 2048 (or whatever) in src/minpack_lm.h and use that instead of the numerical value.
Contact the maintainer (maintainer("minpack.lm")) and ask them about this issue.

optimize matrix multiplication in for loop RcppArmadillo

The aim is to implement a fast version of the orthogonal projective non-negative matrix factorization (opnmf) in R. I am translating the matlab code available here.
I implemented a vanilla R version but it is much slower (about 5.5x slower) than the matlab implementation on my data (~ 225000 x 150) for 20 factor solution.
So I thought using c++ might speed up things but its speed is similar to R. I think this can be optimized but not sure how as I am a newbie to c++. Here is a thread that discusses a similar problem.
Here is my RcppArmadillo implementation.
// [[Rcpp::export]]
Rcpp::List arma_opnmf(const arma::mat & X, const arma::mat & W0, double tol=0.00001, int maxiter=10000, double eps=1e-16) {
arma::mat W = W0;
arma::mat Wold = W;
arma::mat XXW = X * (X.t()*W);
double diffW = 9999999999.9;
Rcout << "The value of maxiter : " << maxiter << "\n";
Rcout << "The value of tol : " << tol << "\n";
int i;
for (i = 0; i < maxiter; i++) {
XXW = X * (X.t()*W);
W = W % XXW / (W * (W.t() * XXW));
//W = W % (X*(X.t()*W)) / (W*((W.t()*X)*(X.t()*W)));
arma::uvec idx = find(W < eps);
W.elem(idx).fill(eps);
W = W / norm(W,2);
diffW = norm(Wold-W, "fro") / norm(Wold, "fro");
if(diffW < tol) {
break;
} else {
Wold = W;
}
if(i % 10 == 0) {
Rcpp::checkUserInterrupt();
}
}
return Rcpp::List::create(Rcpp::Named("W")=W,
Rcpp::Named("iter")=i,
Rcpp::Named("diffW")=diffW);
}
This suggested issue confirms that matlab is quite fast, so is there no hope when using R / c++?
The tests were made on Windows 10 and Ubuntu 16 with R version 4.0.0.
EDIT
After the interesting comments in the answer below. I am posting additional details. I ran tests on a Windows 10 machine with R 3.5.3 (as that's what Microsoft provides) and the comparison shows that RcppArmadillo with Microsoft's R is fastest.
R
user system elapsed
213.76 7.36 221.42
R with RcppArmadillo
user system elapsed
179.88 3.44 183.43
Microsoft's Open R
user system elapsed
167.33 9.96 45.94
Microsoft's Open with RcppArmadillo
user system elapsed
85.47 4.66 23.56
Are you aware that this code is "ultimately" executed by a pair of libraries called LAPACK and BLAS?
Are you aware that Matlab ships with a highly optimised one? Are you aware that on all systems that R runs on you can change which LAPACK/BLAS is being used.
The difference matters greatly. Just this morning a friend posted this tweet contrasting the same R code running on the same Windows computer but in two different R environments. The six-times faster one "simply" uses a parallel LAPACK/BLAS implementation.
Here, you haven't even told us which operating system you are on. You can get OpenBLAS (which uses parallelism) for all OSs that R runs on. You can even get the Intel MKL (which IIRC is what Matlab uses too) fairly easily on some OSs. For Ubuntu/Debian I published a script on GitHub that does it in one step.
Lastly, many years ago I "inherited" a fast program running in Matlab on a (then-large-ish) Windows computer. I rewrote the Matlab part (carefully and slowly, it's effort) in C++ using RcppArmadillo leading a few factors of improvement -- and because we could run that (now open source) code in parallel from R on the same computer another few factors. Together it was orders of magnitude turning a day-long simulation into something that ran a few minutes. So "yes, you can".
Edit: As you have access to Ubuntu, you can switch from basic LAPACK/BLAS to OpenBLAS via a single command, though I am no longer that familiar with Ubuntu 16.04 (as I run 20.04 myself).
Edit 2: Picking up the comparison from Josef's tweet, the Docker r-base container I also maintainer (as part of the Rocker Project) can use OpenBLAS. [1] So once we add it, e.g. via apt-get install libopenblas-dev the timing of a simple repeated matrix crossproduct moves from
root#0eb44b1fcc06:/# Rscript -e 'v <- matrix(1:1e6,1e3); system.time(replicate(10, crossprod(v,v)))'
user system elapsed
9.289 0.084 9.373
root#0eb44b1fcc06:/#
to
root#67bd334f53d4:/# Rscript -e 'v <- matrix(1:1e6,1e3); system.time(replicate(10, crossprod(v,v)))'
user system elapsed
2.259 2.370 0.447
root#67bd334f53d4:/#
which is substantial.

Pyaudio - test computer speakers?

I am trying to put together some code in Python 3.6 to help test the computer hardware that passes through my hands as an IT tech.
I'd like to have a script that plays a simple sine wave tone on the left speaker, then the right and then the both speakers together.
I have found a potentially helpful script over at Pyaudio How to get sound on only one speaker but some of the code to actually run it is missing - chiefly the code for making sin wave tones. I have looked around online and have tried reverse-engineering this back into the code on that page but the maths is a little high-level for me! Sorry.
Thanks,
Will
Update:
I think I have found a partial (albeit long-winded solution) with 'sounddevice' for python 3
#!/usr/bin/env python3
import argparse
import logging
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("filename", help="audio file to be played back")
parser.add_argument("-d", "--device", type=int, help="device ID")
args = parser.parse_args()
try:
import sounddevice as sd
import soundfile as sf
data, fs = sf.read(args.filename, dtype='float32')
sd.play(data, fs, device=args.device, blocking=True, mapping=[1])
status = sd.get_status()
if status:
logging.warning(str(status))
except BaseException as e:
# This avoids printing the traceback, especially if Ctrl-C is used.
raise SystemExit(str(e))
The main chunk of code is repeat twice more but with "mapping = [1]" changed to "mapping = [2]" to test the right speaker and finally with "mapping = [?]" removed in the final block to test both speakers.
I found this over at https://python-sounddevice.readthedocs.io/en/0.2.1/examples.html.
Of course, if anyone knows a quicker and graceful way of getting this done, please share!
You could generate the sine tone directly in Python instead of loading it from a file. I've written some tutorials about creating simple sine tones:
https://nbviewer.jupyter.org/github/mgeier/python-audio/blob/master/simple-signals.ipynb
http://nbviewer.jupyter.org/github/spatialaudio/communication-acoustics-exercises/blob/master/intro.ipynb
Those tutorials use NumPy, because it makes manipulating the audio buffers very easy. But you can of course also do it in pure Python, if you prefer.
Here's an example:
#!/usr/bin/env python3
import math
import sounddevice as sd
sd.default.device = None
sd.default.samplerate = samplerate = 48000
duration = 1.5
volume = 0.3
frequency = 440
# fade time in seconds:
fade_in = 0.01
fade_out = 0.3
buffer = memoryview(bytearray(int(duration * samplerate) * 4)).cast('f')
for i in range(len(buffer)):
buffer[i] = volume * math.cos(2 * math.pi * frequency * i / samplerate)
fade_in_samples = int(fade_in * samplerate)
for i in range(fade_in_samples):
buffer[i] *= i / fade_in_samples
fade_out_samples = int(fade_out * samplerate)
for i in range(fade_out_samples):
buffer[-(i + 1)] *= i / fade_out_samples
for mapping in ([1], [2], [1, 2]):
sd.play(buffer, blocking=True, mapping=mapping)
sd.sleep(500)
Note that this code is using 32-bit floating point numbers (each one using 4 bytes), that's why we reserve 4 times more bytes in our bytearray than the required number of samples.

Constraints(Time/area..) in Yosys and/or ABC

I am using the following basic script to synthesize simple adder design
# read design
read_verilog fulladder1.v
hierarchy -check
# high-level synthesis
proc; opt; fsm; opt; memory; opt
# low-level synthesis
techmap; opt
# map to target architecture
abc -g AND,XOR
# split larger signals
splitnets -ports; opt
show
With using
abc -g AND,XOR
command, ABC syhthesis the design just using AND,XOR and NOT (NOT is automatically added) gates.
My questions about this issue are;
1) Is there any way to force YOSYS and/or ABC tools to use just one universal gate (e.g. NAND) for whole design?
&
After using
abc -g AND,XOR
like command.
2) Is there a way to reduce or maximize the number of specified gates(e.g.XOR) by adding constraints (time/area/priority?...) to libraries
or
using special YOSYS and/or ABC commands?
Many thanks in advance...
The "cost" of built-in cell types is hardcoded in kernel/cost.h.
When mapping to a custom cell library you can specify the cost (area) in your liberty file. See examples/cmos/cmos_cells.lib for an example.
ABC needs a NOT gate in the cell library. But you can always map to a cell library of e.g. NAND and NOT and then use the techmap command to replace all instances of NOT with a NAND with both inputs driven by the same signal (or one input driven by constant 1, whatever you prefer).
Edit: Mapping NOT to NAND with techmap is easy. Simply create a file named not2nand.v with the following contents:
module \$_NOT_ (input A, output Y);
\$_NAND_ _TECHMAP_REPLACE_ (.A(A), .B(A), .Y(Y));
endmodule
Then you can map NOT gates to NANDs using techmap -map not2nand.v.

XC8 builds font tables from top ROM

I wrote a barebone progran template in XC8 (1.37) that I use to develop and test new GLCD functions for the 18F family. Programming is done via a PICkit3. Since I need to quicky reprogram several times the code it is really important that programming is faster as much as possible.
Tipically, the code size is around 2K and it takes less than 10 sec to program,
Everiything is fine until I must use a font table, defined as:
const char font8[] = {....
Now, with just $400 bytes added, the compiler place the table at the ROM's end and the programming of 64K memory takes more than 1 minute.
Is there any way to avoid this?
I tried to manually limit the memory range in the MPLABX options, but this is annoying and a little unsafe (sometimes part of code is truncated).
A while back I had to write some code for emissions testing, where I needed to copy data between extreme ends of RAM. To do that I needed to specify the exact memory addresses. You can also use the C extension __at() construct. http://ww1.microchip.com/downloads/en/DeviceDoc/50002053F.pdf#page=27
int scanMode __at(0x200);
const char keys[] __at(123) = { ’r’, ’s’, ’u’, ’d’};
int modify(int x) __at(0x1000) {
return x * 2 + 3;
}

Resources