user3585292
user3585292

Reputation: 57

Using a logarithmic (floating point) increment in a bash loop

I have this bash script that basically run a c simulation ./infosimul mu num

where the parameters increase linearly and they take just integers.

mu=1
num=0
while test $num -le 6;do
    mkdir $num
    cd $num
    while test $mu -le 200; do
            ../infosimul "$num" "$mu" 
            mu=$((mu+3))
        done
    mu=1
    cd ../
    num=$((num+1))
done

I would like that the mu parameter increase in a set like 0.01, 0.03, 0.09, 0.1, 0.3, 0.9, 1, 3, 9 ,10 or something that is not purely a sequence of integers.

Thanks!

Upvotes: 2

Views: 1720

Answers (3)

Mark Setchell
Mark Setchell

Reputation: 207455

Here's a fairly simple way of doing it:

#!/bin/bash
j=1
k=-2       # We are going to raise 10 to this power
num=1
while : 
do
   mu=$(echo "scale=2;$j*10^$k"|bc)
   echo ../infosimul "$num" "$mu" 
   [[ j -eq 1 ]] && j=2
   [[ j -eq 3 ]] && j=8
   [[ j -eq 9 ]] && j=0 && ((k++))
   ((j++))
   ((num++))
done

Output

../infosimul 1 .01
../infosimul 2 .03
../infosimul 3 .09
../infosimul 4 .10
../infosimul 5 .30
../infosimul 6 .90
../infosimul 7 1
../infosimul 8 3
../infosimul 9 9
../infosimul 10 10
../infosimul 11 30
../infosimul 12 90
../infosimul 13 100
../infosimul 14 300
../infosimul 15 900

Upvotes: 0

konsolebox
konsolebox

Reputation: 75478

And here's something that's just bash:

#!/bin/bash

mu=$1 num=$2

function is_le {
    local A1 A2 B1 B2

    if [[ $1 == *.* ]]; then
        A1=${1%%.*}
        A2=${1##*.}
    else
        A1=$1
        A2=0
    fi

    if [[ $2 == *.* ]]; then
        B1=${2%%.*}
        B2=${2##*.}
    else
        B1=$2
        B2=0
    fi

    (( L = ${#A2} > ${#B2} ? ${#A2} : ${#B2} ))

    A2=$A2'00000000000000000000'; A2=1${A2:0:L}
    B2=$B2'00000000000000000000'; B2=1${B2:0:L}

    (( A1 == B1 ? A2 <= B2 : A1 < B1 ))
}

for (( ; num <= 6; ++num )); do
    mkdir "$num" && pushd "$num" >/dev/null || continue
    while is_le "$mu" 200; do
        ../infosimul "$num" "$mu" 
        mu=$(( ${mu%.*} + 3 )).${mu#*.}
    done
    popd > /dev/null
done

Upvotes: 0

Aaron Digulla
Aaron Digulla

Reputation: 328594

Use this trick: Loop over the sequence 1 3 9.

Use bc to calculate mu:

mu=$(echo "scale=2; $val*$factor" | bc)

Start with factor=0.01 and multiply it by 10 after looping over the sequence above:

factor=$(echo "scale=2; $factor*10" | bc)

Upvotes: 3

Related Questions