litte faster external math

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
einstein1969
Expert
Posts: 961
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

litte faster external math

#1 Post by einstein1969 » 08 Dec 2015 11:08

Hi,

I have seen in this forum an architecture for calculate math using cscript with a call for each expression.

This is a little slow because is necessary instantiate every time the cscript.

example:

Code: Select all

:calculate expr retvar
  for /F %%i in ('echo "%~1" ^| Cscript //nologo FPU-Module.js') do set "%2=%%i"
  set "%2=!%2:,=.!"
goto :eof


FPU-module.js:

Code: Select all

WScript.Stdout.WriteLine(eval(WScript.Stdin.ReadLine().replace(/\x22/g,"")));


I have seen an architetture che start two process that using an interprocess communication for eliminating this limit.

This processes use the captured standard input output for communicate (incapsulate a process)

But it's complicated for my scope.

There is a better (simpler) mechanism for having a faster execution?

I think at buffering the call (a queue or a multi expressions file) plus a simple "comparison predicates" (if a<>=b then 1 else 0) or any other ideas...

This is a code that i need porting. Use bash (run on Linux and Mac) and BC math.

Code: Select all

#!/bin/bash

# versione 0.3.2 by Francesco Poscetti aka einstein1969

# Controllo i parametri in ingresso

if [ $# -lt 4 ]; then
    echo "Uso: $0 file1 file2 filerisultato scarto"
    echo "  scarto e' in gradi"
    exit 1
fi
if [ ! -f "$1" ]; then
    echo "Il file $1 non esiste."
    exit 1
fi
if [ ! -f "$2" ]; then
    echo "Il file $2 non esiste."
    exit 1
fi
if [ -f "$3" ]; then
    echo "Il file $3 esiste. Scegliere un altro nome o rinominare il file"
    exit 1
fi

echo "Controllo $1 con $2. Risultato in $3. Scarto $4" | tee $3

# in caso i files abbiano dei ^M eseguire da vi : 1,$s/Ctrl-vCtrlM/Ctrl-vINVIO/g in ogni caso lo
# script prova a toglierli in automatico.

# controllo il numero di record non vuoti dei files (righe vuote o contenenti spazi e/o tab sono ignorate)
# provo a togliere eventuali ^M ( sed -e "s/\r/\n/g" ). Si puo' usare anche  tr '\r' '\n'

righe1=`cat $1 | sed -e "s/\r/\n/g" -e "/^[ \t]*$/d" | wc -l`
righe2=`cat $2 | sed -e "s/\r/\n/g" -e "/^[ \t]*$/d" | wc -l`
totrighe=$(echo "scale=0; $righe1*$righe2" | bc)

echo "Totale righe non vuote: in $1 sono $righe1, in $2 sono $righe2. Confronti: $totrighe" | tee -a $3
echo -e "N.Ord.\tC.Cat1\tC.Cat2\tDist." >> $3
# confronto i files

rimaste=$totrighe
trovati=0
trovatif1=0

# file di log di bc
flbc="find_near.bc.err.log"
echo `date` > $flbc

old_seconds=$SECONDS
while read fd1
do
    let primomatch=1
    while read fd2
    do
        rimaste=$(echo "$rimaste-1" | bc)

        IN="$fd1 $fd2" ;  declare -a var ;  var=($IN) # gestisce eventuali spazi o tab di troppo!!!
        cod1=${var[0]} ;  x1=${var[1]}  ;  y1=${var[2]} ;  cod2=${var[3]} ;  x2=${var[4]} ;  y2=${var[5]}
                 
        #calcolo la distanza e confronto con scarto, scale: numero di decimali per bc
           
        strbc="if (acos(sin($y1*pi/180)*sin($y2*pi/180)+cos($y1*pi/180)*cos($y2*pi/180)*cos(($x1*pi/180)-($x2*pi/180)))/(pi/180) <= $4) 1 else 0 "
        scarto=$(echo $strbc | bc -q -l extensions.bc 2>> $flbc )
       
        if [ "$scarto" -eq "1" ]; then
            # echo "$fd1 - $fd2 . distanza $distanza minore di $4"
            trovati=$(echo "scale=0; $trovati+1" | bc)
            strbc="acos(sin($y1*pi/180)*sin($y2*pi/180)+cos($y1*pi/180)*cos($y2*pi/180)*cos(($x1*pi/180)-($x2*pi/180)))/(pi/180)"
            distanza=$(echo $strbc | bc -q -l extensions.bc 2>> $flbc )
            #aggiungo nel file risultato           
            if [ "$primomatch" -eq "1" ]; then
                trovatif1=$(echo "scale=0; $trovatif1+1" | bc)
                let primomatch=0
                #echo -n "$cod1 near $cod2"
                echo -ne "$trovatif1 \t$cod1 \t$cod2 \t$distanza" >> $3
            else
                #echo -n ",$cod2"
                echo -ne ",\t$cod2 \t$distanza" >> $3
            fi
        fi       
                     
    done < <(cat $2 | sed -e "s/\r/\n/g" -e "/^[ \t]*$/d")
       
    if [ "$primomatch" -eq "0" ]; then
        #echo ";"
        echo ";" >> $3
    fi

    echo -ne "\rDa fare:$rimaste Trovati:$trovatif1($trovati) "

done < <(cat $1 | sed -e "s/\r/\n/g" -e "/^[ \t]*$/d")
echo "Da fare:$rimaste Trovati:$trovatif1($trovati) " >> $3
echo
echo "---------------------------------------------------------"
echo "File di log errori di bc($flbc):"
cat $flbc
echo "---------------------------------------------------------"
echo "Finito! Risultati in $3."

Rif.

Einstein1969

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: litte faster external math

#2 Post by Aacini » 08 Dec 2015 14:42

einstein1969 wrote:I have seen an architetture che start two process that using an interprocess communication for eliminating this limit.

This processes use the captured standard input output for communicate (incapsulate a process)

But it's complicated for my scope.

There is a better (simpler) mechanism for having a faster execution?

Einstein1969


I assume you refer to Efficient use of JScript expressions in Batch files post. Such method may be modified in a much simpler way that don't require CALL command:

Code: Select all

@if (@CodeSection == @Batch) @then


@echo off

if "%~1" equ "Main" goto %1
CScript //nologo //E:JScript "%~F0"  |  "%~F0" Main
goto :EOF

:Main

setlocal EnableDelayedExpansion
cls
echo Table of Sin(x):
echo/       
for /L %%x in (0,15,360) do (
   echo Math.sin(%%x*Math.PI/180^)>JSinput.txt
   set /P "sin="
   echo %%x   !sin!
)
echo :EOF>JSinput.txt
goto :EOF


@end


// JScript section

var spaces = " ", expr,
    fso = new ActiveXObject("Scripting.FileSystemObject");

function waitForExpr () {
   while ( ! fso.FileExists("JSinput.txt") ) WScript.Sleep(10);
   var file = fso.OpenTextFile("JSinput.txt",1);
   expr = file.ReadLine();
   file.Close();
   fso.DeleteFile("JSinput.txt");
}

for ( var i = 1; i <= 10; i++ ) spaces += spaces;
waitForExpr();
while ( expr != ":EOF" ) {
   WScript.Stdout.Write((eval(expr)+"\r\n"+spaces).substr(0,1023));
   waitForExpr();
}

If you need to read from keyboard when using this method, just use SET /P VAR=<CON

Antonio

einstein1969
Expert
Posts: 961
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: litte faster external math

#3 Post by einstein1969 » 13 Dec 2015 02:48

Thanks Antonio.

Now is necessary to test what of these are more efficiency.

The above script "spin" and use a little of cpu , but I haven't measured.... I will do!

Post Reply