Subversion Repositories wimsdev

Rev

Rev 7692 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

!if  $wims_read_parm!=slib_header
 !goto proc
!endif

slib_author=Georges, KHAZNADAR

slib_example= ,,,2,2,,1 \
(distance,m,1000,2000,y*z),(duration,s,10,20,x/z),(velocity,m/s,50,200,x/y),4,2 \
(distance,m,1000,2000,y*z),(duration,s,10,20,x/z),(impossible_velocity,m/s,-50,-10,x/y),4,2
slib_require=pari
!exit

:proc

!reset slib_fx, slib_fy, slib_fz, slib_randx, slib_randy, slib_randz, slib_constx, slib_consty, slib_constz, slib_nl, slib_nc, slib_namex, slib_namey, slib_namez, slib_unitx, slib_unity, slib_unitz, slib_datax, slib_datax, slib_dataz, slib_prec

slib_parm=!item 1 to 6 of $wims_read_parm
!distribute item $slib_parm into slib_datax, slib_datay, slib_dataz, slib_nl, slib_nc, slib_prec, slib_dbg

!default slib_datax=(I,A,1,10,z/y,(x-1)*(10-x))
!default slib_datay=(R,Ohm,1,10,z/x,(y-1)*(10-y))
!default slib_dataz=(U,V,1,100,x*y,(z-1)*(100-z))
!default slib_nl=3
!default slib_nc=3
!default slib_prec=3
!default slib_dbg=0

slib_datax=!declosing $slib_datax
slib_datay=!declosing $slib_datay
slib_dataz=!declosing $slib_dataz

slib_namex=$(slib_datax[1])
slib_namey=$(slib_datay[1])
slib_namez=$(slib_dataz[1])
slib_unitx=$(slib_datax[2])
slib_unity=$(slib_datay[2])
slib_unitz=$(slib_dataz[2])
slib_randx=$(slib_datax[3 to 4])
slib_randy=$(slib_datay[3 to 4])
slib_randz=$(slib_dataz[3 to 4])
slib_fx=$(slib_datax[5])
slib_fy=$(slib_datay[5])
slib_fz=$(slib_dataz[5])
slib_constx=$(slib_datax[6])
slib_consty=$(slib_datay[6])
slib_constz=$(slib_dataz[6])

!! ==== some expressions which must be constrained to remain positive. ====
!default slib_constx=(x-$(slib_datax[3]))*($(slib_datax[4])-x)
!default slib_consty=(y-$(slib_datay[3]))*($(slib_datay[4])-y)
!default slib_constz=(z-$(slib_dataz[3]))*($(slib_dataz[4])-z)

!! ==== list of given x : at least one given, and one unknown. ====
slib_givenx=1,0

!! ==== compute a random x1 with significant digits matching the given precision  ====
slib_x1=!random $slib_randx
slib_mul=$[10^($slib_prec-1-floor(lg($slib_x1)))]
slib_x1=$[rint($slib_mul*$slib_x1)/$slib_mul]

!for slib_i from 3 to $slib_nc
  slib_r=!randint 0,1
  slib_givenx=$slib_givenx, $slib_r
  !if $slib_r=1
    !!==== compute a random xi with significant digits matching the given precision  ====
    slib_x$slib_i=!random $slib_randx
    slib_mul=$[10^($slib_prec-1-floor(lg($(slib_x$slib_i))))]
    slib_x$slib_i=$[rint($slib_mul*$(slib_x$slib_i))/$slib_mul]
  !endif
!next slib_i
!!==== assert: every given x is an random number between xmin and xmax,  ====
!!==== with no more than prec significant digits. ======================

!! ==== list of given y: at least one given, and one unknown. ====
slib_giveny=1,0


!! ==== compute a random y1 with significant digits matching the given precision  ====
slib_y1=!random $slib_randy
slib_mul=$[10^($slib_prec-1-floor(lg($slib_y1)))]
slib_y1=$[rint($slib_mul*$slib_y1)/$slib_mul]

!for slib_i from 3 to $slib_nl
  slib_r=!randint 0,1
  slib_giveny=$slib_giveny, $slib_r
  !if $slib_r=1
    !!==== compute a random yi with significant digits matching the given precision  ====
    slib_y$slib_i=!random $slib_randy
    slib_mul=$[10^($slib_prec-1-floor(lg($(slib_y$slib_i))))]
    slib_y$slib_i=$[rint($slib_mul*$(slib_y$slib_i))/$slib_mul]
  !endif
!next slib_i
!!==== assert: every given y is an random number between ymin and ymax,  ====
!!==== with no more than prec significant digits. ======================

!!==== getting rid of any previous values of z_i_j ====
!for slib_i from 1 to $slib_nc
  !for slib_j from 1 to $slib_nl
    !reset slib_z_$(slib_j)_$(slib_i)
  !next slib_j
