Seed based randomization perl - perl

I have an array defined say #Array(1..31). Now I have a code where I randomly select a number for a certain number of times and store the results in another array. Example below :
$a1 = $Array[rand(#Array)];
push (#a2, $a1);
Now when I execute this script multiple times, I see that the new array contains very different patter everytime. But I do not want that, I want to generate a similar pattern everytime- where seed comes into picture.
Can someone please help me in how to incorporate seed to randomly select elements from array which can be predictable.?

You do not replace rand with srand: you use srand to initialize the seed for rand: so call srand(0) once and then use rand as you had been.
From your comment, you can use:
srand(0);
sub random {
my $random_select = $_[rand(#_)];
print " The random number selected is $random_select\n";
return $random_select;
}
or back to your original code just add the first line to it:
BEGIN { srand(0) }
$a1 = $Array[rand(#Array)];
push (#a2, $a1);

Related

How to convert string to variable name which will be passed into plot function

How I can convert a string to a variable which will be passed into plot function?
Time = [0,1,2,3];
A = sin(Time);
B = cos(Time);
c = 2*sin(Time);
lookup = {"A", "Freq(Hz)"; "B", "Pressure(bar)", "c", "time(ms),....};
for i=1:length(lookup)
plot(Time, lookup(i,1))
ylabel(lookup(i,2))
end
I want to plot Time vs A and Time vs B and Time vs C likewise I have 50 different variables to plot.
So I planned to create the lookup with string and planned to pass as variable to plot function using eval function call.
But in few places I read that using eval is not good option so kindly suggest the alternate method.
This will solve your immediate problem:
Replace
lookup = {"A", "Freq(Hz)"; "B", "Pressure(bar)", "c", "time(ms)", ...};
with
lookup = {A, "Freq(Hz)"; B, "Pressure(bar)", c, "time(ms)", ...};
Cell arrays are heterogeneous containers, each element can be an array of any time, independently from all other types.
With this change, the rest of your code should work as intended. You might want to add a figure command or a print command inside your loop, as each plot will overwrite the previous one. figure creates a new figure window to plot in, you'll have 50 windows (not so nice). print can save the plot to a file, which might be a better approach here. Don't try to combine the 50 data lines into a single plot, it'll be a mess!
On a larger scale, you might want to rethink your strategy with defining 50 different variables. Cell arrays and struct arrays are really good ways to go about this. For example, you can think of
data.A = sin(Time);
data.B = cos(Time);
data.c = 2*sin(Time);
or
data(1).values = sin(Time);
data(1).name = "A";
data(1).units = "Freq(Hz)";
data(2).values = cos(Time);
data(2).name = "B";
data(2).units = "Pressure(bar)";
data(3).values = 2*sin(Time);
data(3).name = "c";
data(3).units = "time(ms)";
Note that, in the first case, you can also index with data.("A"), which brings you pretty close to your original idea, except that you don't have 50 variables in your workspace, but one single data structure that is easier to deal with.
Here is a very detailed list of reasons why eval can be bad to use. That link also shows some alternatives, similar to what I summarized above.

How do I pass two parameters to a js object, including an array?

I am completely new to Max and am struggling to understand how to use arrays and Javascript parameters.
I have one working js object that outputs an array:
var inlets = 1;
var outlets = 1;
function getRandomChordProgression()
{
outlet(0, [1,4,5]);
return [1,4,5];
}
And then later I want to use that array in another js object, that takes an array and an integer:
var inlets = 2;
var outlets = 1;
function getCurrentChord(chords, barNumber)
{
var chord = chords[barNumber % 3];
outlet(0, chord);
return chord;
}
I tried the below, but the js gets undefined inputs.
The first thing to notice is that in Max Msp, in order to assign a list to a single symbol, you need to use the "tosymbol" object. Even if lists are effectively considered mono dimensional arrays in Max Msp, in order to be understood by javascript they first need to be converted. Once the list is converted into a symbol, we can join it with the integer coming from the number box, pack it with the getCurrentChord message and feed it into the getCurrentChord.js object.
You will see that by converting a list into a symbol every character in the array, including the spaces, is seen as part of the array. So using your example, an array composed by 3 integers will have 5 positions occupied, from 0 to 4. In order to make this work, inside the second .js script the modulo operator needs to be set to 5 in order to have a maximum remainder of 4. This means that by setting the number box to 1 or 3 you will have an empty output. So you need to decide how and if to parse the input or the output in order to obtain only the values desired.
var inlets = 2;
var outlets = 1;
function getCurrentChord(chords, barNumber)
{
var chord = chords[barNumber % 5];
outlet(0, chord);
}
Hope that helps!

Perl - least common multiple

This code should do the LCM from N numbers.
I tried to put prints wherever I can in order to see where is the mistake. and I think is in:
if($vec[0] == $vec[$n-1]){
$resultado = $vec[0];
last;
}
But I can not make it work.
Could you please help me?
I'm a rookie with Perl.
Hope you can solve this problem.
Also I tried to change the variables but it does not work. I mean
$u = 0 , $w = $n-1;
FULL CODE
To get the LCM, you can split the task into multiple subroutines:
is_prime # returns true if the value is prime
roots # returns the roots of a number (all prime numbers that make up a value. Ex: roots of 12 are: 2, 2, 3)
LCM # takes a list of values. Extract the roots while the number is not prime. Store in a hash like and increment everytime we see the root
So we'll have a hash like:
%sub_total = (
VALUE => TIMES_FOUND,
2 => 2,
3 => 1,
);
We have another hash which is the total. If the sub_total hash has a key that is used more often than in the total hash, we add it to the total.
Finally, we loop through the total hash and and find the product using the algorithm:
for (%total){
$prod *= $_ ** $total {$_};
}
Note
I'll shortly attach the code I wrote for getting the LCM. It's not with me now here.

Save a string, double and table Matlab

I have a loop which runs 100 times. In each iteration there is a string, double and a table assigned, and in the next iteration new values are assigned for them. What I want to do is to accumulate these values and after the loop finishes save the total result as result.mat using the matlab save function. I've tried putting them in cell-array but its not working so far, so if anyone could please advise how this can be done.
This is what I did:
results_cell=(100,3);
.
.
.
results_cell(i,1)=stringA;
results_cell(i,2)=TableA;
results_cell(i,3)=DoubleA;
But it gives this error Coversion to Cell from Table is not possible. So I've tried converting TableA to array of Doubles using table2array but I still get this Coversion to Cell from Double is not possible
I think using a structure would be a good way to store your data, since they are of different types and you can assign it meaningful field names for easy reference.
For example, let's call the structure Results. You can initialize it like so.
Results = struct('StringData',[],'TableData',[],'DoubleData',[])
Since you know its dimensions, you can even do this:
N = 100;
Results(N).StringData = [];
Results(N).TableData = [];
Results(N).DoubleData = [];
This automatically create a 1xN structure with 3 fields.
Then in your loop you can assign each field with its associated data like so:
for k = 1:N
Results(k).StringData = String(k);
Results(k).TableData = Table(k);
Results(k).DoubleData = Double(k);
end
where String(k), Table(k) and Double(k) are just generic names for your actual data.
When you're done with the loop you can access any type of data using a single index and the right field name.
In order to save a .mat file, use something like this:
save SomeFileName.mat Results
Which you can load into the workspace as you would with any .mat file:
Eg:
S = load('SomeFileName.mat')
R = S.Results
Hope that helps!

Hash value is not re-initialized when loop is terminated with 'last' keyword

Consider the following nested loops:
my %deleted_documents_names = map { $_ => 1 }
$self->{MANUAL}->get_deleted_documents();
while($sth->fetch){
.....
.....
.....
while(my ($key, $value) = each(%deleted_documents_names)){
{
if($document_name eq $key){
$del_status=1;
last;
}
}
if($del_status==1){next;}
.....
.....
.....
.....
}
Now, I take a sample case where three values (A,B,C) will be compared against two values (B,C).
First scan:
A compared to B
A compared to C
Second scan:
B compared to B
Loop is terminated.
Third scan:
C is compared with C.
In this case, C should be compared first with B, being first value, but this comparison is skipped, and it only scans from the next element after the one that was found equal. If I remove last termination condition and let the loop run for total number of scans, then it works all fine, but I need to find out why in this case, $key refers to the next compared value and not to the first value once loop is restarted after getting terminated with last keyword.
Any help will be appreciated.
Use
keys %deleted_documents_names ; # Reset the "each" iterator.
See keys.
But, why are you iterating over the hash? Why don't you just
if (exists $deleted_documents_names{$document_name}) {
each() is a function that returns key-value pairs from a hash until it reaches the end. It is not aware of the scope it was called in, and doesn't know anything about your while loop logic. See the documentation here.
It can be reset by calling keys %hash or values %hash.
Update: however, as Choroba points out, you don't really need this loop. Your loop and accompanying logic could be replaced by this:
next if (exists $deleted_documents_names{$document_name});
(Hashes are designed with a structure that allows a key to be quickly found. In fact, this structure is what gives them the name "hashes". So doing it this way will be much more efficient than looping through all elements and testing each one).