Simple question, all I want to do is have Solve[] work in a way that instead of solving for a single variable (eg. Vo) it solves for the expression Vo/Vi. In all cases this just equates to dividing both sides by Vi, as it'll cancel out on the RHS anyway, curious if there's a quick way to do it though.
Thanks
EDIT: Here's the code
vd = 0 - V1;
VL = Solve[(V1 - Vi)/R1 + (V1 - Vo)/R2 == 0, V1][[All, 1, 2]][[1]];
VR = Solve[(Vo - V1)/R2 + (Vo - (AO*vd))/RO == 0, V1][[All, 1, 2]][[1]];
Av = Solve[VL == VR, Vo][[All, 1, 2]][[1]];
Av = Av/Vi //I add this to remove the Vi
Basically I want it to solve for Vo/Vi, to automatically remove the Vi from the RHS...
You seem to be using V1 as a placeholder in Solve to get VL and VR. Let's get rid of V1 by putting VL and VR directly into those equations. This means that we also need to define vd as 0 - VR.
Also, let's define Av as Vo/Vi.
We can stuff all of the equations into Eliminate, asking it to eliminate Vo, Vi, VL, VR, and vd:
In[72]:= Eliminate[
vd == 0 - VR
&& (VL - Vi)/R1 + (VL - Vo)/R2 == 0
&& (Vo - VR)/R2 + (Vo - (AO*vd))/RO == 0
&& VL == VR
&& Av == Vo/Vi,
{Vo, Vi, vd, VL, VR}]
Out[72]= Av (1 + AO + R2/R1 + RO/R1) == (-AO R2 + RO)/R1 && R1 != 0 &&
R2 != 0 && RO != 0
That's pretty close to what we want, but it's not quite solved for Av, so let's do that too:
In[73]:= Solve[
Eliminate[
vd == 0 - VR
&& (VL - Vi)/R1 + (VL - Vo)/R2 == 0
&& (Vo - VR)/R2 + (Vo - (AO*vd))/RO == 0
&& VL == VR
&& Av == Vo/Vi,
{Vo, Vi, vd, VL, VR}],
Av]
Out[73]= {{Av -> (-AO R2 + RO)/(R1 + AO R1 + R2 + RO)}}
If you want to actually define the symbol Av, we can do that using /. (ReplaceAll):
In[80]:= Av =.; Av = Av /. Solve[
Eliminate[
vd == 0 - VR
&& (VL - Vi)/R1 + (VL - Vo)/R2 == 0
&& (Vo - VR)/R2 + (Vo - (AO*vd))/RO == 0
&& VL == VR
&& Av == Vo/Vi,
{Vo, Vi, vd, VL, VR}],
Av][[1]];
In[81]:= Av
Out[81]= (-AO R2 + RO)/(R1 + AO R1 + R2 + RO)
Related
I'm trying to sort the Dutch Flag problem with 4 colors instead of 3, it seems that Dafny does not really verify and I could not fix it as well. This is my code:
datatype Colour = RED | WHITE | PINK | BLUE
method FlagSort(flag: array<Colour>) returns (w:int, p:int, b:int)
ensures 0 <= w <= p <= b < flag.Length
ensures forall i :: 0 <= i < w ==> flag[i] == RED
ensures forall i :: w <= i < p ==> flag[i] == WHITE
ensures forall i :: p <= i < b ==> flag[i] == PINK
ensures forall i :: b <= i < flag.Length ==> flag[i] == BLUE
ensures multiset(flag[..]) == multiset(old(flag[..]))
modifies flag
{
var next := 0;
w, p := 0, 0;
b := flag.Length;
while next <= b
invariant 0 <= w <= p <= next <= b <= flag.Length
invariant forall i :: 0 <= i < w ==> flag[i] == RED
invariant forall i :: w <= i < p ==> flag[i] == WHITE
invariant forall i :: p <= i < next ==> flag[i] == PINK
invariant forall i :: b <= i < flag.Length ==> flag[i] == BLUE
invariant multiset(flag[..]) == multiset(old(flag[..]))
{
if flag[next] == RED {
flag[next], flag[w] := flag[w], flag[next];
w := w + 1;
if p < w {
p := p + 1;
}
if next < w {
next := next + 1;
}
} else if flag[next] == WHITE {
flag[next], flag[p] := flag[p], flag[next];
p := p + 1;
next := next + 1;
} else if flag[next] == PINK {
next := next + 1;
} else if flag[next] == BLUE {
b := b - 1;
flag[next], flag[b] := flag[b], flag[next];
}
}
}
Can anyone help me with this please, thank you!
I don't know the solution to this problem (you might be solving a hard problem !), but here is some relevant advice for each of the three errors Dafny found in your code.
Error 1
When you see this:
flag[next], flag[b] := flag[b], flag[next];
^^^ index out of range
you can add an assertion before like this:
assert 0 <= b;
assert b < |flags|;
flag[next], flag[b] := flag[b], flag[next];
Magically, the index out of range will go away, and in your case, the first assertion will fail. You can then apply verification debugging techniques to move the assertion up..
Error 2
while next <= b
^^^^^ cannot prove termination, try supplying a decreases clause
the problem is that it tried to insert the decrease clause b - next, which should always be decreasing and bounded below by zero. If you make it explicit, and hover the decreases expression, it will tell you "the decreases expression is always bounded below by zero", but you get a new error:
while next <= b
^^^^^ decreases expression might not decrease
decreases b - next
What you can do is add this line at the beginning of your while loop.
ghost var b_saved,next_saved := b, next;
and at the end of your while loop, add the decreases check explicitly:
assert b - next < b_saved-next_saved;
You'll see that now the decreases clause is verified, and you have an error on an assert, on which you can apply regular verification debugging techniques.
Error 3
if flag[next] == RED {
^^^^^^^^^^ index out of range.
Similarly, you can insert the implicit assertions there:
assert 0 <= next < flag.Length;
if flag[next] == RED { // No error there
You'll see an underline on next < flag.Length. What can you do to ensure this? Perhaps change an invariant?
This question was migrated from Super User because it can be answered on Stack Overflow.
Migrated last month.
I'm reading a book Effective AWK Programming by Arnold Robbins and I've come across this code there which I'm trying to understand.
It should sort this and similar lists, first all numeric items and then strings:
This first part is easy to understand
BEGIN {
data["one"] = 10
data["two"] = 20
data[10] = "one"
data[100] = 100
data[20] = "two"
f[1] = "cmp_num_idx"
f[2] = "cmp_str_val"
f[3] = "cmp_num_str_val"
for (i = 1; i <= 3; i++) {
printf("Sort function: %s\n", f[i])
PROCINFO["sorted_in"] = f[i]
for (j in data)
printf("\tdata[%s] = %s\n", j, data[j])
print ""
}
}
However I have a problem to understand why at n2 == v2 it returns 1
and I do not follow even this last line
return (v1 < v2) ? -1 : (v1 != v2)
I do understand that if n2==v2 then v2 was a number and not a string!
So this is the problem:
function cmp_num_str_val(i1, v1, i2, v2, n1, n2)
{
# numbers before string value comparison, ascending order
n1 = v1 + 0
n2 = v2 + 0
if (n1 == v1)
return (n2 == v2) ? (n1 - n2) : -1
else if (n2 == v2)
return 1
return (v1 < v2) ? -1 : (v1 != v2)
}
Can someone kindly explain to me the course of this code ?
The if/else/if addresses 'numeric vs numeric', and 'numeric vs string':
if (n1 == v1)
return (n2 == v2) ? (n1 - n2) : -1
else if (n2 == v2)
return 1
# becomes:
if (n1 == v1) { # v1 numeric
if (n2 == v2) return (n1 - n2) # v2 numeric; return 0 if n1==n2; return +<number> if n1>n2; return -<number> if n1<n2
else return -1 # v2 not numeric
}
else { # v1 not numeric
if (n2 == v2) return 1 # v2 numeric
}
If we fall through the if/else/if block then we're looking at 'string vs string' so we proceed to determine which of 3 string comparison outcomes apply.
return (v1 < v2) ? -1 : (v1 != v2)
# becomes:
if (v1 < v2) return -1
else return (v1 != v2) # return 0 if (v1 == v2); return 1 if (v1 > v2)
# or a less convoluted, more verbose, equivalent:
if (v1 < v2) return -1
else if (v1 == v2) return 0
else return 1 # v1 > v2
I am trying to run a parameter variation experiment with 3 iterations and 100 replications in Anylogic. I use the same 100 seeds {10, 20, 30, ..., 1000} for every replication using
root.getDefaultRandomGenerator().setSeed((long) listOfSeeds.get(getCurrentReplication()));
in "before simulation run" java action field in parameter variation properties. I am varying one parameter. For retrieving data after each run I inserted following code in "after simulation run" section
replication = getCurrentReplication();
double totalMins = 0;
double totalLoading = 0;
double totalUnloading = 0;
int i = 0;
while(i < root.pickTime.size()){
double x = root.pickTime.getX(i);
if(i+7 < root.pickTime.size() && x == root.pickTime.getX(i+1) && x == root.pickTime.getX(i+2) && x == root.pickTime.getX(i+3) && x == root.pickTime.getX(i+4) && x == root.pickTime.getX(i+5) && x == root.pickTime.getX(i+6) && x == root.pickTime.getX(i+7)){
double y = root.pickTime.getY(i) + root.pickTime.getY(i+1) + root.pickTime.getY(i+2) + root.pickTime.getY(i+3) +root.pickTime.getY(i+4) +root.pickTime.getY(i+5) +root.pickTime.getY(i+6) +root.pickTime.getY(i+7);
pickTimePV.add(x, y);
i += 8;
continue;}
if(i+6 < root.pickTime.size() && x == root.pickTime.getX(i+1) && x == root.pickTime.getX(i+2) && x == root.pickTime.getX(i+3) && x == root.pickTime.getX(i+4) && x == root.pickTime.getX(i+5) && x == root.pickTime.getX(i+6)){
double y = root.pickTime.getY(i) + root.pickTime.getY(i+1) + root.pickTime.getY(i+2) + root.pickTime.getY(i+3) +root.pickTime.getY(i+4) +root.pickTime.getY(i+5) +root.pickTime.getY(i+6);
pickTimePV.add(x, y);
i += 7;
continue;}
if(i+5 < root.pickTime.size() && x == root.pickTime.getX(i+1) && x == root.pickTime.getX(i+2) && x == root.pickTime.getX(i+3) && x == root.pickTime.getX(i+4) && x == root.pickTime.getX(i+5)){
double y = root.pickTime.getY(i) + root.pickTime.getY(i+1) + root.pickTime.getY(i+2) + root.pickTime.getY(i+3) +root.pickTime.getY(i+4) +root.pickTime.getY(i+5);
pickTimePV.add(x, y);
i += 6;
continue;}
if(i+4 < root.pickTime.size() && x == root.pickTime.getX(i+1) && x == root.pickTime.getX(i+2) && x == root.pickTime.getX(i+3) && x == root.pickTime.getX(i+4)){
double y = root.pickTime.getY(i) + root.pickTime.getY(i+1) + root.pickTime.getY(i+2) + root.pickTime.getY(i+3) +root.pickTime.getY(i+4);
pickTimePV.add(x, y);
i += 5;
continue;}
if(i+3 < root.pickTime.size() && x == root.pickTime.getX(i+1) && x == root.pickTime.getX(i+2) && x == root.pickTime.getX(i+3)){
double y = root.pickTime.getY(i) + root.pickTime.getY(i+1) + root.pickTime.getY(i+2) + root.pickTime.getY(i+3);
pickTimePV.add(x, y);
i += 4;
continue;}
if(i+2 < root.pickTime.size() && x == root.pickTime.getX(i+1) && x == root.pickTime.getX(i+2)){
double y = root.pickTime.getY(i) + root.pickTime.getY(i+1) + root.pickTime.getY(i+2);
pickTimePV.add(x, y);
i += 3;
continue;}
if(i+1 < root.pickTime.size() && x == root.pickTime.getX(i+1)){
double y = root.pickTime.getY(i) + root.pickTime.getY(i+1);
pickTimePV.add(x, y);
i += 2;
continue;}
else{
pickTimePV.add(x, root.pickTime.getY(i));
i++;}}
excelFile.writeDataSet(pickTimePV, 1, 1, 1 + iteration);
pickTimePV.reset();
iteration +=3;
kommiUtilization.add(getCurrentIteration(), root.kommiPool.utilization());
aushilfeUtilization.add(getCurrentIteration(), root.aushilfePop.get(0).timeInState(ResourceUsageState.USAGE_BUSY, MINUTE) / (root.kommissionierer.get(0).timeInState(ResourceUsageState.USAGE_BUSY, MINUTE)/root.kommiPool.utilization()));
ordersInQueue.add(getCurrentIteration(), root.orderQueue.size());
for(int j = 0; j < root.loadingTime.size(); j++){
totalLoading += root.loadingTime.getY(j);}
loadingTimePV.add(getCurrentIteration(), totalLoading/root.totalLoadTrucks);
for(int k = 0; k < root.unloadingTime.size(); k++){
totalUnloading += root.unloadingTime.getY(k);}
unloadingTimePV.add(getCurrentIteration(), totalUnloading/root.totalUnloadTrucks);
for(int t = 0; t < root.pickTime.size(); t++){
totalMins += root.pickTime.getY(t);}
totalPickTime.add(getCurrentIteration(), totalMins);
totalLoadTrucksPV.add(getCurrentIteration(), root.totalLoadTrucks);
totalUnloadTrucksPV.add(getCurrentIteration(), root.totalUnloadTrucks);
After replication No. 61 (183 simulation runs) the system throws the error:
Error in the model during iteration 3
java.lang.RuntimeException: Error in the model during iteration 3
at com.anylogic.engine.ExperimentParamVariation$b.i(Unknown Source)
at com.anylogic.engine.n$b.run(Unknown Source)
Before the error occurs, the last simulation run finishes succesfully (visibile using traceln()). I checked all possible parameter configurations and seed numbers where the error could be thrown with simulation experiments, but everything works fine for simulation experiments. So I guess the error has to do something with the parameter variation experiment setup.
Do you have any ideas how to fix the problem?
Thanks in advance.
I have created this if and else if statements. Flat, Vertical, Facedown, Right Side, and Left Side work... However, I am not sure why the Upside down is not working. Here is my code:
checkOrientation= () => {
let orientation = "unknown";
if (z > .8 && Math.abs(x) < .2 && Math.abs(y) < .2) orientation = "flat";
else if (y > .9 && Math.abs(x) < .2 &&Math.abs(z) < .2) orientation = "vertical";
if (x < .1 && Math.abs(y) < .1 && Math.abs(z) < .3) orientation = "right side";
else if (z < .01 && Math.abs(x) > .9 && Math.abs(y) < .05) orientation = "left side";
if (x > .01 && Math.abs(y) < .7 && Math.abs(z) < .05) orientation = "upside down";
else if (x > .01 && Math.abs (y) < .01 && Math.abs(z) > .01) orientation = "face down";
this.setState({orientation});
}
How to reduce the code space for a hexadecimal ASCII chars conversion using a small code space?
In an embedded application, I have extraordinary limited space (note 1). I need to convert bytes, from serial I/O, with the ASCII values '0' to '9' and 'A' to 'F' to the usual hexadecimal values 0 to 15. Also, all the other 240 combinations, including 'a' to 'f', need to be detected (as an error).
Library functions such as scanf(), atoi(), strtol() are far too large to use.
Speed is not an issue. Code size is the the limiting factor.
My present method re-maps the 256 byte codes into 256 codes such that '0' to '9' and 'A' to 'Z' have the values 0 - 35. Any ideas on how to reduce or different approaches are appreciated.
unsigned char ch = GetData(); // Fetch 1 byte of incoming data;
if (!(--ch & 64)) { // decrement, then if in the '0' to '9' area ...
ch = (ch + 7) & (~64); // move 0-9 next to A-Z codes
}
ch -= 54; // -= 'A' - 10 - 1
if (ch > 15) {
; // handle error
}
Note 1: 256 instructions exist for code and constant data (1 byte data costs 1 instruction) in a PIC protected memory for a bootloader. This code costs ~10 instructions. Current ap needs a re-write & with only 1 spare instruction, reducing even 1 instruction is valuable. I'm going through it piece by piece. Also have looked at overall reconstruction.
Notes: PIC16. I prefer to code in 'C', but must do what ever it takes. Assembly code follows. A quick answer is not required.
if (!(--ch & 64)) {
002D:DECF 44,F 002E:BTFSC 44.6 002F:GOTO 034
ch = (ch + 7) & (~64);
0030:MOVLW 07 0031:ADDWF 44,W 0032:ANDLW BF 0033:MOVWF 44
}// endif
ch -= 54;
0034:MOVLW 36 0035:SUBWF 44,F
[edit best solution]
Optimizing existing solution as suggested by #GJ. In C, performing the ch += 7; ch &= (~64); instead of ch = (ch + 7) & (~64); saved 1 instruction. Going to assembly saved another by not having to reload ch within the if().
PIC16 family is RISC MCPU, so you can try to optimize your asm code.
This is your c compilers asm code...
decf ch, f
btfsc ch, 6
goto Skip
movlw 07
addwf ch, w
andlw 0xBF
movwf ch
Skip
movlw 0x36
subwf ch, f
This is my optimization of upper code...
decf ch, w //WREG = (--ch)
btfsc WREG, 6 //if (!(WREG & 64)) {
goto Skip
addlw 7 //WREG += 7
andlw 0xBF //WREG &= (~64)
Skip
addlw 0x100 - 0x36 //WREG -= 54;
movwf ch //ch = WREG
//
addlw 0x100 - 0x10 //if (WREG > 15) {
btfsc STATUS, 0 //Check carry
goto HandleError
...so only 7 opcodes (2 less) without range error check and 10 opcodes with range error check!
EDIT:
Try also this PIC16 c compiler optimized function, not sure if works...
WREG = (--ch);
if (!(WREG & 64)) { // decrement, then if in the '0' to '9' area ...
WREG = (WREG + 7) & (~64); // move 0-9 next to A-Z codes
}
ch = WREG - 54; // -= 'A' - 10 - 1
if (WREG > 15) {
; // handle error
}
EDIT II: added version which is compatible with older PIC16 MCPUs not made in XLP technology, but code size is one opcode longer.
decf ch, f ;//ch = (--ch)
movf ch, w ;//WREG = ch
btfsc ch, 6 ;//if (!(ch & 64)) {
goto Skip
addlw 7 ;//WREG += 7
andlw 0xBF ;//WREG &= (~64)
Skip
addlw 0x100 - 0x36 ;//WREG -= 54;
movwf ch ;//ch = WREG
//
addlw 0x100 - 0x10 ;//if (WREG > 15) {
btfsc STATUS, 0 ;//Check carry
goto HandleError
EDIT III: explanation
The 'D Kruegers' solution is also very good, but need some modification...
This code..
if (((ch += 0xC6) & 0x80) || !((ch += 0xF9) & 0x80)) {
ch += 0x0A;
}
...we can translate to...
if (((ch -= ('0' + 10)) < 0) || ((ch -= ('A' - '0' - 10)) >= 0)) {
ch += 10;
}
After that we can optimize in asembler...
call GetData
//if GetData return result in WREG then you do not need to store in ch and read it again!
// movwf ch
// movf ch, w
addlw 0x100 - '0' - 10 //if (((WREG -= ('0' + 10)) < 0) || ((WREG -= ('A' - '0' - 10)) >= 0)) {
btfss STATUS, 0
goto DoAddx
addlw 0x100 - ('A' - '0' - 10)
btfsc STATUS, 0
DoAddx
addlw 10 //WREG += 10; }
movwf ch //ch = WREG;
addlw 0x100 - 0x10 //if (WREG > 15) {
btfsc STATUS, 0 //Check carry
goto HandleError
With good compiler optimization, this may take less code space:
unsigned char ch = GetData(); // Fetch 1 byte of incoming data;
if (((ch += 0xC6) & 0x80) || !((ch += 0xF9) & 0x80)) {
ch += 0x0A;
}
if (ch > 15) {
; // handle error
}
Perhaps using ctype.h's isxdigit():
if( isxdigit( ch ) )
{
ch -= (ch >= 'A') ? ('A' - 10) : '0' ;
}
else
{
// handle error
}
Whether that is smaller or not will depend largely on the implementation of isxdigit and perhaps your compiler and processor architecture, but worth a try and far more readable. isxdigit() is normally a macro so there is no function call overhead.
An alternative is to perform the transformation unconditionally then check the range of the result:
ch -= (ch >= 'A') ? ('A' - 10) :
(ch >= '0') ? '0' : 0 ;
if( ch > 0xf )
{
// handle error
}
I suspect this latter will be smaller, but modification of ch on error may be unhelpful in some cases, such as error reporting the original value.