!next slib_i

!!==== at the begin every z is considered as not given, we shall mark z values as given later ====
slib_givenz=!exec pari matrix($slib_nl,$slib_nc)

slib_computablex=$slib_givenx
slib_computabley=$slib_giveny

!!==== gathering the non-computable indexes for x ====
slib_first=1
!for slib_i=1 to $slib_nc
  !if $(slib_computablex[$slib_i]) = 0
    !if $slib_first=1
      slib_range_noncomputablex=$slib_i
      slib_first=0
    !else
      slib_range_noncomputablex=$slib_range_noncomputablex, $slib_i
    !endif
  !endif
!next slib_i
!!=== assert : range_noncomputablex is the list of indexes for noncomputable x
!for  slib_r in $slib_range_noncomputablex
  !!==== gather the computable indexes for y ====
  slib_first=1
  !for slib_i=1 to $slib_nl
    !if $(slib_computabley[$slib_i]) = 1
      !if $slib_first=1
        slib_range_computabley=$slib_i
        slib_first=0
      !else
        slib_range_computabley=$slib_range_computabley, $slib_i
      !endif
    !endif
  !next slib_i
  !!=== assert : range_computabley is the list of indexes for computable y  ====
  slib_s=!randitem $slib_range_computabley
  !!==== assert: x is unknown and y is known for column r and row s ====
  constraint=-1
  maxwhile=20
  currentwhile=0
  !while $constraint <= 0
    currentwhile=$currentwhile+1
    !if $currentwhile > $maxwhile
      !goto too_many_iter
    !endif
    slib_z_$(slib_s)_$(slib_r)=!random $slib_randz
    slib_mul=$[10^($slib_prec-1-floor(lg($(slib_z_$(slib_s)_$(slib_r)))))]
    slib_z_$(slib_s)_$(slib_r)=$[rint($slib_mul*$(slib_z_$(slib_s)_$(slib_r)))/$slib_mul]
    expr=!mathsubst y=$(slib_y$(slib_s)) in $slib_fx
    expr=!mathsubst z=$(slib_z_$(slib_s)_$(slib_r)) in $expr
    slib_x$(slib_r)=!eval $expr
    constraint=!mathsubst x=$(slib_x$(slib_r)) in $slib_constx
  !endwhile
  !!==== assert: the value of xr is strictly inside the range xmin .. xmax ====
  !!==== updating slib_givenz ====
  slib_givenz=!exec pari A=Mat([$slib_givenz]);\
                         B=matrix($slib_nl,$slib_nc,row,col,(row==$slib_s)*(col==$slib_r));\
                         print(A+B);
  slib_givenz=!nospace $slib_givenz
  !! updating slib_computablex
  slib_computablex=!exec pari A=Vec([$slib_computablex]);\
                                B=vector($slib_nc,x,(x==$slib_r));\
                                A+B
  slib_computablex=!nospace $slib_computablex
!next slib_r
!!==== assert: every x is computable ====

!!==== gathering the non-computable indexes for y ====
slib_first=1
!for slib_i=1 to $slib_nl
  !if $(slib_computabley[$slib_i]) = 0
    !if $slib_first=1
      slib_range_noncomputabley=$slib_i
      slib_first=0
    !else
      slib_range_noncomputabley=$slib_range_noncomputabley, $slib_i
    !endif
  !endif
!next slib_i
!!=== assert : range_noncomputabley is the list of indexes for noncomputable y
!for  slib_s in $slib_range_noncomputabley
  !!==== gather the computable indexes for x ====
  slib_first=1
  !for slib_i=1 to $slib_nc
    !if $(slib_computablex[$slib_i]) = 1
      !if $slib_first=1
        slib_range_computablex=$slib_i
        slib_first=0
      !else
        slib_range_computablex=$slib_range_computablex, $slib_i
      !endif
    !endif
  !next slib_i
  !!=== assert : range_computablex is the list of indexes for computable x  ====
  slib_r=!randitem $slib_range_computablex
  !!==== assert: x is known and y is unknown for column r and row s ====
  constraint=-1
  !while $constraint <= 0
    slib_z_$(slib_s)_$(slib_r)=!random $slib_randz
    slib_mul=$[10^($slib_prec-1-floor(lg($(slib_z_$(slib_s)_$(slib_r)))))]
    slib_z_$(slib_s)_$(slib_r)=$[rint($slib_mul*$(slib_z_$(slib_s)_$(slib_r)))/$slib_mul]
    expr=!mathsubst x=$(slib_x$(slib_r)) in $slib_fy
    expr=!mathsubst z=$(slib_z_$(slib_s)_$(slib_r)) in $expr
    slib_y$(slib_s)=!eval $expr
    constraint=!mathsubst y=$(slib_y$(slib_s)) in $slib_consty
  !endwhile
  !!==== assert: the value of ys is strictly inside the range ymin .. ymax ====
  !!==== updating slib_givenz ====
  slib_givenz=!exec pari A=Mat([$slib_givenz]);\
                         B=matrix($slib_nl,$slib_nc,row,col,(row==$slib_s)*(col==$slib_r));\
                         print(A+B);
  slib_givenz=!nospace $slib_givenz
  !! updating slib_computabley
  slib_computabley=!exec pari A=Vec([$slib_computabley]);\
                              B=vector($slib_nl,y,(y==$slib_s));\
                              A+B
  slib_computabley=!nospace $slib_computabley
