公差内的方程求解器

时间:2012-10-30 06:39:50

标签: ruby math loops equation solver

我正在尝试设计一个Ruby脚本,通过获取E24系列电阻器和E12和E6系列电容器和电感器的值来帮助RC / RL电路设计。基本上只是循环通过每个可能的组合方程F = 1 / ( 2 * Pi * R * C ) [例如RC电路]。

我不是追求效率,只是可靠性。我需要它使用上面等式的值循环通过电阻器阵列和电容器/电感器阵列的每一个组合(从不全部3),如果它在特定值的正/负x%范围内,则返回它使用的数组。我可以嵌套2 for循环来遍历每个组合,但是我希望它不仅仅在容差范围内返回值,而是告诉我哪个值最接近(或准确)。

3 个答案:

答案 0 :(得分:2)

在您定义E24E12E6数组,CERTAIN_VALUE和所需的DELTA后,这应该有效:

F = lambda{ |i, r, c| 1 / ( 2 * i * r * c ) }

equation_solver = lambda {
  |equation, resistances, capacitances, inductances, desired_value, delta|
  resistances.find.with_object [] do |resistance, memo|
    capacitances.find.with_object memo do |capacitance, memo|
      inductances = E6.find{ |inductance|
        ( equation.(inductance, resistance, capacitance) - desired_value ).abs < delta
      } and memo << resistance << capacitance << inductance
    end
  end
}

desired_r_c_i = equation_solver.( F, E24, E12, E6, CERTAIN_VALUE, DELTA )

答案 1 :(得分:0)

$resArray = [1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1,10, 11, 12, 13, 15, 16, 18, 20, 22, 24, 27, 30, 33, 36, 39, 43, 47, 51, 56, 62, 68, 75, 82, 91,100, 110, 120, 130, 150, 160, 180, 200, 220, 240, 270, 300, 330, 360, 390, 430, 470, 510, 560, 620, 680, 750, 820, 910,1000, 1100, 1200, 1300, 1500, 1600, 1800, 2000, 2200, 2400, 2700, 3000, 3300, 3600, 3900, 4300, 4700, 5100, 5600, 6200, 6800, 7500, 8200, 9100, 10000, 11000, 12000, 13000, 15000, 16000, 18000, 20000, 22000, 24000, 27000, 30000, 33000, 36000, 39000, 43000, 47000, 51000, 56000, 62000, 68000, 75000, 82000, 91000, 100000, 110000, 120000, 130000, 150000, 160000, 180000, 200000, 220000, 240000, 270000, 300000, 330000, 360000, 390000, 430000, 470000, 510000, 560000, 620000, 680000, 750000, 820000, 910000, 1000000, 1100000, 1200000, 1300000, 1500000, 1600000, 1800000, 2000000, 2200000, 2400000, 2700000, 3000000, 3300000, 3600000, 3900000, 4300000, 4700000, 5100000, 5600000, 6200000, 6800000, 7500000, 8200000, 9100000, 1000000]
$capArray = Array.new
$indArray = Array.new
$breakFreq = 19*(10**3)
$tol = 0.997
$PI = Math.atan2(0,-1)

def makeArray(j,arr)
    for i in 0...$resArray.size
        if i%j == 0
        arr << $resArray[i]*(10**-9)
        end
    end
end

def capTest()
puts "RC Circuit Estimation"
    for i in 0...$resArray.size
        for j in 0...$capArray.size
            n = 1/(2*$PI*$resArray[i]*$capArray[j])
            if n > $breakFreq*$tol && n < $breakFreq*(2-$tol)
                diff = 100 - ((n-$breakFreq)/$breakFreq).abs
                puts "Resistor:  #{$resArray[i]} Ohms"
                puts "Capacitor: #{$capArray[j].to_f} F"
                puts "Within #{diff}%"
                puts "---------------------"
            end
        end
    end
end

def indTest()
puts "RL Circuit Estimation"
    for i in 0...$resArray.size
        for j in 0...$indArray.size
            n = $resArray[i]/(2*$PI*$indArray[j])
            if n > $breakFreq*$tol && n < $breakFreq*(2-$tol)
                diff = (1 - ((n-$breakFreq)/$breakFreq).abs)*100
                puts "Resistor:  #{$resArray[i]} Ohms"
                puts "Inductor: #{$indArray[j].to_f} H"
                puts "Within #{diff}%"
                puts "---------------------"
            end
        end
    end
end

makeArray(2,$capArray)
makeArray(4,$indArray)
capTest()
indTest()

答案 2 :(得分:0)

这是对您的代码的轻微重构:

# I noticed that your resistance array is just the same set of values
# repeated with factors from 1 to 1000000, so this would be more concise
# way of defining it (and less prone to typing errors):
RES_ARRAY = [*-1..5].map{ |e| 10 ** e }.map{ |factor|
             [ 10, 11, 12, 13, 15, 16, 18, 20,
               22, 24, 27, 30, 33, 36, 39, 43,
               47, 51, 56, 62, 68, 75, 82, 91 ].map{ |e| e * factor }
           }.reduce( :+ )

# Global variables should be used very rarely. Constants should be written IN UPCASE:
CAP_ARRAY, IND_ARRAY = [], []
BREAK_FREQ = 19 * ( 10 ** 3 )

# Whole words should be used whenever possible in the code:
TOLERANCE = 0.997

# Methods should be named in snake_case:
def make_array( j, arr )
  # Let us use #each_slice and #map insterad of % and << operators:
  arr.each_slice( j ).map( &:first ).map{ |e| e * 1e-9 }
end

def cap_test
  puts "RC Circuit Estimation"
  for i in 0...RES_ARRAY.size
    for j in 0...CAP_ARRAY.size
      n = 1 / ( 2 * Math::PI * RES_ARRAY[ i ] * CAP_ARRAY[ j ] )
      if n > BREAK_FREQ * TOLERANCE and n < BREAK_FREQ * ( 2 - TOLERANCE )
        diff = 100 - ( ( n - BREAK_FREQ ) / BREAK_FREQ ).abs
        puts "Resistor:  #{RES_ARRAY[ i ]} Ohms"
        puts "Capacitor: #{CAP_ARRAY[ j ].to_f} F"
        puts "Within #{diff}%"
        puts "---------------------"
      end
    end
  end
end

def ind_test
  puts "RL Circuit Estimation"
  for i in 0...RES_ARRAY.size
    for j in 0...IND_ARRAY.size
      n = RES_ARRAY[ i ] / ( 2 * Math::PI * IND_ARRAY[ j ] )
      if n > BREAK_FREQ * TOLERANCE and n < BREAK_FREQ * ( 2 - TOLERANCE )
        diff = ( 1 - ( ( n - BREAK_FREQ ) / BREAK_FREQ ).abs ) * 100
        puts "Resistor:  #{RES_ARRAY[ i ]} Ohms"
        puts "Inductor: #{IND_ARRAY[ j ].to_f} H"
        puts "Within #{diff}%"
        puts "---------------------"
      end
    end
  end
end

make_array 2, CAP_ARRAY
make_array 4, IND_ARRAY
cap_Test()
ind_Test()