!next slib_s
!!==== assert: every y is computable ====

!!computing the non-given z_s_r
!for slib_s=1 to $slib_nl
  !for slib_r=1 to $slib_nc
    !!==== if z is not given we compute it from x and y ====
    !if $(slib_givenz[$slib_s;$slib_r]) = 0
      expr=!mathsubst x=$(slib_x$slib_r) in $slib_fz
      expr=!mathsubst y=$(slib_y$slib_s) in $expr
      expr=!eval ($expr)
      slib_z_$(slib_s)_$(slib_r)=$expr
    !endif
  !next slib_r
!next slib_s

slib_shx=!shuffle $slib_nc
slib_shy=!shuffle $slib_nl

slib_reply=1
slib_replies=
!! slib_t will be a list of chunks of code to make a table when interleaved
!! with slib_replies
slib_t=
slib_t=<table border=3><tr><th bgcolor='#AAFFAA' colspan="2" rowspan="2">$slib_namez ($slib_unitz)</th><th bgcolor='yellow' align='center' colspan="$slib_nc">$slib_namex ($slib_unitx)</th></tr><tr>
!for slib_i=1 to $slib_nc
slib_c=$(slib_shx[$slib_i])
!if $(slib_givenx[$slib_c])=1
  slib_t=$slib_t <td bgcolor='yellow'>$(slib_x$slib_c) $slib_unitx</td>
!else
  slib_t=$slib_t <td bgcolor='yellow' style='padding:8'>,
  slib_replies=$slib_replies $(slib_x$slib_c) $slib_unitx,
  slib_reply=$[$slib_reply+1]
  slib_t=$slib_t </td>
!endif
!next slib_i

!!<tr><td>
!for slib_j=1 to $slib_nl
  slib_l=$(slib_shy[$slib_j])
  slib_t=$slib_t </tr><tr>
  !if $slib_j=1
    slib_t=$slib_t <th bgcolor='lightblue' valign='medium' rowspan="$slib_nl">$slib_namey<br/>($slib_unity)</th>
  !endif
  !if $(slib_giveny[$slib_l])=1
    slib_t=$slib_t <td bgcolor='lightblue'>$(slib_y$slib_l) $slib_unity</td>
  !else
    slib_t=$slib_t <td bgcolor='lightblue' style='padding:8'>,
    slib_replies=$slib_replies $(slib_y$slib_l) $slib_unity,
    slib_reply=$[$slib_reply+1]
    slib_t=$slib_t </td>
  !endif
 !for slib_i=1 to $slib_nc
    slib_c=$(slib_shx[$slib_i])
    !if $(slib_givenz[$slib_l;$slib_c])=1
      slib_t=$slib_t <td bgcolor='#AAFFAA'>$(slib_z_$(slib_l)_$(slib_c)) $slib_unitz</td>
    !else
      slib_t=$slib_t <td bgcolor='#AAFFAA' style='padding:8'>,
      slib_replies=$slib_replies $(slib_z_$(slib_l)_$(slib_c)) $slib_unitz,
      slib_reply=$[$slib_reply+1]
      slib_t=$slib_t </td>
    !endif
  !next slib_i
!next slib_j
slib_t=$slib_t</tr></table>

slib_reply=$[$slib_reply-1]
slib_replies=$(slib_replies[1 to $slib_reply])

slib_table=$(slib_t[1])
!for slib_i=1 to $slib_reply
  !if $slib_dbg=1
    slib_table=$slib_table <input type='text' name='reply$slib_i' value='$(slib_replies[$slib_i])'/> $(slib_t[$[$slib_i+1]])
  !else
    slib_table=$slib_table <input type='text' name='reply$slib_i'/> $(slib_t[$[$slib_i+1]])
  !endif
!next slib_i

slib_out= $slib_table, $slib_reply, $slib_replies, $slib_t
!goto end

:too_many_iter
slib_out= Error. Please inform the developer that have been too many iterations while trying to satisfy the constraints to adjust a variable. This is very unlikely to occur. Please verify whether the constraint set is compatible with the relations linking the variables and their allowed intervals of validity. If you are visiting the help system, the error was triggered by the impossible_velocity validity interval.

:end